adddir ./Graphics adddir ./Graphics/PDF adddir ./Graphics/PDF/Data adddir ./Test adddir ./Test/bin adddir ./Test/interfaces adddir ./dist addfile ./Graphics/PDF.hs hunk ./Graphics/PDF.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- PDF API for Haskell +--------------------------------------------------------- +module Graphics.PDF + ( + -- * HPDF + -- ** PDF Monad + PDF + , runPdf + -- ** PDF Common Types + , PDFRect(..) + , PDFFloat(..) + -- ** Document management + , module Graphics.PDF.Document + -- ** Drawing + , module Graphics.PDF.Shapes + -- *** Draw monad + , Draw + -- ** Colors + , module Graphics.PDF.Colors + -- ** Geometry + , module Graphics.PDF.Coordinates + ) where + + +import qualified Data.IntMap as IM +import qualified Data.Map as M +import qualified Data.ByteString.Lazy as B +import Data.Int +import System.IO +import Control.Exception(bracket) +import Text.Printf(printf) +import Data.Maybe +import Control.Monad.State + +import Graphics.PDF.LowLevel +import Graphics.PDF.Draw +import Graphics.PDF.Colors +import Graphics.PDF.Shapes +import Graphics.PDF.Coordinates +import Graphics.PDF.Pages +import Graphics.PDF.Document + + +-- | Create a new PDF document and return a first page +-- The page is using the document size by default +createPDF :: PDF (PDFReference PDFPage) +createPDF = do + -- Create the Proc structure + proc <- addObject PDFProc + -- Create an empty resource + addObject $ PDFResource proc + -- Reserve an identifier for the root page object + addPage Nothing + +-- | Save all the pages and streams in the main object dictionary +saveObjects :: PDF (PDFReference PDFCatalog) +saveObjects = do + -- Save pages and streams to the object dictionary so that they are saved in the PDF document + pRef <- addPages + -- Create outlines object + outlines <- addObject PDFOutlines + -- Create the catalog + cat <- addObject $ PDFCatalog outlines pRef + modify $ \s -> s {catalog = cat , objects = IM.foldWithKey insertObject (objects s) (streams s) } + gets catalog + where + insertObject objectnb object objdict = IM.insert objectnb (AnyPdfObject object) objdict + + +-- | Write PDF objects in the TOC +writeObjectsAndCreateToc :: Handle -- ^ File handle + -> [B.ByteString] -- ^ List of objects each object being already converted to a bytestring + -> IO (Int,Int64,[B.ByteString]) +writeObjectsAndCreateToc h l = foldM writeObject (0,0::Int64,[]) l where + writeObject (nb,len,toc) obj = do + -- Write the object to the file + B.hPut h obj + -- Remember the position + return (nb+1,len + B.length obj,(toByteString (printf "%010d 00000 n \n" ((fromIntegral len)::Integer))) : toc) + +withFile :: FilePath -> (Handle -> IO c) -> IO c +withFile name = bracket (openBinaryFile name WriteMode) hClose + +-- | Generates a PDF document +runPdf :: String -- ^ Name of the PDF document + -> PDFRect -- ^ Default size for a page + -> ((PDFReference PDFPage) -> PDF a) -- ^ PDF action using the first page of the document as starting point + -> IO () +runPdf filename rect m = do + (root,s) <- flip runStateT vars . unPDF $ createPDF >>= m >> saveObjects + let header = toByteString "%PDF-1.4\n" + objs = objects s + withFile filename $ \h -> do + (nb,len,toc) <- writeObjectsAndCreateToc h $ header : (map (toPDF . pointer) . IM.toAscList $ objs) + B.hPut h . toByteString $ "xref\n" + B.hPut h . toByteString $ "0 " ++ show nb ++ "\n" + B.hPut h . toByteString $ "0000000000 65535 f \n" + B.hPut h . B.concat . tail . reverse $ toc + B.hPut h . toByteString $ "\ntrailer\n" + B.hPut h $ toPDF $ PDFDictionary. M.fromList $ + [ (PDFName "Size",AnyPdfObject . PDFInteger $ nb) + , (PDFName "Root",AnyPdfObject root) + ] + B.hPut h . toByteString $ "\nstartxref\n" + B.hPut h . toByteString $ (show len) + B.hPut h . toByteString $ "\n%%EOF" + where + pointer (x,a) = PDFReferencedObject (fromIntegral x) a + vars = PdfState { + supplySrc = 1 + , objects = IM.empty + , pages = noPages + , streams = IM.empty + , catalog = PDFReference 0 + , defaultRect = rect + } addfile ./Graphics/PDF/Colors.hs hunk ./Graphics/PDF/Colors.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Colors for a PDF document +--------------------------------------------------------- +module Graphics.PDF.Colors( + -- * Colors + -- ** Types + Color(..) + -- ** Functions + , initColorSpace + , fillColor + , strokeColor + ) where + +import Graphics.PDF.Draw + +-- | A PDF color +data Color = Rgb !Double !Double !Double + +-- | Init the PDF color space to RGB. Required before being able to use the color functions. +initColorSpace :: Draw () +initColorSpace = writeCmd "\n/DeviceRGB CS\n/DeviceRGB cs\n" + +-- | Select the filling color +fillColor :: Color -- ^ Filling color + -> Draw () +fillColor (Rgb r g b) = writeCmd $ "\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " sc" + +-- | Select the drawing color +strokeColor :: Color -- ^ Drawing color + -> Draw () +strokeColor (Rgb r g b) = writeCmd $ "\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " SC" + addfile ./Graphics/PDF/Coordinates.hs hunk ./Graphics/PDF/Coordinates.hs 1 - +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Coordinates for a PDF document +--------------------------------------------------------- + +module Graphics.PDF.Coordinates( + -- * Geometry + -- ** Types + Angle(..) + , Matrix + -- ** Transformations + , rotate, translate, scale, identity + -- ** Frame of reference operators + , applyMatrix + ) + where + +import Graphics.PDF.LowLevel +import Graphics.PDF.Draw + +-- | Angle +data Angle = Degree PDFFloat -- ^ Angle in degrees + | Radian PDFFloat -- ^ Angle in radians + +-- | A transformation matrix. An affine transformation a b c d e f +-- +-- @ +-- a b e +-- c d f +-- 0 0 1 +-- @ + +data Matrix = Matrix !PDFFloat !PDFFloat !PDFFloat !PDFFloat !PDFFloat !PDFFloat deriving (Eq) + +-- | Identity matrix +identity :: Matrix +identity = Matrix 1.0 0 0 1.0 0 0 + +instance Show Matrix where + show (Matrix ma mb mc md me mf) = "Matrix " ++ (unwords [(show ma),(show mb),(show mc),(show md),(show me),(show mf)]) + +instance Num Matrix where + -- Matrix addition + (+) (Matrix ma mb mc md me mf ) (Matrix na nb nc nd ne nf) = + Matrix (ma+na) (mb+nb) (mc+nc) (md+nd) (me+ne) (mf+nf) + (*) (Matrix ma mb mc md me mf) (Matrix na nb nc nd ne nf) = + Matrix (ma*na+mb*nc) (ma*nb + mb*nd ) (mc*na+md*nc) (mc*nb +md*nd) (me*na+mf*nc+ne) (me*nb+mf*nd+nf) + negate (Matrix ma mb mc md me mf ) = + Matrix (-ma) (-mb) (-mc) (-md) (-me) (-mf) + abs m = m + signum _ = identity + fromInteger i = Matrix r 0 0 r 0 0 + where + r = fromInteger i + + +-- | Apply a transformation matrix to the current coordinate frame +applyMatrix :: Matrix -> Draw () +applyMatrix (Matrix a b c d e f) = + writeCmd $ "\n" ++ show (a) ++ " " ++ show (b) ++ " " ++ show (c) ++ " " ++ show (d) ++ " " ++ show (e) ++ " " ++ show (f) ++ " cm" + +-- | Rotation matrix +rotate :: Angle -- ^ Rotation angle + -> Matrix +rotate r = Matrix ( (cos radian)) ( (sin radian)) (- ( (sin radian))) ( (cos radian)) 0 0 + where + radian = case r of + Degree angle -> angle / 180 * pi + Radian angle -> angle + + +-- | Translation matrix +translate :: PDFFloat -- ^ Horizontal translation + -> PDFFloat -- ^ Vertical translation + -> Matrix +translate tx ty = Matrix 1 0 0 1 tx ty + + +-- | Scaling matrix +scale :: PDFFloat -- ^ Horizontal scaling + -> PDFFloat -- ^ Horizontal scaling + -> Matrix +scale sx sy = Matrix sx 0 0 sy 0 0 addfile ./Graphics/PDF/Data/PDFTree.hs hunk ./Graphics/PDF/Data/PDFTree.hs 1 - +{-# OPTIONS -cpp -fglasgow-exts -fno-bang-patterns #-} +----------------------------------------------------------------------------- +-- | +-- Module : PDFTree.hs +-- Copyright : (c) Daan Leijen 2002 +-- License : BSD-style +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : provisional +-- Portability : portable +-- +-- An efficient implementation of maps from integer keys to values. +-- +-- Customized by alpheccar for the need of the PDF library. The original is IntMap from +-- the ghc standard libraries +----------------------------------------------------------------------------- +-- #hide +module Graphics.PDF.Data.PDFTree( + PDFTree + , Key + , empty + , lookup + , insert + , fromList + , fold2 + , isLeaf + , size + , keyOf + ) where + +import Prelude hiding (lookup,map,filter,foldr,foldl,null) +import Data.Bits +#if __GLASGOW_HASKELL__ >= 503 +import GHC.Exts ( Word(..), Int(..), shiftRL# ) +#elif __GLASGOW_HASKELL__ +import Word +import GlaExts ( Word(..), Int(..), shiftRL# ) +#else +import Data.Word +#endif + +import Graphics.PDF.LowLevel + +type Nat = Word + +natFromInt :: Key a -> Nat +natFromInt (PDFReference i) = fromIntegral i + +intFromNat :: Nat -> Key a +intFromNat w = PDFReference (fromIntegral w) + +type Prefix a = PDFReference a +type Mask a = PDFReference a +type Key a = PDFReference a + +-- | A map of integers to values @a@. +-- The total size of subtrees is tracked by each node. It is needed for the PDF Tree +data PDFTree a = Nil + | Tip {-# UNPACK #-} !(Key a) a + | Bin {-# UNPACK #-} !Int {-# UNPACK #-} !(Prefix a) {-# UNPACK #-} !(Mask a) !(PDFTree a) !(PDFTree a) + deriving(Eq,Show) + +-- | The key function needed to export a Tree of PDF objects into the format defined +-- by the PDF spec +fold2 :: Monad m => Maybe b -- ^ Parent ref + -> (Maybe b -> PDFTree a -> PDFTree a -> m b) -- ^ Node action + -> (Maybe b -> Key a -> a -> m b) -- ^ Leaf action + -> PDFTree a -- ^ PDFTree + -> m b -- ^ Final action and reference of the root node +fold2 _ _ _ Nil = error "Page tree is empty" +fold2 p _ leaf (Tip k a) = leaf p k a +fold2 p node _ (Bin _ _ _ l r) = node p l r + + + +isLeaf :: PDFTree a -> Bool +isLeaf (Tip _ _) = True +isLeaf _ = False + +keyOf :: PDFTree a -> Key a +keyOf (Tip k _) = k +keyOf _ = error "No key for a node" + +{-------------------------------------------------------------------- + Query +--------------------------------------------------------------------} + +-- | /O(n)/. Number of elements in the map. +size :: PDFTree a -> Int +size t + = case t of + Bin s _ _ _ _ -> s + Tip _ _ -> 1 + Nil -> 0 + +-- | /O(min(n,W))/. Lookup the value at a key in the map. +lookup :: (Monad m) => Key a -> PDFTree a -> m a +lookup k t = case lookup' k t of + Just x -> return x + Nothing -> fail "Data.PDFTree.lookup: Key not found" + +lookup' :: Key a -> PDFTree a -> Maybe a +lookup' k t + = let nk = natFromInt k in seq nk (lookupN nk t) + +lookupN :: Nat -> PDFTree a -> Maybe a +lookupN k t + = case t of + Bin _ _ m l r + | zeroN k (natFromInt m) -> lookupN k l + | otherwise -> lookupN k r + Tip kx x + | (k == natFromInt kx) -> Just x + | otherwise -> Nothing + Nil -> Nothing + +zeroN :: Nat -> Nat -> Bool +zeroN i m = (i .&. m) == 0 + +insert :: Key a -> a -> PDFTree a -> PDFTree a +insert k x t + = case t of + Bin s p m l r + | nomatch k p m -> join k (Tip k x) p t + | zero k m -> Bin (s+1) p m (insert k x l) r + | otherwise -> Bin (s+1) p m l (insert k x r) + Tip ky _ + | k==ky -> Tip k x + | otherwise -> join k (Tip k x) ky t + Nil -> Tip k x + +join :: Prefix a -> PDFTree a -> Prefix a -> PDFTree a -> PDFTree a +join p1 t1 p2 t2 + | zero p1 m = Bin (size t1 + size t2) p m t1 t2 + | otherwise = Bin (size t1 + size t2) p m t2 t1 + where + m = branchMask p1 p2 + p = mask p1 m + +zero :: Key a -> Mask a -> Bool +zero i m + = (natFromInt i) .&. (natFromInt m) == 0 + +nomatch :: Key a -> Prefix a -> Mask a -> Bool +nomatch i p m + = (mask i m) /= p + +mask :: Key a -> Mask a -> Prefix a +mask i m + = maskW (natFromInt i) (natFromInt m) + +{-------------------------------------------------------------------- + Big endian operations +--------------------------------------------------------------------} +maskW :: Nat -> Nat -> Prefix a +maskW i m + = intFromNat (i .&. (complement (m-1) `xor` m)) + +branchMask :: Prefix a -> Prefix a -> Mask a +branchMask p1 p2 + = intFromNat (highestBitMask (natFromInt p1 `xor` natFromInt p2)) + +highestBitMask :: Nat -> Nat +highestBitMask x + = case (x .|. shiftRL x 1) of + x1 -> case (x1 .|. shiftRL x1 2) of + x2 -> case (x2 .|. shiftRL x2 4) of + x3 -> case (x3 .|. shiftRL x3 8) of + x4 -> case (x4 .|. shiftRL x4 16) of + x5 -> case (x5 .|. shiftRL x5 32) of -- for 64 bit platforms + x6 -> (x6 `xor` (shiftRL x6 1)) + +shiftRL :: Nat -> Int -> Nat +#if __GLASGOW_HASKELL__ +{-------------------------------------------------------------------- + GHC: use unboxing to get @shiftRL@ inlined. +--------------------------------------------------------------------} +shiftRL (W# x) (I# i) + = W# (shiftRL# x i) +#else +shiftRL x i = shiftR x i +#endif + +empty :: PDFTree a +empty + = Nil + +{-------------------------------------------------------------------- + Utilities +--------------------------------------------------------------------} +foldlStrict :: (a -> t -> a) -> a -> [t] -> a +foldlStrict f z xs + = case xs of + [] -> z + (x:xx) -> let z' = f z x in seq z' (foldlStrict f z' xx) + +-- | /O(n*min(n,W))/. Create a map from a list of key\/value pairs. +fromList :: [(Key a,a)] -> PDFTree a +fromList xs + = foldlStrict ins empty xs + where + ins t (k,x) = insert k x t + + + addfile ./Graphics/PDF/Document.hs hunk ./Graphics/PDF/Document.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Management of the PDF structure +--------------------------------------------------------- + +module Graphics.PDF.Document( + -- * Document actions + -- ** Page management + addPage + , findPage + , drawWithPage + -- ** Drawings + , createContent + , withNewContext + , emptyDrawing + ) where + +import Graphics.PDF.LowLevel +import Graphics.PDF.Draw +import Graphics.PDF.Pages +import Control.Monad.State +import Graphics.PDF.Colors +import qualified Data.IntMap as IM + +-- | Create a new PDF drawing object +createContent :: Draw a -- ^ List of drawing commands + -> PDF (PDFReference PDFStream) -- ^ Reference to the drawing +createContent (Draw a _) = do + -- Create a new stream + let ns = PDFStream (Draw a ()) + -- Create a new stream referenbce + streamref <- supply + modify $ \s -> s {streams = IM.insert streamref ns (streams s)} + return (PDFReference streamref) + + +-- | Add a new page to a PDF document +addPage :: Maybe PDFRect -- ^ Page size or default document's one + -> PDF (PDFReference PDFPage) -- ^ Reference to the new page +addPage rect' = do + rect <- maybe (gets defaultRect) return rect' + -- Get the root page reference + -- Create a new empty content for the page + pageContent <- createContent initColorSpace + -- Create a new page having as parent the root page + let page = PDFPage Nothing rect pageContent Nothing + -- Create a new page reference + pageref <-supply + -- Save the page since we may want to draw on it + modify $ \s -> s {pages = recordPage (PDFReference pageref) page (pages s)} + return (PDFReference pageref) + +-- | Draw on a given page +drawWithPage :: PDFReference PDFPage -- ^ Page + -> Draw a -- ^ Drawing commands + -> PDF () +drawWithPage page draw = do + -- Get the page dictionary + lPages <- gets pages + -- Get the stream dictionary + lStreams <- gets streams + -- Look for the page + let thePage = findPage page lPages + case thePage of + Nothing -> return () + -- If the page is found, get its stream reference and look for the stream + Just(PDFPage _ _ (PDFReference streamRef) _) -> do + let theContent = IM.lookup streamRef lStreams + case theContent of + Nothing -> return() + -- If the stream is found + Just (PDFStream c) -> do + -- Create a new cntent and update the stream + modify $ \s -> s {streams = IM.insert streamRef (PDFStream $ c >> draw >> return ()) lStreams} addfile ./Graphics/PDF/Draw.hs hunk ./Graphics/PDF/Draw.hs 1 - +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2006 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- PDF API for Haskell +--------------------------------------------------------- +-- #hide +module Graphics.PDF.Draw( + -- * Draw monad + Draw(..) + , PDFStream(..) + , writeCmd + , withNewContext + , emptyDrawing + ) where + +import Graphics.PDF.LowLevel +import qualified Data.ByteString.Lazy as B +import Control.Monad.Writer +import qualified Data.Map as M + +-- | PDF Stream content +data Draw a = Draw !B.ByteString !a + +-- | A PDF stream object +data PDFStream = PDFStream !(Draw ()) + +instance PdfObject (Draw a) where + toPDF (Draw a _) = B.concat [ toByteString "\nstream" + , newline + , a + , newline + , toByteString "endstream"] + +instance PdfObject PDFStream where + toPDF (PDFStream s@(Draw sc _)) = B.append (toPDF . PDFDictionary. M.fromList $ [ (PDFName "Length",AnyPdfObject (PDFLength r))]) (toPDF s) + where + r = (B.length sc) + 1 + +-- | Am empty stream content +emptyDrawing :: Draw () +emptyDrawing = Draw B.empty () + + +instance Functor Draw where + fmap f (Draw stream v) = Draw stream (f v) + +instance Monad Draw where + return a = Draw B.empty a + (Draw stream v) >>= f = let Draw stream' v' = f v in + Draw (B.append stream stream') v' + +instance MonadWriter B.ByteString Draw where + tell w = Draw w () + listen (Draw stream v) = Draw stream (v,stream) + pass (Draw stream (v,f)) = Draw (f stream) v + +writeCmd :: String -> Draw () +writeCmd = tell . toByteString + + +-- | Draw in a new drawing context without perturbing the previous context +-- that is restored after the draw +withNewContext :: Draw a -> Draw a +withNewContext m = do + writeCmd "\nq" + a <- m + writeCmd "\nQ" + return a addfile ./Graphics/PDF/LowLevel.hs hunk ./Graphics/PDF/LowLevel.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2006 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Low level stuff +--------------------------------------------------------- +-- #hide +module Graphics.PDF.LowLevel where + +import qualified Data.ByteString.Lazy as B +import Data.ByteString.Base(c2w) +import qualified Data.Map as M +import Data.List(intersperse) +import Data.Int +import Text.Printf + +import Graphics.PDF.UTF8 + + + +-- | PDF Objects +class PdfObject a where + toPDF :: a -> B.ByteString + +-- | Anonymous PDF object +data AnyPdfObject = forall a . PdfObject a => AnyPdfObject a + +instance PdfObject AnyPdfObject where + toPDF (AnyPdfObject a) = toPDF a + +-- | An integer in a PDF document +newtype PDFInteger = PDFInteger Int deriving(Eq,Show,Ord,Num) + +-- | A length in a PDF document +newtype PDFLength = PDFLength Int64 deriving(Eq,Show,Ord,Num) + +-- | A real number in a PDF document +newtype PDFFloat = PDFFloat Double deriving(Eq,Ord,Num,Fractional,Floating,RealFrac,Real) + +instance Show PDFFloat where + show (PDFFloat x) = printf "%.5f" x + +instance PdfObject PDFInteger where + toPDF (PDFInteger a) = toByteString (show a) + +instance PdfObject PDFLength where + toPDF (PDFLength a) = toByteString (show a) + +instance PdfObject PDFFloat where + toPDF (PDFFloat a) = toByteString (show a) + + + +-- | A PDFString +newtype PDFString = PDFString B.ByteString + +-- | Create a PDF string from an Haskell one +toPDFString :: String -> PDFString +toPDFString = PDFString . toByteString . escapeString + +-- | Convert an Haskell string to an UTF8 encoded bytestring +toByteString :: String -> B.ByteString +toByteString = B.pack . encode + +-- | Escape PDF characters which have a special meaning +escapeString :: String -> String +escapeString [] = [] +escapeString ('(':l) = '\\':'(':escapeString l +escapeString (')':l) = '\\':')':escapeString l +escapeString ('\\':l) = '\\':'\\':escapeString l +escapeString (a:l) = a:escapeString l + +-- Misc strings useful to build bytestrings + +lparen :: B.ByteString +lparen = B.singleton . c2w $ '(' + +rparen :: B.ByteString +rparen = B.singleton . c2w $ ')' + +lbracket :: B.ByteString +lbracket = B.singleton . c2w $ '[' + +rbracket :: B.ByteString +rbracket = B.singleton . c2w $ ']' + +bspace :: B.ByteString +bspace = B.singleton . c2w $ ' ' + +blt :: B.ByteString +blt = B.singleton . c2w $ '<' + +bgt :: B.ByteString +bgt = B.singleton . c2w $ '>' + +newline :: B.ByteString +newline = B.singleton . c2w $ '\n' + +noPdfObject :: B.ByteString +noPdfObject = B.empty + +instance PdfObject PDFString where + toPDF (PDFString a) = B.concat [ lparen + , a + , rparen + ] + + +-- | A PDFName object +newtype PDFName = PDFName String deriving(Eq,Ord) + +instance PdfObject PDFName where + toPDF (PDFName a) = toByteString ("/" ++ a) + +-- | A PDFArray +type PDFArray = [AnyPdfObject] + +instance PdfObject PDFArray where + toPDF l = B.concat $ (lbracket:intersperse bspace (map toPDF l)) ++ [bspace] ++ [rbracket] + +-- | A PDFDictionary + +newtype PDFDictionary = PDFDictionary (M.Map PDFName AnyPdfObject) + +instance PdfObject PDFDictionary where + toPDF (PDFDictionary a) = B.concat $ [blt,blt,newline] + ++ [convertLevel a] + ++ [bgt,bgt] + where + convertLevel _ = let convertItem key value current = B.concat $ [ toPDF key + , bspace + , toPDF value + , newline + , current + ] + + in + M.foldWithKey convertItem B.empty a + +-- | Am empty dictionary +emptyDictionary :: PDFDictionary +emptyDictionary = PDFDictionary M.empty + + + +-- | A PDF rectangle +data PDFRect = PDFRect !Int !Int !Int !Int + +instance PdfObject PDFRect where + toPDF (PDFRect a b c d) = toPDF . map (AnyPdfObject . PDFInteger) $ [a,b,c,d] + + +-- | A Referenced objects +data PDFReferencedObject a = PDFReferencedObject !Int !a + +instance PdfObject a => PdfObject (PDFReferencedObject a) where + toPDF (PDFReferencedObject referenceId obj) = + B.concat $ [ toByteString . show $ referenceId + , toByteString " 0 obj" + , newline + , toPDF obj + , newline + , toByteString "endobj" + , newline , newline + ] + +-- | A reference to a PDF object +data PDFReference s = PDFReference !Int deriving(Eq,Ord,Show) + + +instance PdfObject s => Num (PDFReference s) where + (+) (PDFReference a) (PDFReference b) = PDFReference (a+b) + (*) (PDFReference a) (PDFReference b) = PDFReference (a*b) + negate (PDFReference a) = PDFReference (negate a) + abs (PDFReference a) = PDFReference (abs a) + signum (PDFReference a) = PDFReference (signum a) + fromInteger a = PDFReference (fromInteger a) + +instance PdfObject s => PdfObject (PDFReference s) where + toPDF (PDFReference i) = B.concat $ [ toByteString . show $ i + , toByteString " 0 R"] + + + +instance (PdfObject a,PdfObject b) => PdfObject (Either a b) where + toPDF (Left a) = toPDF a + toPDF (Right a) = toPDF a + addfile ./Graphics/PDF/Pages.hs hunk ./Graphics/PDF/Pages.hs 1 - +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2006 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Low level page management +--------------------------------------------------------- +-- #hide +module Graphics.PDF.Pages( + -- * Low level stuff + -- ** Types + PDFPage(..) + , PDFPages(..) + , PDFProc(..) + , PDFResource(..) + , PdfState(..) + , PDF(..) + , PDFCatalog(..) + , PDFOutlines(..) + -- ** Page management + , findPage + , recordPage + , noPages + , addPages + -- ** PDF Object management + , addObject + , supply + , updateObject + ) where + +import qualified Data.IntMap as IM +import Control.Monad.State +import Graphics.PDF.LowLevel +import Graphics.PDF.Draw +import qualified Data.Map as M +import qualified Graphics.PDF.Data.PDFTree as PT hiding(PDFTree,Key) +import Graphics.PDF.Data.PDFTree(PDFTree,Key) +import Data.Maybe + +-- | The PDF Monad +newtype PDF a = PDF {unPDF :: StateT PdfState IO a} +#ifndef __HADDOCK__ + deriving (Functor, Monad, MonadState PdfState, MonadIO) +#endif + +-- | Returns a new unique identifier +supply :: PDF Int +supply = do + r <- gets supplySrc + modify $ \s -> s {supplySrc = r+1} + return r + +-- | Add an object to the PDF object dictionary and return a PDF reference +addObject :: PdfObject a => a -> PDF (PDFReference a) +addObject a = do + r <- supply + modify $ \s -> s {objects = IM.insert r (AnyPdfObject a) (objects s)} + return (PDFReference r) + + +-- | Update a referenced object with a new one +updateObject :: PdfObject a => PDFReference a -- ^ Reference to the initial object + -> a -- ^ New value + -> PDF () +updateObject (PDFReference i) obj = do + modify $ \s -> s {objects = IM.insert i (AnyPdfObject obj) (objects s)} + + + +-- | The PDF Catalog +data PDFCatalog = PDFCatalog + !(PDFReference PDFOutlines) + !(PDFReference PDFPages) + +-- | PDF outlines +data PDFOutlines = PDFOutlines + +-- | The PDF state +data PdfState = PdfState { supplySrc :: !Int -- ^ Supply of unique identfiers + , objects :: !(IM.IntMap AnyPdfObject) -- ^ Dictionary of PDF objects + , pages :: !Pages -- ^ Pages + , streams :: !(IM.IntMap (PDFStream)) -- ^ PDF Streams + , catalog :: !(PDFReference PDFCatalog) -- ^ Reference to the PDF catalog + , defaultRect :: !PDFRect -- ^ Default page size + } + +-- | A PDF Page object +#ifndef __HADDOCK__ +data PDFPage = PDFPage + !(Maybe (PDFReference PDFPages)) -- ^ Reference to parent + !PDFRect -- ^ Media box + !(PDFReference PDFStream) -- ^ Reference to content + !(Maybe (PDFReference PDFResource)) -- ^ Reference to resources +#else +data PDFPage +#endif + +instance Show PDFPage where + show _ = "PDFPage" + +-- | List of all pages +newtype Pages = Pages (PDFTree PDFPage) + +-- | PDF Pages +#ifndef __HADDOCK__ +data PDFPages = PDFPages + !Int + !(Maybe (PDFReference PDFPages)) -- ^ Reference to parent + [Either (PDFReference PDFPages) (PDFReference PDFPage)] +#else +data PDFPages +#endif + +-- | A PDF Resource +data PDFResource = PDFResource !(PDFReference PDFProc) + +-- | A PDFProc +data PDFProc = PDFProc + + +-- PDF Pages + +instance PdfObject PDFPages where + toPDF (PDFPages c Nothing l) = toPDF $ PDFDictionary. M.fromList $ + [ (PDFName "Type",AnyPdfObject (PDFName "Pages")) + , (PDFName "Kids",AnyPdfObject $ map AnyPdfObject l) + , (PDFName "Count",AnyPdfObject . PDFInteger $ c) + ] + toPDF (PDFPages c (Just parent) l) = toPDF $ PDFDictionary. M.fromList $ + [ (PDFName "Type",AnyPdfObject (PDFName "Pages")) + , (PDFName "Parent",AnyPdfObject parent) + , (PDFName "Kids",AnyPdfObject $ map AnyPdfObject l) + , (PDFName "Count",AnyPdfObject . PDFInteger $ c) + ] + + + +instance PdfObject PDFPage where + toPDF (PDFPage (Just parent) box content rsrc) = toPDF $ PDFDictionary. M.fromList $ + [ (PDFName "Type",AnyPdfObject (PDFName "Page")) + , (PDFName "Parent",AnyPdfObject parent) + , (PDFName "MediaBox",AnyPdfObject box) + , (PDFName "Contents",AnyPdfObject content) + , if isJust rsrc + then + (PDFName "Resources",AnyPdfObject . fromJust $ rsrc) + else + (PDFName "Resources",AnyPdfObject emptyDictionary) + ] + toPDF (PDFPage Nothing _ _ _) = noPdfObject + +instance PdfObject PDFResource where + toPDF (PDFResource l) = toPDF . PDFDictionary . M.fromList $ [ (PDFName "ProcSet",AnyPdfObject l)] + +instance PdfObject PDFProc where + toPDF (PDFProc) = toPDF . map AnyPdfObject$ [PDFName "PDF"] + +-- Main objects in a PDF document + + + + +instance PdfObject PDFCatalog where + toPDF (PDFCatalog outlines lPages) = toPDF $ PDFDictionary . M.fromList $ + [ (PDFName "Type",AnyPdfObject (PDFName "Catalog")) + , (PDFName "Outlines",AnyPdfObject outlines) + , (PDFName "Pages",AnyPdfObject lPages) + ] + +-- PDF Outlines + +instance PdfObject PDFOutlines where + toPDF (PDFOutlines) = toPDF $ PDFDictionary. M.fromList $ + [ (PDFName "Type",AnyPdfObject (PDFName "Outlines")) + , (PDFName "Count",AnyPdfObject (PDFInteger 0)) + ] + + +-- | Record the page in the page catalog +recordPage :: PDFReference PDFPage -- ^ Reference to the page + -> PDFPage -- ^ Page content + -> Pages -- ^ Pages n the documents + -> Pages +recordPage pageref page (Pages lPages) = Pages (PT.insert pageref page lPages) + +-- | Find a page in the catalog +findPage :: PDFReference PDFPage -- ^ Reference to the page + -> Pages -- ^ Pages in the document + -> Maybe PDFPage -- ^ Page content if found +findPage page (Pages lPages) = PT.lookup page lPages + +-- | Add a node PDFTree object +nodePage :: Maybe (PDFReference PDFPages) -- ^ Parent node + -> PDFTree PDFPage -- ^ Left tree + -> PDFTree PDFPage -- ^ Right tree + -> PDF (PDFReference PDFPages) -- ^ PDF reference to the new node pointing to the left and right ones +nodePage ref l r = do + n <- supply + -- Reserve an identifier for the root page object + let pRef = (PDFReference n) :: PDFReference PDFPages + lr <- PT.fold2 (Just pRef) nodePage leafPage l + rr <- PT.fold2 (Just pRef) nodePage leafPage r + case (PT.isLeaf l,PT.isLeaf r) of + (False,False) -> updateObject pRef $ PDFPages (PT.size l + PT.size r) ref [Left lr,Left rr] + (True,False) -> updateObject pRef $ PDFPages (PT.size l + PT.size r) ref [Right (PT.keyOf l),Left rr] + (False,True) -> updateObject pRef $ PDFPages (PT.size l + PT.size r) ref [Left lr,Right (PT.keyOf r)] + (True,True) -> updateObject pRef $ PDFPages (PT.size l + PT.size r) ref [Right (PT.keyOf l),Right (PT.keyOf r)] + return pRef + + +-- | Add a page to the PDG object dictionary +leafPage :: Maybe (PDFReference PDFPages) -- ^ Page parent if any + -> Key PDFPage -- ^ Page reference + -> PDFPage -- ^ Page data + -> PDF (PDFReference PDFPages) -- ^ Reference to a PDFPages objects +leafPage (Just ref) (PDFReference objectnb) (PDFPage _ a b c) = do + modify $ \s -> s {objects = IM.insert objectnb (AnyPdfObject . PDFPage (Just ref) a b $ c) (objects s) } + return ref + +leafPage Nothing p@(PDFReference objectnb) (PDFPage _ a b c) = do + n <- supply + -- Reserve an identifier for the root page object + let pRef = (PDFReference n) :: PDFReference PDFPages + updateObject pRef $ PDFPages 1 Nothing [Right p] + modify $ \s -> s {objects = IM.insert objectnb (AnyPdfObject . PDFPage (Just pRef) a b $ c) (objects s) } + return pRef + +-- | Add all pages to the PDF object dictionary +addPages :: PDF (PDFReference PDFPages) +addPages = do + Pages lPages <- gets pages + PT.fold2 Nothing nodePage leafPage lPages + +-- | Empty page catalog +noPages :: Pages +noPages = Pages (PT.empty) + addfile ./Graphics/PDF/Shapes.hs hunk ./Graphics/PDF/Shapes.hs 1 - +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- PDF Shapes +--------------------------------------------------------- + +module Graphics.PDF.Shapes( + -- * Shapes + -- ** Types + Point + , Polygon + -- ** Lines + , moveto + , lineto + -- ** Polygons + , drawPolygon + , fillPolygon + , fillAndDrawPolygon + ) where + +import Graphics.PDF.LowLevel +import Graphics.PDF.Draw + +-- | Move pen to a given point without drawing anything +moveto :: PDFFloat -- ^ Horizontal coordinate + -> PDFFloat -- ^ Vertical coordinate + -> Draw () +moveto x y = writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " m" + +-- | Draw a line from current point to the one specified by lineto +lineto :: PDFFloat -- ^ Horizontal coordinate + -> PDFFloat -- ^ Vertical coordinate + -> Draw () +lineto x y = writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " l s" + +-- | A point +type Point = (PDFFloat,PDFFloat) + +-- | A polygon +type Polygon = [Point] + +-- | Close a polygon and draw it +drawPolygon :: Polygon -> Draw () +drawPolygon l = do + (uncurry moveto) . head $ l + mapM_ (\(x,y) -> writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " l") (tail l) + writeCmd " h S" + +-- | Close a polygon and fill it +fillPolygon :: Polygon -> Draw () +fillPolygon l = do + (uncurry moveto) . head $ l + mapM_ (\(x,y) -> writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " l") (tail l) + writeCmd " h f" + +-- | Close a polygon. Draw and fill it +fillAndDrawPolygon :: Polygon -> Draw () +fillAndDrawPolygon l = do + (uncurry moveto) . head $ l + mapM_ (\(x,y) -> writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " l") (tail l) + writeCmd " h B" addfile ./Graphics/PDF/UTF8.lhs hunk ./Graphics/PDF/UTF8.lhs 1 +Copyright (c) 2002, members of the Haskell Internationalisation Working +Group All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of the Haskell Internationalisation Working Group nor + the names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +This module provides lazy stream encoding/decoding facilities for UTF-8, +the Unicode Transformation Format with 8-bit words. + +2002-09-02 Sven Moritz Hallberg + + +> module Graphics.PDF.UTF8 +> ( encode, decode, +> encodeOne, decodeOne, +> ) where + +> import Char (ord, chr) +> import Data.Word (Word8, Word16, Word32) +> import Data.Bits (Bits, shiftL, shiftR, (.&.), (.|.)) + + + +///- UTF-8 in General -/// + +Adapted from the Unicode standard, version 3.2, +Table 3.1 "UTF-8 Bit Distribution" (excluded are UTF-16 encodings): + + Scalar 1st Byte 2nd Byte 3rd Byte 4th Byte + 000000000xxxxxxx 0xxxxxxx + 00000yyyyyxxxxxx 110yyyyy 10xxxxxx + zzzzyyyyyyxxxxxx 1110zzzz 10yyyyyy 10xxxxxx + 000uuuzzzzzzyyyyyyxxxxxx 11110uuu 10zzzzzz 10yyyyyy 10xxxxxx + +Also from the Unicode standard, version 3.2, +Table 3.1B "Legal UTF-8 Byte Sequences": + + Code Points 1st Byte 2nd Byte 3rd Byte 4th Byte + U+0000..U+007F 00..7F + U+0080..U+07FF C2..DF 80..BF + U+0800..U+0FFF E0 A0..BF 80..BF + U+1000..U+CFFF E1..EC 80..BF 80..BF + U+D000..U+D7FF ED 80..9F 80..BF + U+D800..U+DFFF ill-formed + U+E000..U+FFFF EE..EF 80..BF 80..BF + U+10000..U+3FFFF F0 90..BF 80..BF 80..BF + U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF + U+100000..U+10FFFF F4 80..8F 80..BF 80..BF + + + +///- Encoding Functions -/// + +Must the encoder ensure that no illegal byte sequences are output or +can we trust the Haskell system to supply only legal values? +For now I include error case for the surrogate values U+D800..U+DFFF and +out-of-range scalars. + +The function is pretty much a transscript of table 3.1B with error checks. +It dispatches the actual encoding to functions specific to the number of +required bytes. + +> encodeOne :: Char -> [Word8] +> encodeOne c +>-- The report guarantees in (6.1.2) that this won't happen: +>-- | n < 0 = error "encodeUTF8: ord returned a negative value" +> | n < 0x0080 = encodeOne_onebyte n8 +> | n < 0x0800 = encodeOne_twobyte n16 +> | n < 0xD800 = encodeOne_threebyte n16 +> | n < 0xE000 = error "encodeUTF8: ord returned a surrogate value" +> | n < 0x10000 = encodeOne_threebyte n16 +>-- Haskell 98 only talks about 16 bit characters, but ghc handles 20.1. +> | n < 0x10FFFF = encodeOne_fourbyte n32 +> | otherwise = error "encodeUTF8: ord returned a value above 0x10FFFF" +> where +> n = ord c :: Int +> n8 = fromIntegral n :: Word8 +> n16 = fromIntegral n :: Word16 +> n32 = fromIntegral n :: Word32 + + +With the above, a stream decoder is trivial: + +> encode :: [Char] -> [Word8] +> encode = concatMap encodeOne + + +Now follow the individual encoders for certain numbers of bytes... + _ + / | __ ___ __ __ + / ^| // /__/ // // + /.==| \\ //_ // // +It's // || // \_/_//_//_ and it's here to stay! + +> encodeOne_onebyte :: Word8 -> [Word8] +> encodeOne_onebyte cp = [cp] + + +00000yyyyyxxxxxx -> 110yyyyy 10xxxxxx + +> encodeOne_twobyte :: Word16 -> [Word8] +> encodeOne_twobyte cp = [(0xC0.|.ys), (0x80.|.xs)] +> where +> xs, ys :: Word8 +> ys = fromIntegral (shiftR cp 6) +> xs = (fromIntegral cp) .&. 0x3F + + +zzzzyyyyyyxxxxxx -> 1110zzzz 10yyyyyy 10xxxxxx + +> encodeOne_threebyte :: Word16 -> [Word8] +> encodeOne_threebyte cp = [(0xE0.|.zs), (0x80.|.ys), (0x80.|.xs)] +> where +> xs, ys, zs :: Word8 +> xs = (fromIntegral cp) .&. 0x3F +> ys = (fromIntegral (shiftR cp 6)) .&. 0x3F +> zs = fromIntegral (shiftR cp 12) + + +000uuuzzzzzzyyyyyyxxxxxx -> 11110uuu 10zzzzzz 10yyyyyy 10xxxxxx + +> encodeOne_fourbyte :: Word32 -> [Word8] +> encodeOne_fourbyte cp = [0xF0.|.us, 0x80.|.zs, 0x80.|.ys, 0x80.|.xs] +> where +> xs, ys, zs, us :: Word8 +> xs = (fromIntegral cp) .&. 0x3F +> ys = (fromIntegral (shiftR cp 6)) .&. 0x3F +> zs = (fromIntegral (shiftR cp 12)) .&. 0x3F +> us = fromIntegral (shiftR cp 18) + + + +///- Decoding -/// + +The decoding is a bit more involved. The byte sequence could contain all +sorts of corruptions. The user must be able to either notice or ignore these +errors. + +I will first look at the decoding of a single character. The process +consumes a certain number of bytes from the input. It returns the +remaining input and either an error and the index of its occurance in the +byte sequence or the decoded character. + +> data Error + +The first byte in a sequence starts with either zero, two, three, or four +ones and one zero to indicate the length of the sequence. If it doesn't, +it is invalid. It is dropped and the next byte interpreted as the start +of a new sequence. + +> = InvalidFirstByte + +All bytes in the sequence except the first match the bit pattern 10xxxxxx. +If one doesn't, it is invalid. The sequence up to that point is dropped +and the "invalid" byte interpreted as the start of a new sequence. The error +includes the length of the partial sequence and the number of expected bytes. + +> | InvalidLaterByte Int -- the byte at relative index n was invalid + +If a sequence ends prematurely, it has been truncated. It dropped and +decoding stops. The error reports the actual and expected lengths of the +sequence. + +> | Truncated Int Int -- only n of m expected bytes were present + +Some sequences would represent code points which would be encoded as a +shorter sequence by a conformant encoder. Such non-shortest sequences are +considered erroneous and dropped. The error reports the actual and +expected number of bytes used. + +> | NonShortest Int Int -- n instead of m bytes were used + +Unicode code points are in the range of [0..0x10FFFF]. Any values outside +of those bounds are simply invalid. + +> | ValueOutOfBounds + +There is no such thing as "surrogate pairs" any more in UTF-8. The +corresponding code points now form illegal byte sequences. + +> | Surrogate +> deriving (Show, Eq) + + +Second, third, and fourth bytes share the common requirement to start +with the bit sequence 10. So, here's the function to check that property. + +> first_bits_not_10 :: Word8 -> Bool +> first_bits_not_10 b +> | (b.&.0xC0) /= 0x80 = True +> | otherwise = False + + +Erm, OK, the single-character decoding function's return type is a bit +longish. It is a tripel: + + - The first component contains the decoded character or an error + if the byte sequence was erroneous. + - The second component contains the number of bytes that were consumed + from the input. + - The third component contains the remaining bytes of input. + +> decodeOne :: [Word8] -> (Either Error Char, Int, [Word8]) +> decodeOne bs@(b1:rest) +> | b1 < 0x80 = decodeOne_onebyte bs +> | b1 < 0xC0 = (Left InvalidFirstByte, 1, rest) +> | b1 < 0xE0 = decodeOne_twobyte bs +> | b1 < 0xEE = decodeOne_threebyte bs +> | b1 < 0xF5 = decodeOne_fourbyte bs +> | otherwise = (Left ValueOutOfBounds, 1, rest) +> decodeOne [] = error "UTF8.decodeOne: No input" + + +0xxxxxxx -> 000000000xxxxxxx + +> decodeOne_onebyte :: [Word8] -> (Either Error Char, Int, [Word8]) +> decodeOne_onebyte (b:bs) = (Right (cpToChar b), 1, bs) +> decodeOne_onebyte[] = error "UTF8.decodeOne_onebyte: No input (can't happen)" + +> cpToChar :: Integral a => a -> Char +> cpToChar = chr . fromIntegral + + +110yyyyy 10xxxxxx -> 00000yyyyyxxxxxx + +> decodeOne_twobyte :: [Word8] -> (Either Error Char, Int, [Word8]) +> decodeOne_twobyte (_:[]) +> = (Left (Truncated 1 2), 1, []) +> decodeOne_twobyte (b1:b2:bs) +> | b1 < 0xC2 = (Left (NonShortest 2 1), 2, bs) +> | first_bits_not_10 b2 = (Left (InvalidLaterByte 1), 1, (b2:bs)) +> | otherwise = (Right (cpToChar result), 2, bs) +> where +> xs, ys, result :: Word32 +> xs = fromIntegral (b2.&.0x3F) +> ys = fromIntegral (b1.&.0x1F) +> result = shiftL ys 6 .|. xs +> decodeOne_twobyte[] = error "UTF8.decodeOne_twobyte: No input (can't happen)" + + +1110zzzz 10yyyyyy 10xxxxxx -> zzzzyyyyyyxxxxxx + +> decodeOne_threebyte :: [Word8] -> (Either Error Char, Int, [Word8]) +> decodeOne_threebyte (_:[]) = threebyte_truncated 1 +> decodeOne_threebyte (_:_:[]) = threebyte_truncated 2 +> decodeOne_threebyte bs@(b1:b2:b3:rest) +> | first_bits_not_10 b2 +> = (Left (InvalidLaterByte 1), 1, drop 1 bs) +> | first_bits_not_10 b3 +> = (Left (InvalidLaterByte 2), 2, drop 2 bs) +> | result < 0x0080 +> = (Left (NonShortest 3 1), 3, rest) +> | result < 0x0800 +> = (Left (NonShortest 3 2), 3, rest) +> | result >= 0xD800 && result < 0xE000 +> = (Left Surrogate, 3, rest) +> | otherwise +> = (Right (cpToChar result), 3, rest) +> where +> xs, ys, zs, result :: Word32 +> xs = fromIntegral (b3.&.0x3F) +> ys = fromIntegral (b2.&.0x3F) +> zs = fromIntegral (b1.&.0x0F) +> result = shiftL zs 12 .|. shiftL ys 6 .|. xs +> decodeOne_threebyte[] +> = error "UTF8.decodeOne_threebyte: No input (can't happen)" + +> threebyte_truncated :: Int -> (Either Error Char, Int, [Word8]) +> threebyte_truncated n = (Left (Truncated n 3), n, []) + + +11110uuu 10zzzzzz 10yyyyyy 10xxxxxx -> 000uuuzzzzzzyyyyyyxxxxxx + +> decodeOne_fourbyte :: [Word8] -> (Either Error Char, Int, [Word8]) +> decodeOne_fourbyte (_:[]) = fourbyte_truncated 1 +> decodeOne_fourbyte (_:_:[]) = fourbyte_truncated 2 +> decodeOne_fourbyte (_:_:_:[]) = fourbyte_truncated 3 +> decodeOne_fourbyte bs@(b1:b2:b3:b4:rest) +> | first_bits_not_10 b2 +> = (Left (InvalidLaterByte 1), 1, drop 1 bs) +> | first_bits_not_10 b3 +> = (Left (InvalidLaterByte 2), 2, drop 2 bs) +> | first_bits_not_10 b4 +> = (Left (InvalidLaterByte 3), 3, drop 3 bs) +> | result < 0x0080 +> = (Left (NonShortest 4 1), 4, rest) +> | result < 0x0800 +> = (Left (NonShortest 4 2), 4, rest) +> | result < 0x10000 +> = (Left (NonShortest 4 3), 4, rest) +> | result > 0x10FFFF +> = (Left ValueOutOfBounds, 4, rest) +> | otherwise +> = (Right (cpToChar result), 4, rest) +> where +> xs, ys, zs, us, result :: Word32 +> xs = fromIntegral (b4 .&. 0x3F) +> ys = fromIntegral (b3 .&. 0x3F) +> zs = fromIntegral (b2 .&. 0x3F) +> us = fromIntegral (b1 .&. 0x07) +> result = xs .|. shiftL ys 6 .|. shiftL zs 12 .|. shiftL us 18 +> decodeOne_fourbyte[] +> = error "UTF8.decodeOne_fourbyte: No input (can't happen)" + +> fourbyte_truncated :: Int -> (Either Error Char, Int, [Word8]) +> fourbyte_truncated n = (Left (Truncated n 4), n, []) + + +The decoder examines all input, recording decoded characters as well as +error-index pairs along the way. + +> decode :: [Word8] -> ([Char], [(Error,Int)]) +> decode bytes = iter 0 [] [] bytes +> where +> iter :: Int -> [Char] -> [(Error,Int)] -> [Word8] +> -> ([Char], [(Error,Int)]) +> iter _ cs es [] = (reverse cs, reverse es) +> iter idx cs es bs +> = case decodeOne bs of +> (Left e, n, rest) -> iter (idx+n) cs ((e,idx):es) rest +> (Right c, n, rest) -> iter (idx+n) (c:cs) es rest + addfile ./HPDF.cabal hunk ./HPDF.cabal 1 +Name: HPDF +Version: 1.0 +License: LGPL +License-file:LICENSE +Copyright: Copyright (c) 2007, alpha +category: Graphics +synopsis: PDF API for Haskell +maintainer: misc@NOSPAMalpheccar.org +homepage: http://www.alpheccar.org +exposed-Modules: + Graphics.PDF, + Graphics.PDF.Colors, + Graphics.PDF.Coordinates, + Graphics.PDF.Document, + Graphics.PDF.Draw, + Graphics.PDF.LowLevel, + Graphics.PDF.Pages, + Graphics.PDF.Shapes, + Graphics.PDF.UTF8 +build-depends: base, haskell98,mtl +extensions: CPP +ghc-options: -Wall -funbox-strict-fields -fglasgow-exts -O2 addfile ./LICENSE hunk ./LICENSE 1 +* Copyright (c) 2007, alpheccar.org +* All rights reserved. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of alpheccar.org nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* UTF8.lhs : Copyright Sven Moritz Hallberg. See the comments in the file. +* PDFTree.hs reusing the code from IntMap : Copyright Daan Leijen. See the comments in the file. + addfile ./README.txt hunk ./README.txt 1 +TO BUILD AND INSTALL THE LIBRARY +================================ + +ghc-pkg unregister HPDF-0.x if you already installed an older version. +ghc-pkg list to check which version is already installed. + +runghc Setup.hs configure or runghc Setup.hs configure -p if you also want to build the profiling version +runghc Setup.hs build +runghc Setup.hs haddock to generate again the HTML pages (optional - only if you have haddock installed) +runghc Setup.hs install (you may have to use sudo) +runghc Setup.hs clean (warning : will clean the HTML pages) + +TO TEST THE LIBRARY +===================== +cd Test +make test : for a simpler test +make : to test the software with the installed library +make prof : to build a profiling version +make clean : to clean everything. + addfile ./Setup.hs hunk ./Setup.hs 1 - +module Main where +import Distribution.Simple( defaultMain ) +main = defaultMain addfile ./Test/Makefile hunk ./Test/Makefile 1 +debug: + ghc -o test -cpp -Wall -funbox-strict-fields -fglasgow-exts -O2 -hidir interfaces -odir bin -i.. --make test.hs + + +prof: + ghc -o test -prof -auto-all -cpp -funbox-strict-fields -fglasgow-exts -O2 -hidir interfaces -odir bin -i.. --make test.hs + +clean: + rm -f test + rm -f *.o + rm -f *.hi + rm -f *.exe + rm -f test.prof + rm -f *.pdf + rm -rf bin + rm -rf interfaces + mkdir bin + mkdir interfaces + addfile ./Test/Penrose.hs hunk ./Test/Penrose.hs 1 - +module Penrose where + +import System.Environment +import Graphics.PDF + +golden :: PDFFloat +golden = ((sqrt 5) + 1) / 2 + +phi :: PDFFloat +phi = 36 / 180 * pi + +blue :: Color +blue = Rgb 0.8 0.8 1 + +green :: Color +green = Rgb 0.8 1 0.8 + +black :: Color +black = Rgb 0 0 0 + +width :: PDFFloat +width = 300 + +data Tile = A | B | A' | B' + +tilea :: PDFFloat -> Tile -> Int -> Draw () +tilea angle k n = withNewContext $ do + applyMatrix (translate width 0) + applyMatrix (rotate . Degree $ angle) + applyMatrix (scale (1/golden) (1/golden)) + divide (n-1) k + + +tileb :: PDFFloat -> Tile -> Int -> Draw () +tileb angle k n = withNewContext $ do + applyMatrix (translate (width*golden) 0) + applyMatrix (rotate . Degree $ angle) + applyMatrix (scale (1/golden) (1/golden)) + divide (n-1) k + + +divide :: Int -> Tile -> Draw () +divide n A | n == 0 = a width + | otherwise = do + tilea 108 A n + tilea 180 B' n + +divide n A' | n == 0 = a' width + | otherwise = do + tilea (-108) A' n + tilea 180 B n + +divide n B | n == 0 = b width + | otherwise = do + tileb 144 B n + tilea 108 A n + tilea 180 B' n + +divide n B' | n == 0 = b' width + | otherwise = do + tileb (-144) B' n + tilea (-108) A' n + tilea 180 B n + + +b :: PDFFloat -> Draw () +b s = do + fillColor blue + strokeColor blue + let pol = [ (0,0) + , ((s*cos(phi)),(s*sin(phi))) + , ((s*golden),0) + ] + fillAndDrawPolygon pol + strokeColor black + drawPolygon pol + + +b' :: PDFFloat -> Draw () +b' s = withNewContext $ do + applyMatrix (scale 1 (-1)) + b s + + +a :: PDFFloat -> Draw () +a s = do + fillColor green + strokeColor green + let pol = [ (0,0) + , ((s*cos(phi)),(s*sin(phi))) + , (s,0) + ] + fillAndDrawPolygon pol + strokeColor black + drawPolygon pol + +a' :: PDFFloat -> Draw () +a' s = withNewContext $ do + applyMatrix (scale 1 (-1)) + a s + +penrose :: Int -> Draw () +penrose n = do + applyMatrix (rotate . Degree $ 36) + divide n B + divide n B' + + + +testPenrose :: IO () +testPenrose = + do nb <- getArgs + let rect = PDFRect 0 0 (round (1.5*width)) (round width) + runPdf ("penrose_" ++ (head nb) ++ ".pdf") rect $ \page -> do + drawWithPage page $ do + initColorSpace + applyMatrix (translate 20 5) + penrose ((read . head $ nb)::Int) + + addfile ./Test/test.hs hunk ./Test/test.hs 1 - +--------------------------------------------------------------------------- +-- | +-- Module : Main +-- Copyright : (c) Christophe Favergeon, 2007 +-- License : BSD-style +-- +-- Maintainer : c-favergeon-borgialli@ti.com +-- Stability : experimental +-- Portability : portable +-- +-- Description +-- +-- Some text +-- +-- See below for examples. + +----------------------------------------------------------------------------- + + +module Main where + + +import Graphics.PDF +import Penrose + +simple :: IO () +simple = do + let rect = PDFRect 0 0 612 792 + runPdf "test.pdf" rect $ \page -> do + drawWithPage page $ do + initColorSpace + strokeColor (Rgb 1 0 0) + fillColor (Rgb 0 0 1) + (withNewContext $ do + applyMatrix (scale 0.5 0.5) + applyMatrix (translate 300 0) + draw) + draw + mapM_ (const $ addPage Nothing) [1..10] + return () + where + draw = do + moveto 0 0 + lineto 100 100 + let poly = [(100,100),(200,100),(200,200),(100,200)] + fillPolygon poly + + +-- | Get options and set config +main :: IO() +main = do + simple + testPenrose hunk ./Graphics/PDF.hs 31 + -- ** Misc (until the right module is created) + , toPDFString hunk ./Graphics/PDF.hs 94 + +-- | The PDFTrailer +#ifndef __HADDOCK__ +data PDFTrailer = PDFTrailer + !Int -- ^ Number of PDF objects in the document + !(PDFReference PDFCatalog) -- ^ Reference to the PDf catalog + !(PDFDocumentInfo) +#else +data PDFTrailer +#endif + +instance PdfObject PDFTrailer where + toPDF (PDFTrailer size root infos) = toPDF $ PDFDictionary. M.fromList $ + [ (PDFName "Size",AnyPdfObject . PDFInteger $ size) + , (PDFName "Root",AnyPdfObject root) + , (PDFName "Info",AnyPdfObject . PDFDictionary . M.fromList $ allInfos) + ] + where + getField (_,Nothing) = [] + getField (name,Just r) = [(name,AnyPdfObject r)] + allInfos = concat . map (getField) $ [ (PDFName "Author",author infos) + , (PDFName "Subject",subject infos) + ] hunk ./Graphics/PDF.hs 120 + -> PDFDocumentInfo hunk ./Graphics/PDF.hs 124 -runPdf filename rect m = do +runPdf filename docInfo rect m = do hunk ./Graphics/PDF.hs 135 - B.hPut h $ toPDF $ PDFDictionary. M.fromList $ - [ (PDFName "Size",AnyPdfObject . PDFInteger $ nb) - , (PDFName "Root",AnyPdfObject root) - ] + B.hPut h . toPDF $ PDFTrailer nb root docInfo hunk ./Graphics/PDF/Document.hs 23 + -- ** Document information + , PDFDocumentInfo(..) + , standardDocInfo hunk ./Graphics/PDF/Document.hs 35 +-- | Document metadata +data PDFDocumentInfo = PDFDocumentInfo { + author :: Maybe PDFString + , subject :: Maybe PDFString + } + +-- | No information for the document +standardDocInfo :: PDFDocumentInfo +standardDocInfo = PDFDocumentInfo Nothing Nothing + hunk ./Graphics/PDF/LowLevel.hs 22 -import Graphics.PDF.UTF8 - +--import Graphics.PDF.UTF8 +import Data.Encoding +import Data.Encoding.UTF8 +import Data.Encoding.UTF16 hunk ./Graphics/PDF/LowLevel.hs 66 -toPDFString = PDFString . toByteString . escapeString +toPDFString = PDFString . encodeLazy UTF16 . escapeString hunk ./Graphics/PDF/LowLevel.hs 70 -toByteString = B.pack . encode +--toByteString = B.pack . encode +toByteString = encodeLazy UTF8 hunk ./Graphics/PDF/Pages.hs 58 -addObject :: PdfObject a => a -> PDF (PDFReference a) +addObject :: (PdfObject a) => a -> PDF (PDFReference a) hunk ./Graphics/PDF/Pages.hs 66 -updateObject :: PdfObject a => PDFReference a -- ^ Reference to the initial object +updateObject :: (PdfObject a) => PDFReference a -- ^ Reference to the initial object hunk ./Graphics/PDF/UTF8.lhs 1 -Copyright (c) 2002, members of the Haskell Internationalisation Working -Group All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -* Neither the name of the Haskell Internationalisation Working Group nor - the names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -This module provides lazy stream encoding/decoding facilities for UTF-8, -the Unicode Transformation Format with 8-bit words. - -2002-09-02 Sven Moritz Hallberg - - -> module Graphics.PDF.UTF8 -> ( encode, decode, -> encodeOne, decodeOne, -> ) where - -> import Char (ord, chr) -> import Data.Word (Word8, Word16, Word32) -> import Data.Bits (Bits, shiftL, shiftR, (.&.), (.|.)) - - - -///- UTF-8 in General -/// - -Adapted from the Unicode standard, version 3.2, -Table 3.1 "UTF-8 Bit Distribution" (excluded are UTF-16 encodings): - - Scalar 1st Byte 2nd Byte 3rd Byte 4th Byte - 000000000xxxxxxx 0xxxxxxx - 00000yyyyyxxxxxx 110yyyyy 10xxxxxx - zzzzyyyyyyxxxxxx 1110zzzz 10yyyyyy 10xxxxxx - 000uuuzzzzzzyyyyyyxxxxxx 11110uuu 10zzzzzz 10yyyyyy 10xxxxxx - -Also from the Unicode standard, version 3.2, -Table 3.1B "Legal UTF-8 Byte Sequences": - - Code Points 1st Byte 2nd Byte 3rd Byte 4th Byte - U+0000..U+007F 00..7F - U+0080..U+07FF C2..DF 80..BF - U+0800..U+0FFF E0 A0..BF 80..BF - U+1000..U+CFFF E1..EC 80..BF 80..BF - U+D000..U+D7FF ED 80..9F 80..BF - U+D800..U+DFFF ill-formed - U+E000..U+FFFF EE..EF 80..BF 80..BF - U+10000..U+3FFFF F0 90..BF 80..BF 80..BF - U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF - U+100000..U+10FFFF F4 80..8F 80..BF 80..BF - - - -///- Encoding Functions -/// - -Must the encoder ensure that no illegal byte sequences are output or -can we trust the Haskell system to supply only legal values? -For now I include error case for the surrogate values U+D800..U+DFFF and -out-of-range scalars. - -The function is pretty much a transscript of table 3.1B with error checks. -It dispatches the actual encoding to functions specific to the number of -required bytes. - -> encodeOne :: Char -> [Word8] -> encodeOne c ->-- The report guarantees in (6.1.2) that this won't happen: ->-- | n < 0 = error "encodeUTF8: ord returned a negative value" -> | n < 0x0080 = encodeOne_onebyte n8 -> | n < 0x0800 = encodeOne_twobyte n16 -> | n < 0xD800 = encodeOne_threebyte n16 -> | n < 0xE000 = error "encodeUTF8: ord returned a surrogate value" -> | n < 0x10000 = encodeOne_threebyte n16 ->-- Haskell 98 only talks about 16 bit characters, but ghc handles 20.1. -> | n < 0x10FFFF = encodeOne_fourbyte n32 -> | otherwise = error "encodeUTF8: ord returned a value above 0x10FFFF" -> where -> n = ord c :: Int -> n8 = fromIntegral n :: Word8 -> n16 = fromIntegral n :: Word16 -> n32 = fromIntegral n :: Word32 - - -With the above, a stream decoder is trivial: - -> encode :: [Char] -> [Word8] -> encode = concatMap encodeOne - - -Now follow the individual encoders for certain numbers of bytes... - _ - / | __ ___ __ __ - / ^| // /__/ // // - /.==| \\ //_ // // -It's // || // \_/_//_//_ and it's here to stay! - -> encodeOne_onebyte :: Word8 -> [Word8] -> encodeOne_onebyte cp = [cp] - - -00000yyyyyxxxxxx -> 110yyyyy 10xxxxxx - -> encodeOne_twobyte :: Word16 -> [Word8] -> encodeOne_twobyte cp = [(0xC0.|.ys), (0x80.|.xs)] -> where -> xs, ys :: Word8 -> ys = fromIntegral (shiftR cp 6) -> xs = (fromIntegral cp) .&. 0x3F - - -zzzzyyyyyyxxxxxx -> 1110zzzz 10yyyyyy 10xxxxxx - -> encodeOne_threebyte :: Word16 -> [Word8] -> encodeOne_threebyte cp = [(0xE0.|.zs), (0x80.|.ys), (0x80.|.xs)] -> where -> xs, ys, zs :: Word8 -> xs = (fromIntegral cp) .&. 0x3F -> ys = (fromIntegral (shiftR cp 6)) .&. 0x3F -> zs = fromIntegral (shiftR cp 12) - - -000uuuzzzzzzyyyyyyxxxxxx -> 11110uuu 10zzzzzz 10yyyyyy 10xxxxxx - -> encodeOne_fourbyte :: Word32 -> [Word8] -> encodeOne_fourbyte cp = [0xF0.|.us, 0x80.|.zs, 0x80.|.ys, 0x80.|.xs] -> where -> xs, ys, zs, us :: Word8 -> xs = (fromIntegral cp) .&. 0x3F -> ys = (fromIntegral (shiftR cp 6)) .&. 0x3F -> zs = (fromIntegral (shiftR cp 12)) .&. 0x3F -> us = fromIntegral (shiftR cp 18) - - - -///- Decoding -/// - -The decoding is a bit more involved. The byte sequence could contain all -sorts of corruptions. The user must be able to either notice or ignore these -errors. - -I will first look at the decoding of a single character. The process -consumes a certain number of bytes from the input. It returns the -remaining input and either an error and the index of its occurance in the -byte sequence or the decoded character. - -> data Error - -The first byte in a sequence starts with either zero, two, three, or four -ones and one zero to indicate the length of the sequence. If it doesn't, -it is invalid. It is dropped and the next byte interpreted as the start -of a new sequence. - -> = InvalidFirstByte - -All bytes in the sequence except the first match the bit pattern 10xxxxxx. -If one doesn't, it is invalid. The sequence up to that point is dropped -and the "invalid" byte interpreted as the start of a new sequence. The error -includes the length of the partial sequence and the number of expected bytes. - -> | InvalidLaterByte Int -- the byte at relative index n was invalid - -If a sequence ends prematurely, it has been truncated. It dropped and -decoding stops. The error reports the actual and expected lengths of the -sequence. - -> | Truncated Int Int -- only n of m expected bytes were present - -Some sequences would represent code points which would be encoded as a -shorter sequence by a conformant encoder. Such non-shortest sequences are -considered erroneous and dropped. The error reports the actual and -expected number of bytes used. - -> | NonShortest Int Int -- n instead of m bytes were used - -Unicode code points are in the range of [0..0x10FFFF]. Any values outside -of those bounds are simply invalid. - -> | ValueOutOfBounds - -There is no such thing as "surrogate pairs" any more in UTF-8. The -corresponding code points now form illegal byte sequences. - -> | Surrogate -> deriving (Show, Eq) - - -Second, third, and fourth bytes share the common requirement to start -with the bit sequence 10. So, here's the function to check that property. - -> first_bits_not_10 :: Word8 -> Bool -> first_bits_not_10 b -> | (b.&.0xC0) /= 0x80 = True -> | otherwise = False - - -Erm, OK, the single-character decoding function's return type is a bit -longish. It is a tripel: - - - The first component contains the decoded character or an error - if the byte sequence was erroneous. - - The second component contains the number of bytes that were consumed - from the input. - - The third component contains the remaining bytes of input. - -> decodeOne :: [Word8] -> (Either Error Char, Int, [Word8]) -> decodeOne bs@(b1:rest) -> | b1 < 0x80 = decodeOne_onebyte bs -> | b1 < 0xC0 = (Left InvalidFirstByte, 1, rest) -> | b1 < 0xE0 = decodeOne_twobyte bs -> | b1 < 0xEE = decodeOne_threebyte bs -> | b1 < 0xF5 = decodeOne_fourbyte bs -> | otherwise = (Left ValueOutOfBounds, 1, rest) -> decodeOne [] = error "UTF8.decodeOne: No input" - - -0xxxxxxx -> 000000000xxxxxxx - -> decodeOne_onebyte :: [Word8] -> (Either Error Char, Int, [Word8]) -> decodeOne_onebyte (b:bs) = (Right (cpToChar b), 1, bs) -> decodeOne_onebyte[] = error "UTF8.decodeOne_onebyte: No input (can't happen)" - -> cpToChar :: Integral a => a -> Char -> cpToChar = chr . fromIntegral - - -110yyyyy 10xxxxxx -> 00000yyyyyxxxxxx - -> decodeOne_twobyte :: [Word8] -> (Either Error Char, Int, [Word8]) -> decodeOne_twobyte (_:[]) -> = (Left (Truncated 1 2), 1, []) -> decodeOne_twobyte (b1:b2:bs) -> | b1 < 0xC2 = (Left (NonShortest 2 1), 2, bs) -> | first_bits_not_10 b2 = (Left (InvalidLaterByte 1), 1, (b2:bs)) -> | otherwise = (Right (cpToChar result), 2, bs) -> where -> xs, ys, result :: Word32 -> xs = fromIntegral (b2.&.0x3F) -> ys = fromIntegral (b1.&.0x1F) -> result = shiftL ys 6 .|. xs -> decodeOne_twobyte[] = error "UTF8.decodeOne_twobyte: No input (can't happen)" - - -1110zzzz 10yyyyyy 10xxxxxx -> zzzzyyyyyyxxxxxx - -> decodeOne_threebyte :: [Word8] -> (Either Error Char, Int, [Word8]) -> decodeOne_threebyte (_:[]) = threebyte_truncated 1 -> decodeOne_threebyte (_:_:[]) = threebyte_truncated 2 -> decodeOne_threebyte bs@(b1:b2:b3:rest) -> | first_bits_not_10 b2 -> = (Left (InvalidLaterByte 1), 1, drop 1 bs) -> | first_bits_not_10 b3 -> = (Left (InvalidLaterByte 2), 2, drop 2 bs) -> | result < 0x0080 -> = (Left (NonShortest 3 1), 3, rest) -> | result < 0x0800 -> = (Left (NonShortest 3 2), 3, rest) -> | result >= 0xD800 && result < 0xE000 -> = (Left Surrogate, 3, rest) -> | otherwise -> = (Right (cpToChar result), 3, rest) -> where -> xs, ys, zs, result :: Word32 -> xs = fromIntegral (b3.&.0x3F) -> ys = fromIntegral (b2.&.0x3F) -> zs = fromIntegral (b1.&.0x0F) -> result = shiftL zs 12 .|. shiftL ys 6 .|. xs -> decodeOne_threebyte[] -> = error "UTF8.decodeOne_threebyte: No input (can't happen)" - -> threebyte_truncated :: Int -> (Either Error Char, Int, [Word8]) -> threebyte_truncated n = (Left (Truncated n 3), n, []) - - -11110uuu 10zzzzzz 10yyyyyy 10xxxxxx -> 000uuuzzzzzzyyyyyyxxxxxx - -> decodeOne_fourbyte :: [Word8] -> (Either Error Char, Int, [Word8]) -> decodeOne_fourbyte (_:[]) = fourbyte_truncated 1 -> decodeOne_fourbyte (_:_:[]) = fourbyte_truncated 2 -> decodeOne_fourbyte (_:_:_:[]) = fourbyte_truncated 3 -> decodeOne_fourbyte bs@(b1:b2:b3:b4:rest) -> | first_bits_not_10 b2 -> = (Left (InvalidLaterByte 1), 1, drop 1 bs) -> | first_bits_not_10 b3 -> = (Left (InvalidLaterByte 2), 2, drop 2 bs) -> | first_bits_not_10 b4 -> = (Left (InvalidLaterByte 3), 3, drop 3 bs) -> | result < 0x0080 -> = (Left (NonShortest 4 1), 4, rest) -> | result < 0x0800 -> = (Left (NonShortest 4 2), 4, rest) -> | result < 0x10000 -> = (Left (NonShortest 4 3), 4, rest) -> | result > 0x10FFFF -> = (Left ValueOutOfBounds, 4, rest) -> | otherwise -> = (Right (cpToChar result), 4, rest) -> where -> xs, ys, zs, us, result :: Word32 -> xs = fromIntegral (b4 .&. 0x3F) -> ys = fromIntegral (b3 .&. 0x3F) -> zs = fromIntegral (b2 .&. 0x3F) -> us = fromIntegral (b1 .&. 0x07) -> result = xs .|. shiftL ys 6 .|. shiftL zs 12 .|. shiftL us 18 -> decodeOne_fourbyte[] -> = error "UTF8.decodeOne_fourbyte: No input (can't happen)" - -> fourbyte_truncated :: Int -> (Either Error Char, Int, [Word8]) -> fourbyte_truncated n = (Left (Truncated n 4), n, []) - - -The decoder examines all input, recording decoded characters as well as -error-index pairs along the way. - -> decode :: [Word8] -> ([Char], [(Error,Int)]) -> decode bytes = iter 0 [] [] bytes -> where -> iter :: Int -> [Char] -> [(Error,Int)] -> [Word8] -> -> ([Char], [(Error,Int)]) -> iter _ cs es [] = (reverse cs, reverse es) -> iter idx cs es bs -> = case decodeOne bs of -> (Left e, n, rest) -> iter (idx+n) cs ((e,idx):es) rest -> (Right c, n, rest) -> iter (idx+n) (c:cs) es rest - rmfile ./Graphics/PDF/UTF8.lhs hunk ./HPDF.cabal 5 -Copyright: Copyright (c) 2007, alpha +Copyright: Copyright (c) 2007, alpheccar hunk ./HPDF.cabal 10 -exposed-Modules: - Graphics.PDF, - Graphics.PDF.Colors, - Graphics.PDF.Coordinates, - Graphics.PDF.Document, - Graphics.PDF.Draw, - Graphics.PDF.LowLevel, - Graphics.PDF.Pages, - Graphics.PDF.Shapes, - Graphics.PDF.UTF8 -build-depends: base, haskell98,mtl -extensions: CPP +build-depends: base, haskell98,mtl,encoding hunk ./HPDF.cabal 12 - +extensions: CPP +exposed-Modules: + Graphics.PDF + Graphics.PDF.Colors + Graphics.PDF.Coordinates + Graphics.PDF.Document + Graphics.PDF.Shapes +Other-Modules: + Graphics.PDF.LowLevel + Graphics.PDF.Data.PDFTree + Graphics.PDF.Pages + Graphics.PDF.Draw hunk ./Test/Makefile 8 +standard: + ghc -o test --make test.hs + hunk ./Test/Penrose.hs 114 - runPdf ("penrose_" ++ (head nb) ++ ".pdf") rect $ \page -> do + runPdf ("penrose_" ++ (head nb) ++ ".pdf") standardDocInfo rect $ \page -> do hunk ./Test/test.hs 29 - runPdf "test.pdf" rect $ \page -> do + runPdf "test.pdf" (standardDocInfo {author=Just . toPDFString $ "alpheccar (éèçà)"}) rect $ \page -> do hunk ./Graphics/PDF/Document.hs 17 + , addPageWithTransition hunk ./Graphics/PDF/Document.hs 20 + -- ** Page transitions + , PDFTransition(..) + , PDFTransStyle(..) + , PDFTransDirection(..) + , PDFTransDimension(..) + , PDFTransDirection2(..) hunk ./Graphics/PDF/Document.hs 63 - +-- Create a new empty page +createANewPage :: Maybe PDFRect -- ^ Page size or default document's one + -> PDF (Int,PDFPage) -- ^ Reference to the new page +createANewPage rect' = do + rect <- maybe (gets defaultRect) return rect' + -- Get the root page reference + -- Create a new empty content for the page + pageContent <- createContent initColorSpace + -- Create a new page having as parent the root page + let page = PDFPage Nothing rect pageContent Nothing Nothing Nothing + -- Create a new page reference + pageref <-supply + return (pageref , page) + hunk ./Graphics/PDF/Document.hs 81 - rect <- maybe (gets defaultRect) return rect' - -- Get the root page reference - -- Create a new empty content for the page - pageContent <- createContent initColorSpace - -- Create a new page having as parent the root page - let page = PDFPage Nothing rect pageContent Nothing - -- Create a new page reference - pageref <-supply - -- Save the page since we may want to draw on it + (pageref,page) <- createANewPage rect' hunk ./Graphics/PDF/Document.hs 84 + +addPageWithTransition :: Maybe PDFRect -- ^ Page size or default document's one + -> Maybe PDFFloat -- ^ Optional duration + -> Maybe PDFTransition -- ^ Optional transition + -> PDF (PDFReference PDFPage) -- ^ Reference to the new page +addPageWithTransition rect' dur t = do + (pageref,PDFPage a b c d _ _) <- createANewPage rect' + modify $ \s -> s {pages = recordPage (PDFReference pageref) (PDFPage a b c d dur t) (pages s)} + return (PDFReference pageref) hunk ./Graphics/PDF/Document.hs 108 - Just(PDFPage _ _ (PDFReference streamRef) _) -> do + Just(PDFPage _ _ (PDFReference streamRef) _ _ _) -> do hunk ./Graphics/PDF/Pages.hs 24 + , Pages hunk ./Graphics/PDF/Pages.hs 30 + -- ** Page transitions + , PDFTransition(..) + , PDFTransStyle(..) + , PDFTransDirection(..) + , PDFTransDimension(..) + , PDFTransDirection2(..) hunk ./Graphics/PDF/Pages.hs 105 + !(Maybe PDFFloat) -- ^ Optional uration + !(Maybe PDFTransition) -- ^ Optional transition hunk ./Graphics/PDF/Pages.hs 133 +-- | A PDF Transition +data PDFTransition = PDFTransition !PDFFloat !PDFTransStyle deriving(Eq) hunk ./Graphics/PDF/Pages.hs 136 +-- | Dimension of a transition +data PDFTransDimension = Horizontal | Vertical deriving(Eq) + +instance Show PDFTransDimension where + show Horizontal = "H" + show Vertical = "V" + +-- | Direction of a transition +data PDFTransDirection = Inward | Outward deriving(Eq) + +instance Show PDFTransDirection where + show Inward = "I" + show Outward = "O" + +-- | Direction of a transition +data PDFTransDirection2 = LeftToRight + | BottomToTop -- ^ Wipe only + | RightToLeft -- ^ Wipe only + | TopToBottom + | TopLeftToBottomRight -- ^ Glitter only + deriving(Eq) + +floatDirection :: PDFTransDirection2 -> PDFFloat +floatDirection LeftToRight = 0 +floatDirection BottomToTop = 90 +floatDirection RightToLeft = 180 +floatDirection TopToBottom = 270 +floatDirection TopLeftToBottomRight = 315 + +-- | Transition style +data PDFTransStyle = Split PDFTransDimension PDFTransDirection + | Blinds PDFTransDimension + | Box PDFTransDirection + | Wipe PDFTransDirection2 + | Dissolve + | Glitter PDFTransDirection2 + deriving(Eq) + +instance Show PDFTransStyle where + show (Split _ _) = "Split" + show (Blinds _) = "Blinds" + show (Box _) = "Box" + show (Wipe _) = "Wipe" + show (Dissolve) = "Dissolve" + show (Glitter _) = "Glitter" + +instance PdfObject PDFTransition where + toPDF (PDFTransition d t) = toPDF $ PDFDictionary. M.fromList $ + [ (PDFName "Type",AnyPdfObject (PDFName "Trans")) + , (PDFName "S",AnyPdfObject (PDFName (show t))) + , (PDFName "D",AnyPdfObject d) + ] ++ optionalDm t ++ optionalM t ++ optionalDi t + where + optionalDm (Split a _) = [ (PDFName "Dm",AnyPdfObject (PDFName (show a)))] + optionalDm (Blinds a) = [ (PDFName "Dm",AnyPdfObject (PDFName (show a)))] + optionalDm _ = [] + optionalM (Split _ a) = [ (PDFName "M",AnyPdfObject (PDFName (show a)))] + optionalM (Box a) = [ (PDFName "M",AnyPdfObject (PDFName (show a)))] + optionalM _ = [] + optionalDi (Wipe a) = [ (PDFName "Di",AnyPdfObject (floatDirection a))] + optionalDi (Glitter a) = [ (PDFName "Di",AnyPdfObject (floatDirection a))] + optionalDi _ = [] + hunk ./Graphics/PDF/Pages.hs 206 - ] + ] hunk ./Graphics/PDF/Pages.hs 212 - ] - + ] hunk ./Graphics/PDF/Pages.hs 216 - toPDF (PDFPage (Just parent) box content rsrc) = toPDF $ PDFDictionary. M.fromList $ + toPDF (PDFPage (Just parent) box content rsrc d t) = toPDF $ PDFDictionary. M.fromList $ hunk ./Graphics/PDF/Pages.hs 226 - ] - toPDF (PDFPage Nothing _ _ _) = noPdfObject + ] ++ (maybe [] (\x -> [(PDFName "Dur",AnyPdfObject x)]) d) + ++ (maybe [] (\x -> [(PDFName "Trans",AnyPdfObject x)]) t) + toPDF (PDFPage Nothing _ _ _ _ _) = noPdfObject hunk ./Graphics/PDF/Pages.hs 294 -leafPage (Just ref) (PDFReference objectnb) (PDFPage _ a b c) = do - modify $ \s -> s {objects = IM.insert objectnb (AnyPdfObject . PDFPage (Just ref) a b $ c) (objects s) } +leafPage (Just ref) (PDFReference objectnb) (PDFPage _ a b c d e) = do + modify $ \s -> s {objects = IM.insert objectnb (AnyPdfObject $ PDFPage (Just ref) a b c d e) (objects s) } hunk ./Graphics/PDF/Pages.hs 298 -leafPage Nothing p@(PDFReference objectnb) (PDFPage _ a b c) = do +leafPage Nothing p@(PDFReference objectnb) (PDFPage _ a b c d e) = do hunk ./Graphics/PDF/Pages.hs 303 - modify $ \s -> s {objects = IM.insert objectnb (AnyPdfObject . PDFPage (Just pRef) a b $ c) (objects s) } + modify $ \s -> s {objects = IM.insert objectnb (AnyPdfObject $ PDFPage (Just pRef) a b c d e) (objects s) } hunk ./Graphics/PDF.hs 3 --- Copyright : (c) alpha 2007 +-- Copyright : (c) alpheccar 2007 hunk ./Graphics/PDF.hs 10 --- PDF API for Haskell +-- Generation of PDF documents hunk ./Graphics/PDF.hs 21 + , PDFReference + , PDFString + , PDFPage + , Pages hunk ./Graphics/PDF.hs 61 -createPDF :: PDF (PDFReference PDFPage) +createPDF :: PDF () hunk ./Graphics/PDF.hs 67 - -- Reserve an identifier for the root page object - addPage Nothing + return () hunk ./Graphics/PDF.hs 125 - -> ((PDFReference PDFPage) -> PDF a) -- ^ PDF action using the first page of the document as starting point + -> PDF a -- ^ PDF action hunk ./Graphics/PDF.hs 128 - (root,s) <- flip runStateT vars . unPDF $ createPDF >>= m >> saveObjects + (root,s) <- flip runStateT vars . unPDF $ createPDF >> m >> saveObjects hunk ./HPDF.cabal 7 -synopsis: PDF API for Haskell +synopsis: Generation of PDF documents hunk ./Test/Penrose.hs 114 - runPdf ("penrose_" ++ (head nb) ++ ".pdf") standardDocInfo rect $ \page -> do + runPdf ("penrose_" ++ (head nb) ++ ".pdf") standardDocInfo rect $ do + page <- addPage Nothing hunk ./Test/test.hs 29 - runPdf "test.pdf" (standardDocInfo {author=Just . toPDFString $ "alpheccar (éèçà)"}) rect $ \page -> do + runPdf "test.pdf" (standardDocInfo {author=Just . toPDFString $ "alpheccar (éèçà)"}) rect $ do + page <- addPageWithTransition Nothing (Just 3.0) (Just (PDFTransition 1.0 Dissolve)) hunk ./Test/test.hs 40 - mapM_ (const $ addPage Nothing) [1..10] + mapM_ (const $ addPageWithTransition Nothing (Just 3) (Just (PDFTransition 1.0 Dissolve))) [1..10] hunk ./Graphics/PDF/Document.hs 32 + , PDFDocumentPageMode(..) + , PDFDocumentPageLayout(..) + , PDFViewerPreferences(..) hunk ./Graphics/PDF/Document.hs 36 + , standardViewerPrefs hunk ./Graphics/PDF/Document.hs 48 - author :: Maybe PDFString - , subject :: Maybe PDFString + author :: PDFString + , subject :: PDFString + , pageMode :: PDFDocumentPageMode + , pageLayout :: PDFDocumentPageLayout + , viewerPreferences :: PDFViewerPreferences hunk ./Graphics/PDF/Document.hs 54 + + hunk ./Graphics/PDF/Document.hs 59 -standardDocInfo = PDFDocumentInfo Nothing Nothing +standardDocInfo = PDFDocumentInfo (toPDFString "") (toPDFString "") UseNone SinglePage standardViewerPrefs hunk ./Graphics/PDF/LowLevel.hs 59 - +instance PdfObject Bool where + toPDF (True) = toByteString "true" + toPDF (False) = toByteString "false" hunk ./Graphics/PDF/Pages.hs 25 + , PDFDocumentPageMode(..) + , PDFDocumentPageLayout(..) + , PDFViewerPreferences(..) + -- ** Document management + , standardViewerPrefs hunk ./Graphics/PDF/Pages.hs 84 +-- | Document page mode +data PDFDocumentPageMode = UseNone + | UseOutlines + | UseThumbs + | FullScreen + deriving(Eq,Show) hunk ./Graphics/PDF/Pages.hs 91 +-- | Document page layout +data PDFDocumentPageLayout = SinglePage + | OneColumn + | TwoColumnLeft + | TwoColumnRight + | TwoPageLeft + | TwoPageRight + deriving(Eq,Show) + +data PDFViewerPreferences = PDFViewerPreferences { hideToolbar :: Bool + , hideMenuBar :: Bool + , hideWindowUI :: Bool + , fitWindow :: Bool + , centerWindow :: Bool + , displayDoctitle :: Bool + , nonFullScreenPageMode :: PDFDocumentPageMode + } + +instance PdfObject PDFViewerPreferences where + toPDF (PDFViewerPreferences ht hm hwui fw cw ddt nfspm ) = toPDF $ PDFDictionary. M.fromList $ + [ (PDFName "HideToolbar",AnyPdfObject ht) + , (PDFName "HideMenubar",AnyPdfObject hm) + , (PDFName "HideWindowUI",AnyPdfObject hwui) + , (PDFName "FitWindow",AnyPdfObject fw) + , (PDFName "CenterWindow",AnyPdfObject cw) + , (PDFName "DisplayDocTitle",AnyPdfObject ddt) + , (PDFName "NonFullScreenPageMode",AnyPdfObject . PDFName . show $ nfspm) + ] + +standardViewerPrefs :: PDFViewerPreferences +standardViewerPrefs = PDFViewerPreferences False False False False False False UseNone hunk ./Graphics/PDF/Pages.hs 127 + !PDFDocumentPageMode + !PDFDocumentPageLayout + !PDFViewerPreferences hunk ./Graphics/PDF/Pages.hs 287 - toPDF (PDFCatalog outlines lPages) = toPDF $ PDFDictionary . M.fromList $ + toPDF (PDFCatalog outlines lPages pageMode pageLayout viewerPrefs) = toPDF $ PDFDictionary . M.fromList $ hunk ./Graphics/PDF/Pages.hs 291 + , (PDFName "PageMode", AnyPdfObject . PDFName . show $ pageMode) + , (PDFName "PageLayout", AnyPdfObject . PDFName . show $ pageLayout) + , (PDFName "ViewerPreferences", AnyPdfObject viewerPrefs) hunk ./Graphics/PDF.hs 47 -import Data.Maybe hunk ./Graphics/PDF.hs 69 -saveObjects :: PDF (PDFReference PDFCatalog) -saveObjects = do +saveObjects :: PDFDocumentInfo -> PDF (PDFReference PDFCatalog) +saveObjects infos = do hunk ./Graphics/PDF.hs 76 - cat <- addObject $ PDFCatalog outlines pRef + cat <- addObject $ PDFCatalog outlines pRef (pageMode infos) (pageLayout infos) (viewerPreferences infos) hunk ./Graphics/PDF.hs 114 - getField (_,Nothing) = [] - getField (name,Just r) = [(name,AnyPdfObject r)] - allInfos = concat . map (getField) $ [ (PDFName "Author",author infos) - , (PDFName "Subject",subject infos) - ] + allInfos = [ (PDFName "Author",AnyPdfObject . author $ infos) + , (PDFName "Subject",AnyPdfObject . subject $ infos) + ] hunk ./Graphics/PDF.hs 125 - (root,s) <- flip runStateT vars . unPDF $ createPDF >> m >> saveObjects + (root,s) <- flip runStateT vars . unPDF $ createPDF >> m >> saveObjects docInfo hunk ./Test/test.hs 29 - runPdf "test.pdf" (standardDocInfo {author=Just . toPDFString $ "alpheccar (éèçà)"}) rect $ do + runPdf "test.pdf" (standardDocInfo { author=toPDFString $ "alpheccar (éèçà)" + , pageMode = FullScreen + , viewerPreferences = standardViewerPrefs { + hideToolbar = True + } + }) rect $ do hunk ./Graphics/PDF/Document.hs 46 --- | Document metadata -data PDFDocumentInfo = PDFDocumentInfo { - author :: PDFString - , subject :: PDFString - , pageMode :: PDFDocumentPageMode - , pageLayout :: PDFDocumentPageLayout - , viewerPreferences :: PDFViewerPreferences - } - hunk ./Graphics/PDF/Document.hs 50 -standardDocInfo = PDFDocumentInfo (toPDFString "") (toPDFString "") UseNone SinglePage standardViewerPrefs +standardDocInfo = PDFDocumentInfo (toPDFString "") (toPDFString "") UseNone SinglePage standardViewerPrefs True hunk ./Graphics/PDF/Document.hs 55 -createContent (Draw a _) = do +createContent d = do hunk ./Graphics/PDF/Document.hs 57 - let ns = PDFStream (Draw a ()) hunk ./Graphics/PDF/Document.hs 59 - modify $ \s -> s {streams = IM.insert streamref ns (streams s)} + modify $ \s -> s {streams = IM.insert streamref (d >> return ()) (streams s)} hunk ./Graphics/PDF/Document.hs 112 - Just (PDFStream c) -> do + Just c -> do hunk ./Graphics/PDF/Document.hs 114 - modify $ \s -> s {streams = IM.insert streamRef (PDFStream $ c >> draw >> return ()) lStreams} + modify $ \s -> s {streams = IM.insert streamRef (c >> draw >> return ()) lStreams} hunk ./Graphics/PDF/Draw.hs 24 +import Control.Monad.RWS hunk ./Graphics/PDF/Draw.hs 26 +import Control.Monad.Reader +import Control.Monad.State hunk ./Graphics/PDF/Draw.hs 31 -data Draw a = Draw !B.ByteString !a +--data Draw a = Draw !B.ByteString !a +newtype Draw a = Draw {unDraw :: RWS Bool B.ByteString Bool a} + deriving(Monad,MonadWriter B.ByteString, MonadReader Bool, MonadState Bool, Functor) hunk ./Graphics/PDF/Draw.hs 36 -data PDFStream = PDFStream !(Draw ()) - -instance PdfObject (Draw a) where - toPDF (Draw a _) = B.concat [ toByteString "\nstream" - , newline - , a - , newline - , toByteString "endstream"] - +data PDFStream = PDFStream !B.ByteString !Bool !(PDFReference PDFLength) + hunk ./Graphics/PDF/Draw.hs 39 - toPDF (PDFStream s@(Draw sc _)) = B.append (toPDF . PDFDictionary. M.fromList $ [ (PDFName "Length",AnyPdfObject (PDFLength r))]) (toPDF s) - where - r = (B.length sc) + 1 + toPDF (PDFStream s c l) = + B.concat $ [ (toPDF . PDFDictionary. M.fromList $ [ (PDFName "Length",AnyPdfObject l)] ++ compressedStream c) + , toByteString "\nstream" + , newline + , s + , newline + , toByteString "endstream"] + where + compressedStream False = [] + compressedStream True = [(PDFName "Filter",AnyPdfObject $ [AnyPdfObject . PDFName $ "FlateDecode"])] + hunk ./Graphics/PDF/Draw.hs 53 -emptyDrawing = Draw B.empty () - - -instance Functor Draw where - fmap f (Draw stream v) = Draw stream (f v) +emptyDrawing = return () hunk ./Graphics/PDF/Draw.hs 55 -instance Monad Draw where - return a = Draw B.empty a - (Draw stream v) >>= f = let Draw stream' v' = f v in - Draw (B.append stream stream') v' - -instance MonadWriter B.ByteString Draw where - tell w = Draw w () - listen (Draw stream v) = Draw stream (v,stream) - pass (Draw stream (v,f)) = Draw (f stream) v hunk ./Graphics/PDF/LowLevel.hs 42 -newtype PDFLength = PDFLength Int64 deriving(Eq,Show,Ord,Num) +data PDFLength = PDFLength Int64 deriving(Eq,Show,Ord) + +instance Num PDFLength where + (+) (PDFLength a) (PDFLength b) = PDFLength (a+b) + (*) (PDFLength a) (PDFLength b) = PDFLength (a*b) + negate (PDFLength a) = PDFLength (negate a) + abs (PDFLength a) = PDFLength (abs a) + signum (PDFLength a) = PDFLength (signum a) + fromInteger a = PDFLength (fromInteger a) hunk ./Graphics/PDF/Pages.hs 28 + , PDFDocumentInfo(..) hunk ./Graphics/PDF/Pages.hs 85 + -- | Document metadata +data PDFDocumentInfo = PDFDocumentInfo { + author :: PDFString + , subject :: PDFString + , pageMode :: PDFDocumentPageMode + , pageLayout :: PDFDocumentPageLayout + , viewerPreferences :: PDFViewerPreferences + , compressed :: Bool + } + + hunk ./Graphics/PDF/Pages.hs 150 - , streams :: !(IM.IntMap (PDFStream)) -- ^ PDF Streams + , streams :: !(IM.IntMap (Draw ())) -- ^ Draw commands hunk ./Graphics/PDF/Pages.hs 153 + , docInfo :: !PDFDocumentInfo -- ^ Document infos hunk ./Graphics/PDF/Pages.hs 300 - toPDF (PDFCatalog outlines lPages pageMode pageLayout viewerPrefs) = toPDF $ PDFDictionary . M.fromList $ + toPDF (PDFCatalog outlines lPages pgMode pgLayout viewerPrefs) = toPDF $ PDFDictionary . M.fromList $ hunk ./Graphics/PDF/Pages.hs 304 - , (PDFName "PageMode", AnyPdfObject . PDFName . show $ pageMode) - , (PDFName "PageLayout", AnyPdfObject . PDFName . show $ pageLayout) + , (PDFName "PageMode", AnyPdfObject . PDFName . show $ pgMode) + , (PDFName "PageLayout", AnyPdfObject . PDFName . show $ pgLayout) hunk ./Graphics/PDF.hs 39 - +import Control.Monad.RWS hunk ./Graphics/PDF.hs 56 - +import Codec.Compression.Zlib hunk ./Graphics/PDF.hs 68 + +-- Create the PDF stream objects from the draw monads +createStreams :: [(Int,Draw ())] -> PDF () +createStreams l = mapM_ addStream l + where + addStream (k,d) = do + let (_,_,w') = (runRWS . unDraw $ d) False False + r <- supply + let ref = PDFReference r :: PDFReference PDFLength + infos <- gets docInfo + if compressed infos + then do + let w'' = compress w' + updateObject (PDFReference k :: PDFReference PDFStream) (PDFStream w'' True ref) + updateObject ref (PDFLength ((B.length w'') + 1)) + else do + updateObject (PDFReference k :: PDFReference PDFStream) (PDFStream w' False ref) + updateObject ref (PDFLength ((B.length w') + 1)) + hunk ./Graphics/PDF.hs 88 -saveObjects :: PDFDocumentInfo -> PDF (PDFReference PDFCatalog) -saveObjects infos = do +saveObjects :: PDF (PDFReference PDFCatalog) +saveObjects = do + infos <- gets docInfo hunk ./Graphics/PDF.hs 97 - modify $ \s -> s {catalog = cat , objects = IM.foldWithKey insertObject (objects s) (streams s) } + modify $ \s -> s {catalog = cat} + s <- gets streams + createStreams . IM.toList $ s hunk ./Graphics/PDF.hs 101 - where - insertObject objectnb object objdict = IM.insert objectnb (AnyPdfObject object) objdict - hunk ./Graphics/PDF.hs 143 -runPdf filename docInfo rect m = do - (root,s) <- flip runStateT vars . unPDF $ createPDF >> m >> saveObjects docInfo +runPdf filename infos rect m = do + (root,s) <- flip runStateT vars . unPDF $ createPDF >> m >> saveObjects hunk ./Graphics/PDF.hs 154 - B.hPut h . toPDF $ PDFTrailer nb root docInfo + B.hPut h . toPDF $ PDFTrailer nb root infos hunk ./Graphics/PDF.hs 167 + , docInfo = infos hunk ./HPDF.cabal 10 -build-depends: base, haskell98,mtl,encoding +build-depends: base, haskell98,mtl,encoding,zlib hunk ./Test/Penrose.hs 114 - runPdf ("penrose_" ++ (head nb) ++ ".pdf") standardDocInfo rect $ do + runPdf ("penrose_" ++ (head nb) ++ ".pdf") (standardDocInfo {compressed=True}) rect $ do hunk ./Test/test.hs 31 + , compressed = True hunk ./Graphics/PDF.hs 39 -import Control.Monad.RWS hunk ./Graphics/PDF.hs 62 - proc <- addObject PDFProc + --proc <- addObject PDFProc hunk ./Graphics/PDF.hs 64 - addObject $ PDFResource proc + --addObject $ PDFResource proc hunk ./Graphics/PDF.hs 69 -createStreams :: [(Int,Draw ())] -> PDF () +createStreams :: [(Int, (Maybe (PDFReference PDFPage),Draw ()))] -> PDF () hunk ./Graphics/PDF.hs 72 - addStream (k,d) = do - let (_,_,w') = (runRWS . unDraw $ d) False False + addStream (k,(p,d)) = do hunk ./Graphics/PDF.hs 74 - let ref = PDFReference r :: PDFReference PDFLength + let (state',w') = runDrawing d (DrawEnvironment r) + ref = PDFReference r :: PDFReference PDFLength + -- If the stream is linked to a page we add the stream resources to the page + case p of + Nothing -> return () + Just pageRef -> do + rsrcRef <- addObject (rsrc state') + setPageResource rsrcRef pageRef hunk ./Graphics/PDF.hs 95 + s <- gets streams + createStreams . IM.toList $ s hunk ./Graphics/PDF.hs 105 - s <- gets streams - createStreams . IM.toList $ s hunk ./Graphics/PDF/Colors.hs 17 - , initColorSpace + , setRGBColorSpace hunk ./Graphics/PDF/Colors.hs 20 + , setAlpha hunk ./Graphics/PDF/Colors.hs 24 +import Graphics.PDF.LowLevel +import Graphics.PDF.Resources +import qualified Data.Map as M +import Control.Monad.State(gets) hunk ./Graphics/PDF/Colors.hs 31 - + | Hsv !Double !Double !Double + +-- | Set alpha value for transparency +setAlpha :: Double -> Draw () +setAlpha alpha = do + alphaMap <- gets alphas + case M.lookup alpha alphaMap of + Nothing -> do + newName <- supplyName + let alphaState = ExtGState . PDFDictionary . M.fromList $ [ (PDFName "CA", AnyPdfObject . PDFFloat $ alpha) + , (PDFName "ca", AnyPdfObject . PDFFloat $ alpha) + ] + modifyStrict $ \s -> s {rsrc = addGState (PDFName newName) alphaState (rsrc s), alphas = M.insert alpha newName (alphas s)} + writeCmd ("\n/" ++ newName ++ " gs") + Just n -> writeCmd ("\n/" ++ n ++ " gs") + hunk ./Graphics/PDF/Colors.hs 48 -initColorSpace :: Draw () -initColorSpace = writeCmd "\n/DeviceRGB CS\n/DeviceRGB cs\n" +setRGBColorSpace :: Draw () +setRGBColorSpace = writeCmd "\n/DeviceRGB CS\n/DeviceRGB cs\n" + + +hsvToRgb :: (Double,Double,Double) -> (Double,Double,Double) +hsvToRgb (h,s,v) = + let hi = fromIntegral (floor (h / 60) `mod` 6 :: Int) :: Double + f = h/60 - hi + p = v * (1-s) + q = v * (1 - f*s) + t = v * (1 - (1-f)*s) in + case hi of + 0 -> (v,t,p) + 1 -> (q,v,p) + 2 -> (p,v,t) + 3 -> (p,q,v) + 4 -> (t,p,v) + 5 -> (v,p,q) + _ -> error "Hue value incorrect" hunk ./Graphics/PDF/Colors.hs 71 -fillColor (Rgb r g b) = writeCmd $ "\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " sc" +fillColor (Rgb r g b) = do + writeCmd $ "\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " rg" +fillColor (Hsv h s v) = do + let (r,g,b) = hsvToRgb (h,s,v) + writeCmd $ "\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " rg" hunk ./Graphics/PDF/Colors.hs 80 -strokeColor (Rgb r g b) = writeCmd $ "\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " SC" +strokeColor (Rgb r g b) = do + writeCmd $ "\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " RG" +strokeColor (Hsv h s v) = do + let (r,g,b) = hsvToRgb (h,s,v) + writeCmd $ "\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " RG" hunk ./Graphics/PDF/Document.hs 20 + , setPageResource hunk ./Graphics/PDF/Document.hs 44 -import Graphics.PDF.Colors hunk ./Graphics/PDF/Document.hs 45 - +import Graphics.PDF.Resources hunk ./Graphics/PDF/Document.hs 59 - modify $ \s -> s {streams = IM.insert streamref (d >> return ()) (streams s)} + modifyStrict $ \s -> s {streams = IM.insert streamref (Nothing,d >> return ()) (streams s)} hunk ./Graphics/PDF/Document.hs 69 - pageContent <- createContent initColorSpace + pageContent <- createContent (return ()) hunk ./Graphics/PDF/Document.hs 73 - pageref <-supply + pageref <- supply hunk ./Graphics/PDF/Document.hs 81 - modify $ \s -> s {pages = recordPage (PDFReference pageref) page (pages s)} + modifyStrict $ \s -> s {pages = recordPage (PDFReference pageref) page (pages s)} hunk ./Graphics/PDF/Document.hs 90 - modify $ \s -> s {pages = recordPage (PDFReference pageref) (PDFPage a b c d dur t) (pages s)} + modifyStrict $ \s -> s {pages = recordPage (PDFReference pageref) (PDFPage a b c d dur t) (pages s)} hunk ./Graphics/PDF/Document.hs 93 +-- | Set page resource +setPageResource :: PDFReference PDFResource -> PDFReference PDFPage -> PDF () +setPageResource newr page = do + -- Get the page dictionary + lPages <- gets pages + -- Look for the page + let thePage = findPage page lPages + case thePage of + Nothing -> return () + -- If the page is found, get its stream reference and look for the stream + Just (PDFPage a b c oldr e f) -> modifyStrict $ \s -> s {pages = recordPage page (PDFPage a b c (Just newr) e f) lPages} + hunk ./Graphics/PDF/Document.hs 124 - Just c -> do + Just (_,c) -> do hunk ./Graphics/PDF/Document.hs 126 - modify $ \s -> s {streams = IM.insert streamRef (c >> draw >> return ()) lStreams} + modifyStrict $ \s -> s {streams = IM.insert streamRef (Just page,c >> draw >> return ()) lStreams} hunk ./Graphics/PDF/Draw.hs 17 - , writeCmd hunk ./Graphics/PDF/Draw.hs 18 + , DrawState(..) + , DrawEnvironment(..) + , supplyName hunk ./Graphics/PDF/Draw.hs 22 + , writeCmd + , runDrawing hunk ./Graphics/PDF/Draw.hs 33 +import Graphics.PDF.Resources hunk ./Graphics/PDF/Draw.hs 35 +data DrawState = DrawState { + supplyNames :: [String] + , rsrc :: PDFResource + , alphas :: M.Map Double String + } +data DrawEnvironment = DrawEnvironment { + streamId :: Int + } + + hunk ./Graphics/PDF/Draw.hs 47 -newtype Draw a = Draw {unDraw :: RWS Bool B.ByteString Bool a} - deriving(Monad,MonadWriter B.ByteString, MonadReader Bool, MonadState Bool, Functor) +newtype Draw a = Draw {unDraw :: RWS DrawEnvironment B.ByteString DrawState a} + deriving(Monad,MonadWriter B.ByteString, MonadReader DrawEnvironment, MonadState DrawState, Functor) hunk ./Graphics/PDF/Draw.hs 65 - --- | Am empty stream content -emptyDrawing :: Draw () +-- | An empty drawing +emptyDrawing :: Draw () hunk ./Graphics/PDF/Draw.hs 68 - - + +-- | Write a command to the drawing hunk ./Graphics/PDF/Draw.hs 72 - hunk ./Graphics/PDF/Draw.hs 73 +-- | Get a new resource name +supplyName :: Draw String +supplyName = do + (x:xs) <- gets supplyNames + modifyStrict $ \s -> s {supplyNames = xs} + return x + +-- | Execute the drawing commands to get a new state and an uncompressed PDF stream +runDrawing :: Draw () -> DrawEnvironment -> (DrawState,B.ByteString) +runDrawing drawing environment = + let state = DrawState + (map (("O" ++ (show . streamId $ environment)) ++ ) $ [replicate k ['a'..'z'] | k <- [1..]] >>= sequence) + emptyRsrc + M.empty + (_,state',w') = (runRWS . unDraw $ drawing) environment state in + (state',w') + hunk ./Graphics/PDF/LowLevel.hs 21 +import Control.Monad.State hunk ./Graphics/PDF/LowLevel.hs 163 +isEmptyDictionary :: PDFDictionary -> Bool +isEmptyDictionary (PDFDictionary d) = M.null d hunk ./Graphics/PDF/LowLevel.hs 166 +insertInPdfDict :: PDFName -> AnyPdfObject -> PDFDictionary -> PDFDictionary +insertInPdfDict key obj (PDFDictionary d) = PDFDictionary $ M.insert key obj d hunk ./Graphics/PDF/LowLevel.hs 193 +-- | Get the reference value +referenceValue :: PDFReference s -> Int +referenceValue (PDFReference i) = i hunk ./Graphics/PDF/LowLevel.hs 215 - +modifyStrict :: (MonadState s m) => (s -> s) -> m () +modifyStrict f = do + s <- get + put $! (f s) hunk ./Graphics/PDF/Pages.hs 18 - , PDFProc(..) - , PDFResource(..) hunk ./Graphics/PDF/Pages.hs 54 +import Graphics.PDF.Resources hunk ./Graphics/PDF/Pages.hs 66 - modify $ \s -> s {supplySrc = r+1} + modifyStrict $ \s -> s {supplySrc = r+1} hunk ./Graphics/PDF/Pages.hs 73 - modify $ \s -> s {objects = IM.insert r (AnyPdfObject a) (objects s)} + modifyStrict $ \s -> s {objects = IM.insert r (AnyPdfObject a) (objects s)} hunk ./Graphics/PDF/Pages.hs 82 - modify $ \s -> s {objects = IM.insert i (AnyPdfObject obj) (objects s)} + modifyStrict $ \s -> s {objects = IM.insert i (AnyPdfObject obj) (objects s)} hunk ./Graphics/PDF/Pages.hs 149 - , streams :: !(IM.IntMap (Draw ())) -- ^ Draw commands + , streams :: !(IM.IntMap ((Maybe (PDFReference PDFPage)),Draw ())) -- ^ Draw commands hunk ./Graphics/PDF/Pages.hs 162 - !(Maybe PDFFloat) -- ^ Optional uration + !(Maybe PDFFloat) -- ^ Optional duration hunk ./Graphics/PDF/Pages.hs 184 --- | A PDF Resource -data PDFResource = PDFResource !(PDFReference PDFProc) - --- | A PDFProc -data PDFProc = PDFProc - hunk ./Graphics/PDF/Pages.hs 281 -instance PdfObject PDFResource where - toPDF (PDFResource l) = toPDF . PDFDictionary . M.fromList $ [ (PDFName "ProcSet",AnyPdfObject l)] - -instance PdfObject PDFProc where - toPDF (PDFProc) = toPDF . map AnyPdfObject$ [PDFName "PDF"] hunk ./Graphics/PDF/Pages.hs 344 - modify $ \s -> s {objects = IM.insert objectnb (AnyPdfObject $ PDFPage (Just ref) a b c d e) (objects s) } + modifyStrict $ \s -> s {objects = IM.insert objectnb (AnyPdfObject $ PDFPage (Just ref) a b c d e) (objects s) } hunk ./Graphics/PDF/Pages.hs 352 - modify $ \s -> s {objects = IM.insert objectnb (AnyPdfObject $ PDFPage (Just pRef) a b c d e) (objects s) } + modifyStrict $ \s -> s {objects = IM.insert objectnb (AnyPdfObject $ PDFPage (Just pRef) a b c d e) (objects s) } addfile ./Graphics/PDF/Resources.hs hunk ./Graphics/PDF/Resources.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2006 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- PDF Resources +--------------------------------------------------------- +-- #hide +module Graphics.PDF.Resources( + PDFResource + , ExtGState(..) + , addGState + , emptyRsrc + ) where + +import Graphics.PDF.LowLevel +import qualified Data.Map as M + +-- | A PDF Resource +data PDFResource = PDFResource { + procSet :: !PDFArray + , extGState :: M.Map PDFName ExtGState + } + +emptyRsrc :: PDFResource +emptyRsrc = PDFResource [AnyPdfObject . PDFName $ "PDF"] (M.empty) + + +newtype ExtGState = ExtGState PDFDictionary + + +toDictionary :: PdfObject a => M.Map PDFName a -> PDFDictionary +toDictionary = PDFDictionary . M.map AnyPdfObject + +instance PdfObject ExtGState where + toPDF (ExtGState r) = toPDF $ insertInPdfDict (PDFName "Type") (AnyPdfObject (PDFName "ExtGState")) r + +ifNotNull :: PdfObject a => String -> M.Map PDFName a -> [(PDFName,AnyPdfObject)] +ifNotNull n d = if M.null d then [] else [(PDFName n,AnyPdfObject . toDictionary $ d)] + +instance PdfObject PDFResource where + toPDF r = toPDF . PDFDictionary . M.fromList $ + [(PDFName "ProcSet",AnyPdfObject (procSet r))] ++ + ifNotNull "ExtGState" (extGState r) + +-- | Add a new G State to the G State dictionary for the given resource +addGState :: PDFName -- ^ GState name must be unique + -> ExtGState -- ^ G State content + -> PDFResource -- ^ Old resource + -> PDFResource -- ^ New resource +addGState name newValue r = r {extGState = M.insert name newValue (extGState r) } + hunk ./Test/Penrose.hs 114 - runPdf ("penrose_" ++ (head nb) ++ ".pdf") (standardDocInfo {compressed=True}) rect $ do + runPdf ("penrose_" ++ (head nb) ++ ".pdf") (standardDocInfo {compressed=False}) rect $ do hunk ./Test/Penrose.hs 117 - initColorSpace hunk ./Test/test.hs 31 - , compressed = True + , compressed = False hunk ./Test/test.hs 38 - initColorSpace hunk ./Test/test.hs 42 - applyMatrix (translate 300 0) + applyMatrix (translate 200 20) hunk ./Test/test.hs 44 + fillColor (Rgb 1 0 0) + setAlpha 0.4 hunk ./Test/test.hs 47 + setAlpha 0.4 hunk ./Graphics/PDF/Colors.hs 20 - , setAlpha + , setStrokeAlpha + , setFillAlpha hunk ./Graphics/PDF/Colors.hs 26 -import Graphics.PDF.Resources -import qualified Data.Map as M hunk ./Graphics/PDF/Colors.hs 27 +import Graphics.PDF.Resources hunk ./Graphics/PDF/Colors.hs 32 - + + + + +-- | Set alpha value for transparency +setStrokeAlpha :: Double -> Draw () +setStrokeAlpha alpha = do + alphaMap <- gets strokeAlphas + (newName,newMap) <- setResource "ExtGState" (StrokeAlpha alpha) alphaMap + modifyStrict $ \s -> s { strokeAlphas = newMap } + writeCmd ("\n/" ++ newName ++ " gs") + hunk ./Graphics/PDF/Colors.hs 45 -setAlpha :: Double -> Draw () -setAlpha alpha = do - alphaMap <- gets alphas - case M.lookup alpha alphaMap of - Nothing -> do - newName <- supplyName - let alphaState = ExtGState . PDFDictionary . M.fromList $ [ (PDFName "CA", AnyPdfObject . PDFFloat $ alpha) - , (PDFName "ca", AnyPdfObject . PDFFloat $ alpha) - ] - modifyStrict $ \s -> s {rsrc = addGState (PDFName newName) alphaState (rsrc s), alphas = M.insert alpha newName (alphas s)} - writeCmd ("\n/" ++ newName ++ " gs") - Just n -> writeCmd ("\n/" ++ n ++ " gs") +setFillAlpha :: Double -> Draw () +setFillAlpha alpha = do + alphaMap <- gets fillAlphas + (newName,newMap) <- setResource "ExtGState" (FillAlpha alpha) alphaMap + modifyStrict $ \s -> s { fillAlphas = newMap } + writeCmd ("\n/" ++ newName ++ " gs") hunk ./Graphics/PDF/Document.hs 103 - Just (PDFPage a b c oldr e f) -> modifyStrict $ \s -> s {pages = recordPage page (PDFPage a b c (Just newr) e f) lPages} + Just (PDFPage a b c _ e f) -> modifyStrict $ \s -> s {pages = recordPage page (PDFPage a b c (Just newr) e f) lPages} hunk ./Graphics/PDF/Draw.hs 24 + , writeString + , setResource hunk ./Graphics/PDF/Draw.hs 40 - , alphas :: M.Map Double String + , strokeAlphas :: M.Map StrokeAlpha String + , fillAlphas :: M.Map FillAlpha String + , theFonts :: M.Map PDFFont String hunk ./Graphics/PDF/Draw.hs 77 +-- | Write a PDF string object to the drawing +writeString :: PDFString -> Draw () +writeString = tell . toPDF + hunk ./Graphics/PDF/Draw.hs 94 - M.empty + M.empty M.empty M.empty hunk ./Graphics/PDF/Draw.hs 106 + +-- | Set a resource in the resource dictionary +setResource :: (Ord a, PdfResourceObject a) => String -- ^ Dict name + -> a -- ^ Resource value + -> M.Map a String -- ^ Old cache value + -> Draw (String,M.Map a String) -- ^ New cache value +setResource dict values oldCache = do + case M.lookup values oldCache of + Nothing -> do + newName <- supplyName + modifyStrict $ \s -> s { rsrc = addResource (PDFName dict) (PDFName newName) (toRsrc values) (rsrc s)} + return (newName,M.insert values newName oldCache) + Just n -> return (n,oldCache) + + hunk ./Graphics/PDF/LowLevel.hs 73 -newtype PDFString = PDFString B.ByteString +newtype PDFString = PDFString B.ByteString deriving(Eq,Ord) hunk ./Graphics/PDF/LowLevel.hs 77 -toPDFString = PDFString . encodeLazy UTF16 . escapeString +toPDFString = PDFString . encodeLazy UTF8 . escapeString hunk ./Graphics/PDF/LowLevel.hs 219 + + hunk ./Graphics/PDF/Resources.hs 15 - , ExtGState(..) - , addGState + , addResource hunk ./Graphics/PDF/Resources.hs 17 + , StrokeAlpha(..) + , FillAlpha(..) + , PdfResourceObject(..) + , PDFFont(..) + , FontName(..) hunk ./Graphics/PDF/Resources.hs 27 +-- Fonts +type FontSize = Int +data FontName = Helvetica deriving(Eq,Ord) + +instance Show FontName where + show Helvetica = "Helvetica" + +data PDFFont = PDFFont FontName FontSize deriving(Eq) + +instance Ord PDFFont where + compare (PDFFont na sa) (PDFFont nb sb) = if sa == sb then compare na nb else compare sa sb + +instance PdfResourceObject PDFFont where + toRsrc (PDFFont f _) = [(PDFName "Type",AnyPdfObject . PDFName $ "Font") + , (PDFName "Subtype",AnyPdfObject . PDFName $ "Type1") + , (PDFName "BaseFont",AnyPdfObject . PDFName $ show f)] + +newtype StrokeAlpha = StrokeAlpha Double deriving(Eq,Ord) +instance PdfResourceObject StrokeAlpha where + toRsrc (StrokeAlpha a) = [(PDFName "CA",AnyPdfObject . PDFFloat $ a)] + +newtype FillAlpha = FillAlpha Double deriving(Eq,Ord) +instance PdfResourceObject FillAlpha where + toRsrc (FillAlpha a) = [(PDFName "ca",AnyPdfObject . PDFFloat $ a)] + +class PdfResourceObject a where + toRsrc :: a -> [(PDFName,AnyPdfObject)] + hunk ./Graphics/PDF/Resources.hs 58 - , extGState :: M.Map PDFName ExtGState + , resources :: M.Map PDFName PDFDictionary hunk ./Graphics/PDF/Resources.hs 60 - + + hunk ./Graphics/PDF/Resources.hs 65 - -newtype ExtGState = ExtGState PDFDictionary - - -toDictionary :: PdfObject a => M.Map PDFName a -> PDFDictionary -toDictionary = PDFDictionary . M.map AnyPdfObject - -instance PdfObject ExtGState where - toPDF (ExtGState r) = toPDF $ insertInPdfDict (PDFName "Type") (AnyPdfObject (PDFName "ExtGState")) r hunk ./Graphics/PDF/Resources.hs 66 -ifNotNull :: PdfObject a => String -> M.Map PDFName a -> [(PDFName,AnyPdfObject)] -ifNotNull n d = if M.null d then [] else [(PDFName n,AnyPdfObject . toDictionary $ d)] +getResources :: M.Map PDFName PDFDictionary -> [(PDFName,AnyPdfObject)] +getResources = M.toList . M.map AnyPdfObject hunk ./Graphics/PDF/Resources.hs 72 - ifNotNull "ExtGState" (extGState r) + getResources (resources r) hunk ./Graphics/PDF/Resources.hs 75 -addGState :: PDFName -- ^ GState name must be unique - -> ExtGState -- ^ G State content +addResource :: PDFName -- ^ GState dictionary + -> PDFName -- ^ GState name must be unique + -> [(PDFName,AnyPdfObject)] -- ^ G State content hunk ./Graphics/PDF/Resources.hs 80 -addGState name newValue r = r {extGState = M.insert name newValue (extGState r) } +addResource dict name newValue r = let addValue (Just (PDFDictionary a)) = Just . PDFDictionary $ M.insert name (AnyPdfObject . PDFDictionary . M.fromList $ newValue) a + addValue (Nothing) = Just . PDFDictionary $ M.insert name (AnyPdfObject . PDFDictionary . M.fromList $ newValue) M.empty + in + r {resources = M.alter addValue dict (resources r)} + addfile ./Graphics/PDF/Text.hs hunk ./Graphics/PDF/Text.hs 1 - +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- PDF TExt +--------------------------------------------------------- + +module Graphics.PDF.Text( + -- * Text + testText + ) where + +import Graphics.PDF.LowLevel +import Graphics.PDF.Draw +import Control.Monad.State(gets) +import Graphics.PDF.Resources + +testText :: PDFFloat + -> PDFFloat + -> Int + -> PDFString + -> Draw () +testText x y size s = do + alphaMap <- gets theFonts + (newName,newMap) <- setResource "Font" (PDFFont Helvetica 12) alphaMap + modifyStrict $ \s -> s { theFonts = newMap } + + writeCmd "\nBT" + writeCmd $ "\n/" ++ newName ++ " " ++ (show size) ++ " Tf" + writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " Td" + writeCmd $ "\n" + writeString s + writeCmd " Tj\nET" hunk ./Test/test.hs 25 +import Graphics.PDF.Text hunk ./Test/test.hs 45 + testText 200 200 12 (toPDFString "This is a test") hunk ./Test/test.hs 47 - setAlpha 0.4 + setFillAlpha 0.4 hunk ./Test/test.hs 49 - setAlpha 0.4 + setFillAlpha 0.4 hunk ./Graphics/PDF/Document.hs 15 + -- ** Special document objects + PDFXObject hunk ./Graphics/PDF/Document.hs 18 - addPage + , addPage hunk ./Graphics/PDF/Document.hs 30 - , createContent hunk ./Graphics/PDF/Document.hs 32 + , createXObject + , drawXObject hunk ./Graphics/PDF/Document.hs 49 +import qualified Data.Map as M + hunk ./Graphics/PDF/Document.hs 57 --- | Create a new PDF drawing object +drawXObject :: PDFReference PDFXObject -> Draw () +drawXObject r = do + xobjectMap <- gets xobjects + (newName,newMap) <- setResource "XObject" r xobjectMap + modifyStrict $ \s -> s { xobjects = newMap } + writeCmd ("\n/" ++ newName ++ " Do") + +-- | Create a PDF XObject +createXObject :: Int -- ^ Left + -> Int -- ^ Bottom + -> Int -- ^ Right + -> Int -- ^ Top + -> Draw a -- ^ Drawing commands + -> PDF (PDFReference PDFXObject) +createXObject xa ya xb yb d = let a' = do modifyStrict $ \s -> s {otherRsrcs = PDFDictionary. M.fromList $ + [ (PDFName "Type",AnyPdfObject . PDFName $ "XObject") + , (PDFName "Subtype",AnyPdfObject . PDFName $ "Form") + , (PDFName "FormType",AnyPdfObject . PDFInteger $ 1) + , (PDFName "Matrix",AnyPdfObject . (map (AnyPdfObject . PDFInteger)) $ [1,0,0,1,0,0]) + , (PDFName "BBox",AnyPdfObject . (map (AnyPdfObject . PDFInteger)) $ [xa,ya,xb,yb]) + ] + } + d + in do + PDFReference s <- createContent a' Nothing + return (PDFReference s) + +-- | Create a new empty content for a page hunk ./Graphics/PDF/Document.hs 86 + -> Maybe (PDFReference PDFPage) hunk ./Graphics/PDF/Document.hs 88 -createContent d = do - -- Create a new stream +createContent d page = do hunk ./Graphics/PDF/Document.hs 91 - modifyStrict $ \s -> s {streams = IM.insert streamref (Nothing,d >> return ()) (streams s)} + modifyStrict $ \s -> s {streams = IM.insert streamref (page,d >> return ()) (streams s)} hunk ./Graphics/PDF/Document.hs 93 + + hunk ./Graphics/PDF/Document.hs 102 + -- Create a new page reference + pageref <- supply hunk ./Graphics/PDF/Document.hs 105 - pageContent <- createContent (return ()) + pageContent <- createContent (return ()) (Just (PDFReference pageref :: PDFReference PDFPage)) hunk ./Graphics/PDF/Document.hs 108 - -- Create a new page reference - pageref <- supply hunk ./Graphics/PDF/Draw.hs 26 + , emptyEnvironment hunk ./Graphics/PDF/Draw.hs 44 + , xobjects :: M.Map (PDFReference PDFXObject) String + , otherRsrcs :: PDFDictionary hunk ./Graphics/PDF/Draw.hs 48 - streamId :: Int + streamId :: Int hunk ./Graphics/PDF/Draw.hs 51 +emptyEnvironment :: DrawEnvironment +emptyEnvironment = DrawEnvironment 0 hunk ./Graphics/PDF/Draw.hs 54 + + hunk ./Graphics/PDF/Draw.hs 62 -data PDFStream = PDFStream !B.ByteString !Bool !(PDFReference PDFLength) +data PDFStream = PDFStream !B.ByteString !Bool !(PDFReference PDFLength) !PDFDictionary hunk ./Graphics/PDF/Draw.hs 65 - toPDF (PDFStream s c l) = - B.concat $ [ (toPDF . PDFDictionary. M.fromList $ [ (PDFName "Length",AnyPdfObject l)] ++ compressedStream c) + toPDF (PDFStream s c l d) = + B.concat $ [ toPDF dict hunk ./Graphics/PDF/Draw.hs 75 + lenDict = PDFDictionary. M.fromList $ [ (PDFName "Length",AnyPdfObject l)] ++ compressedStream c + dict = pdfDictUnion lenDict d hunk ./Graphics/PDF/Draw.hs 100 - let state = DrawState - (map (("O" ++ (show . streamId $ environment)) ++ ) $ [replicate k ['a'..'z'] | k <- [1..]] >>= sequence) + let names = (map (("O" ++ (show . streamId $ environment)) ++ ) $ [replicate k ['a'..'z'] | k <- [1..]] >>= sequence) + state = DrawState + names hunk ./Graphics/PDF/Draw.hs 104 - M.empty M.empty M.empty - (_,state',w') = (runRWS . unDraw $ drawing) environment state in + M.empty M.empty M.empty M.empty + emptyDictionary + (_,state',w') = (runRWS . unDraw $ drawing) environment state + in hunk ./Graphics/PDF/LowLevel.hs 77 -toPDFString = PDFString . encodeLazy UTF8 . escapeString +toPDFString = PDFString . encodeLazy UTF16 . escapeString hunk ./Graphics/PDF/LowLevel.hs 220 - +pdfDictUnion :: PDFDictionary -> PDFDictionary -> PDFDictionary +pdfDictUnion (PDFDictionary a) (PDFDictionary b) = PDFDictionary $ M.union a b hunk ./Graphics/PDF/Resources.hs 22 + , resourceToDict + , PDFXObject hunk ./Graphics/PDF/Resources.hs 42 - toRsrc (PDFFont f _) = [(PDFName "Type",AnyPdfObject . PDFName $ "Font") + toRsrc (PDFFont f _) = AnyPdfObject . PDFDictionary . M.fromList $ + [(PDFName "Type",AnyPdfObject . PDFName $ "Font") hunk ./Graphics/PDF/Resources.hs 49 - toRsrc (StrokeAlpha a) = [(PDFName "CA",AnyPdfObject . PDFFloat $ a)] + toRsrc (StrokeAlpha a) = AnyPdfObject . PDFDictionary . M.fromList $ [(PDFName "CA",AnyPdfObject . PDFFloat $ a)] hunk ./Graphics/PDF/Resources.hs 53 - toRsrc (FillAlpha a) = [(PDFName "ca",AnyPdfObject . PDFFloat $ a)] + toRsrc (FillAlpha a) = AnyPdfObject . PDFDictionary . M.fromList $ [(PDFName "ca",AnyPdfObject . PDFFloat $ a)] hunk ./Graphics/PDF/Resources.hs 56 - toRsrc :: a -> [(PDFName,AnyPdfObject)] + toRsrc :: a -> AnyPdfObject hunk ./Graphics/PDF/Resources.hs 58 +instance PdfResourceObject (PDFReference PDFXObject) where + toRsrc = AnyPdfObject + hunk ./Graphics/PDF/Resources.hs 76 - toPDF r = toPDF . PDFDictionary . M.fromList $ - [(PDFName "ProcSet",AnyPdfObject (procSet r))] ++ - getResources (resources r) + toPDF r = toPDF . resourceToDict $ r hunk ./Graphics/PDF/Resources.hs 81 - -> [(PDFName,AnyPdfObject)] -- ^ G State content + -> AnyPdfObject -- ^ G State content hunk ./Graphics/PDF/Resources.hs 84 -addResource dict name newValue r = let addValue (Just (PDFDictionary a)) = Just . PDFDictionary $ M.insert name (AnyPdfObject . PDFDictionary . M.fromList $ newValue) a - addValue (Nothing) = Just . PDFDictionary $ M.insert name (AnyPdfObject . PDFDictionary . M.fromList $ newValue) M.empty +addResource dict name newValue r = let addValue (Just (PDFDictionary a)) = Just . PDFDictionary $ M.insert name newValue a + addValue (Nothing) = Just . PDFDictionary $ M.insert name newValue M.empty hunk ./Graphics/PDF/Resources.hs 89 - - +-- | Convert the resource to a PDf dictionary +resourceToDict :: PDFResource -> PDFDictionary +resourceToDict r = PDFDictionary . M.fromList $ + [(PDFName "ProcSet",AnyPdfObject (procSet r))] ++ + getResources (resources r) + +-- | An XObject +data PDFXObject +instance PdfObject PDFXObject where + toPDF _ = noPdfObject hunk ./Graphics/PDF/Text.hs 15 - testText + -- ** Types + PDFFont(..) + , FontName(..) + -- ** Functions + , drawText hunk ./Graphics/PDF/Text.hs 27 -testText :: PDFFloat +drawText :: PDFFont + -> PDFFloat hunk ./Graphics/PDF/Text.hs 30 - -> Int hunk ./Graphics/PDF/Text.hs 32 -testText x y size s = do - alphaMap <- gets theFonts - (newName,newMap) <- setResource "Font" (PDFFont Helvetica 12) alphaMap +drawText font@(PDFFont _ size) x y s = do + fontMap <- gets theFonts + (newName,newMap) <- setResource "Font" font fontMap hunk ./Graphics/PDF.hs 74 - let (state',w') = runDrawing d (DrawEnvironment r) + let (state',w') = runDrawing d (emptyEnvironment {streamId = r}) hunk ./Graphics/PDF.hs 77 - case p of - Nothing -> return () + rsrcRef <- addObject (rsrc state') + resources <- case p of + Nothing -> do + return $ (otherRsrcs state') `pdfDictUnion` (PDFDictionary . M.fromList $ [(PDFName "Resources",AnyPdfObject rsrcRef)]) hunk ./Graphics/PDF.hs 82 - rsrcRef <- addObject (rsrc state') hunk ./Graphics/PDF.hs 83 + return (otherRsrcs state') + hunk ./Graphics/PDF.hs 86 + -- Resources to add to the stream hunk ./Graphics/PDF.hs 90 - updateObject (PDFReference k :: PDFReference PDFStream) (PDFStream w'' True ref) + updateObject (PDFReference k :: PDFReference PDFStream) (PDFStream w'' True ref resources) hunk ./Graphics/PDF.hs 93 - updateObject (PDFReference k :: PDFReference PDFStream) (PDFStream w' False ref) + updateObject (PDFReference k :: PDFReference PDFStream) (PDFStream w' False ref resources) hunk ./Test/test.hs 37 + r <- createXObject 0 0 200 200 draw hunk ./Test/test.hs 45 - draw) - testText 200 200 12 (toPDFString "This is a test") + drawXObject r) + drawText (PDFFont Helvetica 12) 200 200 (toPDFString "This is a test éèçàù") hunk ./Test/test.hs 49 - draw + drawXObject r hunk ./Test/test.hs 51 - mapM_ (const $ addPageWithTransition Nothing (Just 3) (Just (PDFTransition 1.0 Dissolve))) [1..10] + return () + --mapM_ (const $ addPageWithTransition Nothing (Just 3) (Just (PDFTransition 1.0 Dissolve))) [1..10] hunk ./Graphics/PDF/LowLevel.hs 23 ---import Graphics.PDF.UTF8 hunk ./Graphics/PDF/LowLevel.hs 25 -import Data.Encoding.UTF16 - +import Data.Encoding.ISO88591 +import Data.Bits hunk ./Graphics/PDF/LowLevel.hs 76 -toPDFString = PDFString . encodeLazy UTF16 . escapeString +toPDFString = PDFString . encodeLazy ISO88591 . escapeString hunk ./Graphics/PDF/LowLevel.hs 122 - , a + , a hunk ./Graphics/PDF/LowLevel.hs 125 - + where + toHexa = B.concatMap hexaDigit + hexaDigit d = let hi = (d `shiftR` 4) .&. 0x0F + lo = d .&. 0x0F + chr n = if n >=0 && n <=9 then n + c2w '0' else (n-10) + c2w 'A' + in + B.pack [chr hi,chr lo] hunk ./Graphics/PDF/Resources.hs 31 -data FontName = Helvetica deriving(Eq,Ord) +data FontName = Helvetica + | Helvetica_Bold + | Helvetica_Oblique + | Helvetica_BoldOblique + | Times_Roman + | Times_Bold + | Times_Italic + | Times_BoldItalic + | Courier + | Courier_Bold + | Courier_Oblique + | Courier_BoldOblique + | Symbol + | ZapfDingbats + deriving(Eq,Ord) hunk ./Graphics/PDF/Resources.hs 49 + show Helvetica_Bold = "Helvetica-Bold" + show Helvetica_Oblique = "Helvetica-Oblique" + show Helvetica_BoldOblique = "Helvetica-BoldOblique" + show Times_Roman = "Times-Roman" + show Times_Bold = "Times-Bold" + show Times_Italic = "Times-Italic" + show Times_BoldItalic = "Times-BoldItalic" + show Courier = "Courier" + show Courier_Bold = "Courier-Bold" + show Courier_Oblique = "Courier-Oblique" + show Courier_BoldOblique = "Courier-BoldOblique" + show Symbol = "Symbol" + show ZapfDingbats = "ZapfDingbats" hunk ./Graphics/PDF/Resources.hs 72 - , (PDFName "BaseFont",AnyPdfObject . PDFName $ show f)] + , (PDFName "BaseFont",AnyPdfObject . PDFName $ show f) + , (PDFName "Encoding",AnyPdfObject . PDFName $ "WinAnsiEncoding")] adddir ./Graphics/PDF/LowLevel move ./Graphics/PDF/LowLevel.hs ./Graphics/PDF/LowLevel/Types.hs hunk ./Graphics/PDF.hs 35 - -- ** Misc (until the right module is created) - , toPDFString + -- ** Text + , module Graphics.PDF.Text + -- ** Navigation + , module Graphics.PDF.Navigation hunk ./Graphics/PDF.hs 41 +import Graphics.PDF.Navigation +import Graphics.PDF.Text hunk ./Graphics/PDF.hs 52 -import Graphics.PDF.LowLevel +import Graphics.PDF.LowLevel.Types hunk ./Graphics/PDF.hs 109 - outlines <- addObject PDFOutlines + o <- gets outline + oref <- addOutlines o hunk ./Graphics/PDF.hs 112 - cat <- addObject $ PDFCatalog outlines pRef (pageMode infos) (pageLayout infos) (viewerPreferences infos) + cat <- addObject $ PDFCatalog oref pRef (pageMode infos) (pageLayout infos) (viewerPreferences infos) hunk ./Graphics/PDF.hs 182 + , outline = Nothing + , currentPageNumber = Nothing hunk ./Graphics/PDF.hs 186 + hunk ./Graphics/PDF/Colors.hs 25 -import Graphics.PDF.LowLevel +import Graphics.PDF.LowLevel.Types hunk ./Graphics/PDF/Colors.hs 33 - - - +instance PdfObject Color where + toPDF (Rgb r g b) = toPDF . map (AnyPdfObject . PDFFloat) $ [r,g,b] + toPDF (Hsv h s v) = let (r,g,b) = hsvToRgb (h,s,v) + in toPDF . map (AnyPdfObject . PDFFloat) $ [r,g,b] + hunk ./Graphics/PDF/Coordinates.hs 25 -import Graphics.PDF.LowLevel +import Graphics.PDF.LowLevel.Types hunk ./Graphics/PDF/Data/PDFTree.hs 41 -import Graphics.PDF.LowLevel +import Graphics.PDF.LowLevel.Types hunk ./Graphics/PDF/Data/PDFTree.hs 59 - | Bin {-# UNPACK #-} !Int {-# UNPACK #-} !(Prefix a) {-# UNPACK #-} !(Mask a) !(PDFTree a) !(PDFTree a) + | Bin {-# UNPACK #-} !(Prefix a) {-# UNPACK #-} !(Mask a) !(PDFTree a) !(PDFTree a) hunk ./Graphics/PDF/Data/PDFTree.hs 65 - -> (Maybe b -> PDFTree a -> PDFTree a -> m b) -- ^ Node action - -> (Maybe b -> Key a -> a -> m b) -- ^ Leaf action + -> (Maybe b -> PDFTree a -> PDFTree a -> m (Int,b)) -- ^ Node action + -> (Maybe b -> Key a -> a -> m (Int,b)) -- ^ Leaf action hunk ./Graphics/PDF/Data/PDFTree.hs 68 - -> m b -- ^ Final action and reference of the root node + -> m (Int,b) -- ^ Final action and reference of the root node hunk ./Graphics/PDF/Data/PDFTree.hs 71 -fold2 p node _ (Bin _ _ _ l r) = node p l r +fold2 p node _ (Bin _ _ l r) = node p l r hunk ./Graphics/PDF/Data/PDFTree.hs 91 - Bin s _ _ _ _ -> s + Bin _ _ l r -> (size l) + (size r) hunk ./Graphics/PDF/Data/PDFTree.hs 108 - Bin _ _ m l r + Bin _ m l r hunk ./Graphics/PDF/Data/PDFTree.hs 122 - Bin s p m l r + Bin p m l r hunk ./Graphics/PDF/Data/PDFTree.hs 124 - | zero k m -> Bin (s+1) p m (insert k x l) r - | otherwise -> Bin (s+1) p m l (insert k x r) + | zero k m -> Bin p m (insert k x l) r + | otherwise -> Bin p m l (insert k x r) hunk ./Graphics/PDF/Data/PDFTree.hs 133 - | zero p1 m = Bin (size t1 + size t2) p m t1 t2 - | otherwise = Bin (size t1 + size t2) p m t2 t1 + | zero p1 m = Bin p m t1 t2 + | otherwise = Bin p m t2 t1 hunk ./Graphics/PDF/Document.hs 43 -import Graphics.PDF.LowLevel +import Graphics.PDF.LowLevel.Types hunk ./Graphics/PDF/Document.hs 114 - (pageref,page) <- createANewPage rect' - modifyStrict $ \s -> s {pages = recordPage (PDFReference pageref) page (pages s)} - return (PDFReference pageref) + (pf,page) <- createANewPage rect' + let pageref = PDFReference pf + modifyStrict $ \s -> s {pages = recordPage pageref page (pages s), currentPageNumber = maybe (Just 0) (Just . (+) 1) (currentPageNumber s)} + return pageref hunk ./Graphics/PDF/Document.hs 124 - (pageref,PDFPage a b c d _ _) <- createANewPage rect' - modifyStrict $ \s -> s {pages = recordPage (PDFReference pageref) (PDFPage a b c d dur t) (pages s)} - return (PDFReference pageref) + (pf,PDFPage a b c d _ _) <- createANewPage rect' + let pageref = PDFReference pf + modifyStrict $ \s -> s {pages = recordPage pageref (PDFPage a b c d dur t) (pages s), currentPageNumber = maybe (Just 0) (Just . (+) 1) (currentPageNumber s)} + return pageref hunk ./Graphics/PDF/Draw.hs 29 -import Graphics.PDF.LowLevel +import Graphics.PDF.LowLevel.Types hunk ./Graphics/PDF/LowLevel/Types.hs 13 -module Graphics.PDF.LowLevel where +module Graphics.PDF.LowLevel.Types where addfile ./Graphics/PDF/Navigation.hs hunk ./Graphics/PDF/Navigation.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- PDF Navigation +--------------------------------------------------------- + +module Graphics.PDF.Navigation( + Destination(..) + , newOutline + , moveToParent + ) where + +import Graphics.PDF.Pages +import Graphics.PDF.LowLevel.Types +import Graphics.PDF.Colors(Color(..)) +import qualified Data.Map as M +import Control.Monad.State(gets) + +newOutline :: PDFString -> PDF () +newOutline s = do + p <- gets currentPageNumber + case p of + Nothing -> return () + Just aPage -> do + ot <- gets outline + let value = (s,Destination aPage) + case ot of + Nothing -> modifyStrict $ \s -> s {outline = Just $ insertDown value (OutlineLoc (Node value []) Top)} + Just r -> modifyStrict $ \s -> s {outline = Just $ insertRight value r} + +moveToParent :: PDF () +moveToParent = do + ot <- gets outline + case ot of + Nothing -> return () + Just r -> modifyStrict $ \s -> s {outline = Just $ up r} hunk ./Graphics/PDF/Pages.hs 21 - , PDFOutlines(..) hunk ./Graphics/PDF/Pages.hs 33 + , getCurrentPage hunk ./Graphics/PDF/Pages.hs 44 + -- ** Outlines + , PDFOutline(..) + , OutlineStyle(..) + , PDFOutlineEntry(..) + , Destination(..) + , Outline + , OutlineLoc(..) + , Tree(..) + , OutlineCtx(..) + , addOutlines + , insertDown + , insertRight + , up hunk ./Graphics/PDF/Pages.hs 61 -import Graphics.PDF.LowLevel +import Graphics.PDF.LowLevel.Types hunk ./Graphics/PDF/Pages.hs 68 +import Graphics.PDF.Colors(Color(..)) +import Data.List(zip4) hunk ./Graphics/PDF/Pages.hs 151 - !(PDFReference PDFOutlines) + !(Maybe (PDFReference PDFOutline)) hunk ./Graphics/PDF/Pages.hs 156 - --- | PDF outlines -data PDFOutlines = PDFOutlines hunk ./Graphics/PDF/Pages.hs 165 + , outline :: Maybe Outline -- ^ Root outline + , currentPageNumber :: Maybe Int hunk ./Graphics/PDF/Pages.hs 304 - , (PDFName "Outlines",AnyPdfObject outlines) hunk ./Graphics/PDF/Pages.hs 308 - ] - --- PDF Outlines - -instance PdfObject PDFOutlines where - toPDF (PDFOutlines) = toPDF $ PDFDictionary. M.fromList $ - [ (PDFName "Type",AnyPdfObject (PDFName "Outlines")) - , (PDFName "Count",AnyPdfObject (PDFInteger 0)) - ] - + ] ++ (maybe [] (\x -> [(PDFName "Outlines",AnyPdfObject x)]) outlines) hunk ./Graphics/PDF/Pages.hs 327 - -> PDF (PDFReference PDFPages) -- ^ PDF reference to the new node pointing to the left and right ones + -> PDF (Int,PDFReference PDFPages) -- ^ PDF reference to the new node pointing to the left and right ones hunk ./Graphics/PDF/Pages.hs 332 - lr <- PT.fold2 (Just pRef) nodePage leafPage l - rr <- PT.fold2 (Just pRef) nodePage leafPage r + (sl,lr) <- PT.fold2 (Just pRef) nodePage leafPage l + (sr,rr) <- PT.fold2 (Just pRef) nodePage leafPage r + let len = sl + sr hunk ./Graphics/PDF/Pages.hs 336 - (False,False) -> updateObject pRef $ PDFPages (PT.size l + PT.size r) ref [Left lr,Left rr] - (True,False) -> updateObject pRef $ PDFPages (PT.size l + PT.size r) ref [Right (PT.keyOf l),Left rr] - (False,True) -> updateObject pRef $ PDFPages (PT.size l + PT.size r) ref [Left lr,Right (PT.keyOf r)] - (True,True) -> updateObject pRef $ PDFPages (PT.size l + PT.size r) ref [Right (PT.keyOf l),Right (PT.keyOf r)] - return pRef + (False,False) -> updateObject pRef $ PDFPages len ref [Left lr,Left rr] + (True,False) -> updateObject pRef $ PDFPages len ref [Right (PT.keyOf l),Left rr] + (False,True) -> updateObject pRef $ PDFPages len ref [Left lr,Right (PT.keyOf r)] + (True,True) -> updateObject pRef $ PDFPages len ref [Right (PT.keyOf l),Right (PT.keyOf r)] + return (len,pRef) hunk ./Graphics/PDF/Pages.hs 347 - -> PDF (PDFReference PDFPages) -- ^ Reference to a PDFPages objects + -> PDF (Int,PDFReference PDFPages) -- ^ Reference to a PDFPages objects hunk ./Graphics/PDF/Pages.hs 350 - return ref + return (1,ref) hunk ./Graphics/PDF/Pages.hs 358 - return pRef + return (1,pRef) hunk ./Graphics/PDF/Pages.hs 364 - PT.fold2 Nothing nodePage leafPage lPages + (_,r) <- PT.fold2 Nothing nodePage leafPage lPages + return r hunk ./Graphics/PDF/Pages.hs 371 +data PDFOutline = PDFOutline !(PDFReference PDFOutlineEntry) !(PDFReference PDFOutlineEntry) + +instance PdfObject PDFOutline where + toPDF (PDFOutline first last) = toPDF $ PDFDictionary. M.fromList $ [ + (PDFName "Type",AnyPdfObject . PDFName $ "Outlines") + , (PDFName "First",AnyPdfObject first) + , (PDFName "Last",AnyPdfObject last) + ] + +data OutlineStyle = Normal + | Italic + | Bold + deriving(Eq) + +data PDFOutlineEntry = PDFOutlineEntry !PDFString + !(PDFReference PDFOutlineEntry) -- Parent + !(Maybe (PDFReference PDFOutlineEntry)) -- Prev + !(Maybe (PDFReference PDFOutlineEntry)) -- Next + !(Maybe (PDFReference PDFOutlineEntry)) -- First + !(Maybe (PDFReference PDFOutlineEntry)) -- Last + Int -- Count of descendent (negative) + Destination + Color -- + OutlineStyle + +instance PdfObject OutlineStyle where + toPDF Normal = toPDF (PDFInteger 0) + toPDF Italic = toPDF (PDFInteger 1) + toPDF Bold = toPDF (PDFInteger 2) + +instance PdfObject PDFOutlineEntry where + toPDF (PDFOutlineEntry title parent prev next first last count dest color style) = + toPDF $ PDFDictionary. M.fromList $ [ + (PDFName "Title",AnyPdfObject title) + , (PDFName "Parent",AnyPdfObject parent) + ] + ++ + maybe [] (\x -> [(PDFName "Prev",AnyPdfObject x)]) prev + ++ + maybe [] (\x -> [(PDFName "Next",AnyPdfObject x)]) next + ++ + maybe [] (\x -> [(PDFName "First",AnyPdfObject x)]) first + ++ + maybe [] (\x -> [(PDFName "Last",AnyPdfObject x)]) last + ++ + [ (PDFName "Count",AnyPdfObject (PDFInteger count)) + , (PDFName "Dest",AnyPdfObject dest) + , (PDFName "C",AnyPdfObject color) + , (PDFName "F",AnyPdfObject style) + ] + +data Destination = Destination !Int deriving(Eq,Show) + +instance PdfObject Destination where + toPDF (Destination r) = toPDF [ AnyPdfObject . PDFInteger $ r + , AnyPdfObject . PDFName $ "XYZ" + , AnyPdfObject . PDFInteger $ 0 + , AnyPdfObject . PDFInteger $ 0 + , AnyPdfObject . PDFInteger $ 0] + +-- Outline types without a position pointer. The true outline is the derivative +type OutlineData = (PDFString,Destination) +type Outline = OutlineLoc (PDFString,Destination) + +data Tree a = Node a [Tree a] + +data OutlineCtx a = Top | Child { value :: a + , parent :: OutlineCtx a + , lefts :: [Tree a] + , rights :: [Tree a] + } + + +data OutlineLoc a = OutlineLoc (Tree a) (OutlineCtx a) + + +-- insert a subtree to the right of the current node +insertRight :: a -> OutlineLoc a -> OutlineLoc a +insertRight t' (OutlineLoc _ Top) = error "Cannot insert right of the top node" +insertRight t' (OutlineLoc t c ) = let c' = Child { value = value c + , parent = parent c + , rights = rights c + , lefts = lefts c ++ [t] } + in OutlineLoc (Node t' []) c' + +insertLeft :: a -> OutlineLoc a -> OutlineLoc a +insertLeft t' (OutlineLoc _ Top) = error "Cannot insert left of the top node" +insertLeft t' (OutlineLoc t c ) = let c' = Child { value = value c + , parent = parent c + , rights = t : (rights c) + , lefts = lefts c } + in OutlineLoc (Node t' []) c' + +insertDown :: a -> OutlineLoc a -> OutlineLoc a +insertDown t' (OutlineLoc (Node v cs) c) = let c' = Child { value = v + , parent = c + , rights = [] + , lefts = cs + } + in OutlineLoc (Node t' []) c' + +-- move up +up :: OutlineLoc a -> OutlineLoc a +up (OutlineLoc _ Top ) = error "Cannot go up from the top node" +up (OutlineLoc t (Child v c ls rs)) = let t' = Node v (ls ++ [t] ++ rs) + in OutlineLoc t' c + + +addOutlines :: Maybe Outline -> PDF (Maybe (PDFReference PDFOutline)) +addOutlines Nothing = return Nothing +addOutlines (Just r) = do + let (Node root l) = toTree r + if null l + then return Nothing + else do + rootRef <- supply + (first,end) <- createOutline (PDFReference rootRef) l + let outlineCatalog = PDFOutline first end + updateObject (PDFReference rootRef) outlineCatalog + return (Just (PDFReference rootRef)) + + +createOutline :: PDFReference PDFOutlineEntry -> [Tree OutlineData] -> PDF (PDFReference PDFOutlineEntry,PDFReference PDFOutlineEntry) +createOutline r children = do + -- Get references for all these outlines + refs' <- mapM (const (supply >>= return . Just . PDFReference)) children + -- (previousRef, currentRef, currentNode, nextRef) + let refs = zip4 (Nothing : init refs') refs' children (tail refs' ++ [Nothing]) + current (_,c,_,_) = c + Just first = current (head refs) + Just end = current (last refs) + mapM_ (addEntry first end) refs + return (first,end) + where + addEntry first end (prev,Just current,Node (title,dest) c,next) = do + (f,e) <- if (null c) + then + return (Nothing,Nothing) + else + createOutline current c >>= \(x,y) -> return (Just x,Just y) + let o = PDFOutlineEntry title + r -- Parent + prev -- Prev + next + f + e + (-(length c)) + dest + (Rgb 0 0 0) + Normal + updateObject current o + + +toTree :: OutlineLoc a -> Tree a +toTree (OutlineLoc a Top) = a +toTree a = toTree (up a) + + +-- | Reference to the last created page +getCurrentPage :: PDF (Maybe Int) +getCurrentPage = gets currentPageNumber hunk ./Graphics/PDF/Resources.hs 26 -import Graphics.PDF.LowLevel +import Graphics.PDF.LowLevel.Types hunk ./Graphics/PDF/Shapes.hs 27 -import Graphics.PDF.LowLevel +import Graphics.PDF.LowLevel.Types hunk ./Graphics/PDF/Text.hs 20 + , toPDFString hunk ./Graphics/PDF/Text.hs 23 -import Graphics.PDF.LowLevel +import Graphics.PDF.LowLevel.Types hunk ./HPDF.cabal 19 + Graphics.PDF.Text + Graphics.PDF.Navigation hunk ./HPDF.cabal 22 - Graphics.PDF.LowLevel + Graphics.PDF.LowLevel.Types hunk ./HPDF.cabal 25 + Graphics.PDF.Resources hunk ./Test/test.hs 30 + --runPdf "test.pdf" (standardDocInfo { author=toPDFString $ "alpheccar (éèçà)" + -- , pageMode = FullScreen + -- , compressed = False + -- , viewerPreferences = standardViewerPrefs { + -- hideToolbar = True + -- } + -- }) rect $ do hunk ./Test/test.hs 38 - , pageMode = FullScreen hunk ./Test/test.hs 39 - , viewerPreferences = standardViewerPrefs { - hideToolbar = True - } hunk ./Test/test.hs 41 - page <- addPageWithTransition Nothing (Just 3.0) (Just (PDFTransition 1.0 Dissolve)) + --page <- addPageWithTransition Nothing (Just 3.0) (Just (PDFTransition 1.0 Dissolve)) + page <- addPage Nothing + newOutline (toPDFString "Page Main") hunk ./Test/test.hs 57 - --mapM_ (const $ addPageWithTransition Nothing (Just 3) (Just (PDFTransition 1.0 Dissolve))) [1..10] + --mapM_ (\x -> do addPageWithTransition Nothing (Just 3) (Just (PDFTransition 1.0 Dissolve)) + -- newOutline (toPDFString $ "Page " ++ (show x)) + -- ) [1..10] + mapM_ (\x -> do addPage Nothing + newOutline (toPDFString $ "Page " ++ (show x)) + ) [1..10] hunk ./Graphics/PDF/Document.hs 116 - modifyStrict $ \s -> s {pages = recordPage pageref page (pages s), currentPageNumber = maybe (Just 0) (Just . (+) 1) (currentPageNumber s)} + modifyStrict $ \s -> s {pages = recordPage pageref page (pages s), currentPage = Just pageref} hunk ./Graphics/PDF/Document.hs 126 - modifyStrict $ \s -> s {pages = recordPage pageref (PDFPage a b c d dur t) (pages s), currentPageNumber = maybe (Just 0) (Just . (+) 1) (currentPageNumber s)} + modifyStrict $ \s -> s {pages = recordPage pageref (PDFPage a b c d dur t) (pages s), currentPage = Just pageref} hunk ./Graphics/PDF/Navigation.hs 27 - p <- gets currentPageNumber + p <- gets currentPage hunk ./Graphics/PDF/Pages.hs 166 - , currentPageNumber :: Maybe Int + , currentPage :: Maybe (PDFReference PDFPage) hunk ./Graphics/PDF/Pages.hs 422 -data Destination = Destination !Int deriving(Eq,Show) +data Destination = Destination !(PDFReference PDFPage) deriving(Eq,Show) hunk ./Graphics/PDF/Pages.hs 425 - toPDF (Destination r) = toPDF [ AnyPdfObject . PDFInteger $ r - , AnyPdfObject . PDFName $ "XYZ" - , AnyPdfObject . PDFInteger $ 0 - , AnyPdfObject . PDFInteger $ 0 + toPDF (Destination r) = toPDF [ AnyPdfObject r + , AnyPdfObject . PDFName $ "FitH" hunk ./Graphics/PDF/Pages.hs 528 -getCurrentPage :: PDF (Maybe Int) -getCurrentPage = gets currentPageNumber +getCurrentPage :: PDF (Maybe (PDFReference PDFPage)) +getCurrentPage = gets currentPage hunk ./Graphics/PDF.hs 183 - , currentPageNumber = Nothing + , currentPage = Nothing hunk ./Graphics/PDF/Navigation.hs 14 - Destination(..) - , newOutline + -- * Navigation + -- ** Types + OutlineStyle(..) + -- ** Functions + , newSibling + , newChild hunk ./Graphics/PDF/Navigation.hs 29 -newOutline :: PDFString -> PDF () -newOutline s = do +newSibling :: PDFString -- ^ Outline title + -> Maybe Color -- ^ Outline color + -> Maybe OutlineStyle -- ^Outline style + -> PDF () +newSibling s col style = do hunk ./Graphics/PDF/Navigation.hs 39 - let value = (s,Destination aPage) + let value = (s,col,style,Destination aPage) hunk ./Graphics/PDF/Navigation.hs 44 +newChild :: PDFString -- ^ Outline title + -> Maybe Color -- ^ Outline color + -> Maybe OutlineStyle -- ^Outline style + -> PDF () +newChild s col style = do + p <- gets currentPage + case p of + Nothing -> return () + Just aPage -> do + ot <- gets outline + let value = (s,col,style,Destination aPage) + case ot of + Nothing -> modifyStrict $ \s -> s {outline = Just $ insertDown value (OutlineLoc (Node value []) Top)} + Just r -> modifyStrict $ \s -> s {outline = Just $ insertDown value r} + hunk ./Graphics/PDF/Pages.hs 426 - , AnyPdfObject . PDFName $ "FitH" - , AnyPdfObject . PDFInteger $ 0] + , AnyPdfObject . PDFName $ "Fit" + ] hunk ./Graphics/PDF/Pages.hs 430 -type OutlineData = (PDFString,Destination) -type Outline = OutlineLoc (PDFString,Destination) +type OutlineData = (PDFString,Maybe Color, Maybe OutlineStyle,Destination) +type Outline = OutlineLoc OutlineData hunk ./Graphics/PDF/Pages.hs 503 - addEntry first end (prev,Just current,Node (title,dest) c,next) = do + addEntry first end (prev,Just current,Node (title,col,style,dest) c,next) = do hunk ./Graphics/PDF/Pages.hs 517 - (Rgb 0 0 0) - Normal + (maybe (Rgb 0 0 0) id col) + (maybe Normal id style) hunk ./Test/test.hs 27 +triplet :: String -> PDF () +triplet s = do + addPage Nothing + newSibling (toPDFString $ "Page A" ++ s) (Just $ Rgb 1 0 0) Nothing + addPage Nothing + newChild (toPDFString $ "Page B" ++ s) Nothing (Just Italic) + addPage Nothing + newChild (toPDFString $ "Page C" ++ s) Nothing (Just Bold) + addPage Nothing + newSibling (toPDFString $ "Page D" ++ s) Nothing Nothing + moveToParent + moveToParent + hunk ./Test/test.hs 56 - newOutline (toPDFString "Page Main") + newSibling (toPDFString "Page Main") Nothing Nothing hunk ./Test/test.hs 73 - mapM_ (\x -> do addPage Nothing - newOutline (toPDFString $ "Page " ++ (show x)) - ) [1..10] + triplet "A" + triplet "B" + triplet "C" hunk ./Graphics/PDF.hs 39 + -- ** Annotations + , module Graphics.PDF.Annotation hunk ./Graphics/PDF.hs 53 - +import Graphics.PDF.Annotation hunk ./Graphics/PDF.hs 73 - hunk ./Graphics/PDF.hs 84 + -- Not linked to a page hunk ./Graphics/PDF.hs 87 + -- Linked to a page hunk ./Graphics/PDF.hs 89 + setPageAnnotations (annots state') pageRef addfile ./Graphics/PDF/Annotation.hs hunk ./Graphics/PDF/Annotation.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- PDF Annotations +--------------------------------------------------------- + +module Graphics.PDF.Annotation( + -- * Annotations + -- ** Types + AnnotationType(..) + , Annotation(..) + -- ** Functions + , newAnnotation + ) where + +import Graphics.PDF.LowLevel.Types +import Graphics.PDF.Resources +import Graphics.PDF.Draw +import qualified Data.Map as M + +data AnnotationType = TextAnnotation + | Link + | FreeText + | Line + | Square + | Circle + | Highlight + | Underline + | Squiggly + | StrikeOut + | Stamp + | Ink + | Popup + | FileAttachment + | Sound + | Movie + | Widget + | PrinterMark + deriving(Eq,Show) + +data Annotation = Annotation AnnotationType [PDFFloat] PDFString + +instance PdfObject Annotation where + toPDF (Annotation aType rect content) = toPDF . PDFDictionary . M.fromList $ + [(PDFName "Type",AnyPdfObject . PDFName $ "Annot") + , (PDFName "Subtype",AnyPdfObject . PDFName $ (show aType)) + , (PDFName "Rect",AnyPdfObject . map AnyPdfObject $ rect) + , (PDFName "Contents",AnyPdfObject content) + ] + +-- | Set alpha value for transparency +newAnnotation :: Annotation -> Draw () +newAnnotation annot = do + modifyStrict $ \s -> s {annots = (AnyPdfObject annot):(annots s)} + return () hunk ./Graphics/PDF/Document.hs 23 + , setPageAnnotations hunk ./Graphics/PDF/Document.hs 108 - let page = PDFPage Nothing rect pageContent Nothing Nothing Nothing + let page = PDFPage Nothing rect pageContent Nothing Nothing Nothing [] hunk ./Graphics/PDF/Document.hs 125 - (pf,PDFPage a b c d _ _) <- createANewPage rect' + (pf,PDFPage a b c d _ _ pageAnnots) <- createANewPage rect' hunk ./Graphics/PDF/Document.hs 127 - modifyStrict $ \s -> s {pages = recordPage pageref (PDFPage a b c d dur t) (pages s), currentPage = Just pageref} + modifyStrict $ \s -> s {pages = recordPage pageref (PDFPage a b c d dur t pageAnnots) (pages s), currentPage = Just pageref} hunk ./Graphics/PDF/Document.hs 130 +-- | Set page annotations +setPageAnnotations :: [AnyPdfObject] -> PDFReference PDFPage -> PDF () +setPageAnnotations an page = do + -- Get the page dictionary + lPages <- gets pages + -- Look for the page + let thePage = findPage page lPages + case thePage of + Nothing -> return () + -- If the page is found, get its stream reference and look for the stream + Just (PDFPage a b c d e f _) -> do + refs <- mapM (\x -> addObject x >>= return . AnyPdfObject) an + modifyStrict $ \s -> s {pages = recordPage page (PDFPage a b c d e f refs) lPages} + hunk ./Graphics/PDF/Document.hs 154 - Just (PDFPage a b c _ e f) -> modifyStrict $ \s -> s {pages = recordPage page (PDFPage a b c (Just newr) e f) lPages} + Just (PDFPage a b c _ e f g) -> modifyStrict $ \s -> s {pages = recordPage page (PDFPage a b c (Just newr) e f g) lPages} hunk ./Graphics/PDF/Document.hs 170 - Just(PDFPage _ _ (PDFReference streamRef) _ _ _) -> do + Just(PDFPage _ _ (PDFReference streamRef) _ _ _ _) -> do hunk ./Graphics/PDF/Draw.hs 46 + , annots :: [AnyPdfObject] hunk ./Graphics/PDF/Draw.hs 105 - M.empty M.empty M.empty M.empty - emptyDictionary + M.empty M.empty M.empty M.empty + emptyDictionary [] hunk ./Graphics/PDF/Pages.hs 178 + ![AnyPdfObject] -- ^ Annotation array hunk ./Graphics/PDF/Pages.hs 282 - toPDF (PDFPage (Just parent) box content rsrc d t) = toPDF $ PDFDictionary. M.fromList $ + toPDF (PDFPage (Just parent) box content rsrc d t annots) = toPDF $ PDFDictionary. M.fromList $ hunk ./Graphics/PDF/Pages.hs 294 - toPDF (PDFPage Nothing _ _ _ _ _) = noPdfObject + ++ ((\x -> if null x then [] else [(PDFName "Annots",AnyPdfObject x)]) annots) + toPDF (PDFPage Nothing _ _ _ _ _ _) = noPdfObject hunk ./Graphics/PDF/Pages.hs 350 -leafPage (Just ref) (PDFReference objectnb) (PDFPage _ a b c d e) = do - modifyStrict $ \s -> s {objects = IM.insert objectnb (AnyPdfObject $ PDFPage (Just ref) a b c d e) (objects s) } +leafPage (Just ref) (PDFReference objectnb) (PDFPage _ a b c d e f) = do + modifyStrict $ \s -> s {objects = IM.insert objectnb (AnyPdfObject $ PDFPage (Just ref) a b c d e f) (objects s) } hunk ./Graphics/PDF/Pages.hs 354 -leafPage Nothing p@(PDFReference objectnb) (PDFPage _ a b c d e) = do +leafPage Nothing p@(PDFReference objectnb) (PDFPage _ a b c d e f) = do hunk ./Graphics/PDF/Pages.hs 359 - modifyStrict $ \s -> s {objects = IM.insert objectnb (AnyPdfObject $ PDFPage (Just pRef) a b c d e) (objects s) } + modifyStrict $ \s -> s {objects = IM.insert objectnb (AnyPdfObject $ PDFPage (Just pRef) a b c d e f) (objects s) } hunk ./Test/test.hs 58 + newAnnotation (Annotation TextAnnotation [0,0,100,100] (toPDFString "Test")) hunk ./Graphics/PDF/Annotation.hs 45 - deriving(Eq,Show) + deriving(Eq) hunk ./Graphics/PDF/Annotation.hs 47 +instance Show AnnotationType where + show TextAnnotation = "Text" + show Link = "Link" + show FreeText = "FreeText" + show Line = "Line" + show Square = "Square" + show Circle = "Circle" + show Highlight = "Highlight" + show Underline = "Underline" + show Squiggly = "Squiggly" + show StrikeOut = "StrikeOut" + show Stamp = "Stamp" + show Ink = "Ink" + show Popup = "Popup" + show FileAttachment = "FileAttachment" + show Sound = "Sound" + show Movie = "Movie" + show Widget = "Widget" + show PrinterMark = "PrinterMark" + hunk ./Graphics/PDF.hs 41 + -- ** Actions + , module Graphics.PDF.Action hunk ./Graphics/PDF.hs 64 +import Graphics.PDF.Action addfile ./Graphics/PDF/Action.hs hunk ./Graphics/PDF/Action.hs 1 - +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- PDF Actions +--------------------------------------------------------- + +module Graphics.PDF.Action( + -- * Actions + -- ** Types + ActionType(..) + , Action(..) + -- ** Functions + ) where + +import Graphics.PDF.LowLevel.Types +import qualified Data.Map as M + +data ActionType = URI String + +newtype Action = Action ActionType + +actionFields :: ActionType -> [(PDFName,AnyPdfObject)] +actionFields (URI s) = [ (PDFName "S",AnyPdfObject (PDFName "URI")) + , (PDFName "URI",AnyPdfObject (toPDFString s)) + ] + +instance PdfObject Action where + toPDF (Action a) = toPDF . PDFDictionary . M.fromList $ + [(PDFName "Type",AnyPdfObject . PDFName $ "Action") + ] ++ actionFields a hunk ./Graphics/PDF/Annotation.hs 18 + , TextIcon(..) hunk ./Graphics/PDF/Annotation.hs 26 +import Graphics.PDF.Pages(PDFPage) hunk ./Graphics/PDF/Annotation.hs 28 +import Graphics.PDF.Action hunk ./Graphics/PDF/Annotation.hs 30 -data AnnotationType = TextAnnotation - | Link - | FreeText - | Line - | Square - | Circle - | Highlight - | Underline - | Squiggly - | StrikeOut - | Stamp - | Ink - | Popup - | FileAttachment - | Sound - | Movie - | Widget - | PrinterMark +data TextIcon = Note + | Paragraph + | NewParagraph + | Key + | Comment + | Help + | Insert + deriving(Eq,Show) + +data AnnotationType = TextAnnotation (Maybe TextIcon) + | PDFLink (PDFReference PDFPage) PDFFloat PDFFloat + | URLLink String hunk ./Graphics/PDF/Annotation.hs 45 - show TextAnnotation = "Text" - show Link = "Link" - show FreeText = "FreeText" - show Line = "Line" - show Square = "Square" - show Circle = "Circle" - show Highlight = "Highlight" - show Underline = "Underline" - show Squiggly = "Squiggly" - show StrikeOut = "StrikeOut" - show Stamp = "Stamp" - show Ink = "Ink" - show Popup = "Popup" - show FileAttachment = "FileAttachment" - show Sound = "Sound" - show Movie = "Movie" - show Widget = "Widget" - show PrinterMark = "PrinterMark" + show (TextAnnotation _) = "Text" + show (PDFLink _ _ _) = "Link" + show (URLLink _) = "Link" + hunk ./Graphics/PDF/Annotation.hs 52 +annotationTypeDictionary :: AnnotationType -> [(PDFName,AnyPdfObject)] +annotationTypeDictionary (TextAnnotation Nothing) = [] +annotationTypeDictionary (TextAnnotation (Just n)) = [(PDFName "Name",AnyPdfObject . PDFName $ show n)] +annotationTypeDictionary (URLLink a) = [(PDFName "A",AnyPdfObject (Action (URI a))) + ,(PDFName "Border",AnyPdfObject . map AnyPdfObject $ [PDFInteger 0,PDFInteger 0,PDFInteger 0])] +annotationTypeDictionary (PDFLink p x y) = let dest = [ AnyPdfObject p + , AnyPdfObject (PDFName "XYZ") + , AnyPdfObject x + , AnyPdfObject y + , AnyPdfObject (PDFInteger 0)] + in + [(PDFName "Dest",AnyPdfObject dest) + ,(PDFName "Border",AnyPdfObject . map AnyPdfObject $ [PDFInteger 0,PDFInteger 0,PDFInteger 0])] + hunk ./Graphics/PDF/Annotation.hs 72 - ] + ] ++ annotationTypeDictionary aType hunk ./Test/test.hs 58 - newAnnotation (Annotation TextAnnotation [0,0,100,100] (toPDFString "Test")) + newAnnotation (Annotation (URLLink "http://www.alpheccar.org") [0,0,100,100] (toPDFString "Test")) hunk ./Graphics/PDF.hs 43 + -- ** Images + , module Graphics.PDF.Image hunk ./Graphics/PDF.hs 67 +import Graphics.PDF.Image +import Graphics.PDF.Resources(emptyResource) hunk ./Graphics/PDF.hs 85 + -- New reference for the stream hunk ./Graphics/PDF.hs 87 + -- Run the drawing and get the new state (resource, annotation) hunk ./Graphics/PDF.hs 90 - -- If the stream is linked to a page we add the stream resources to the page - rsrcRef <- addObject (rsrc state') - resources <- case p of - -- Not linked to a page - Nothing -> do - return $ (otherRsrcs state') `pdfDictUnion` (PDFDictionary . M.fromList $ [(PDFName "Resources",AnyPdfObject rsrcRef)]) - -- Linked to a page - Just pageRef -> do - setPageAnnotations (annots state') pageRef - setPageResource rsrcRef pageRef - return (otherRsrcs state') + + -- If no resource needed by this drawing + resources <- if emptyResource (rsrc state') + then do + case p of + -- Not linked to a page + -- otherResource are entries specific to a special stream (like an XObject) so we return empty for a page + Nothing -> return (otherRsrcs state') + -- Linked to a page + Just pageRef -> do + setPageAnnotations (annots state') pageRef + return emptyDictionary + -- Some resource are needed by the stream + else do + rsrcRef <- addObject (rsrc state') + case p of + -- Not linked to a page + Nothing -> do + return $ (otherRsrcs state') `pdfDictUnion` (PDFDictionary . M.fromList $ [(PDFName "Resources",AnyPdfObject rsrcRef)]) + -- Linked to a page + Just pageRef -> do + setPageAnnotations (annots state') pageRef + setPageResource rsrcRef pageRef + return emptyDictionary hunk ./Graphics/PDF.hs 117 - if compressed infos + -- We compress only if the stream is not using its own filter + if (compressed infos) && (not (pdfDictMember (PDFName "Filter") resources)) hunk ./Graphics/PDF.hs 122 - updateObject ref (PDFLength ((B.length w'') + 1)) + updateObject ref (PDFLength (B.length w'')) hunk ./Graphics/PDF.hs 125 - updateObject ref (PDFLength ((B.length w') + 1)) + updateObject ref (PDFLength (B.length w')) hunk ./Graphics/PDF/Document.hs 16 - PDFXObject + PDFXForm hunk ./Graphics/PDF/Document.hs 33 - , createXObject + , createPDFXForm hunk ./Graphics/PDF/Document.hs 58 -drawXObject :: PDFReference PDFXObject -> Draw () -drawXObject r = do - xobjectMap <- gets xobjects - (newName,newMap) <- setResource "XObject" r xobjectMap - modifyStrict $ \s -> s { xobjects = newMap } - writeCmd ("\n/" ++ newName ++ " Do") + hunk ./Graphics/PDF/Document.hs 61 -createXObject :: Int -- ^ Left +createPDFXForm :: Int -- ^ Left hunk ./Graphics/PDF/Document.hs 66 - -> PDF (PDFReference PDFXObject) -createXObject xa ya xb yb d = let a' = do modifyStrict $ \s -> s {otherRsrcs = PDFDictionary. M.fromList $ + -> PDF (PDFReference PDFXForm) +createPDFXForm xa ya xb yb d = let a' = do modifyStrict $ \s -> s {otherRsrcs = PDFDictionary. M.fromList $ hunk ./Graphics/PDF/Document.hs 75 - d + d hunk ./Graphics/PDF/Document.hs 80 --- | Create a new empty content for a page -createContent :: Draw a -- ^ List of drawing commands - -> Maybe (PDFReference PDFPage) - -> PDF (PDFReference PDFStream) -- ^ Reference to the drawing -createContent d page = do - -- Create a new stream referenbce - streamref <- supply - modifyStrict $ \s -> s {streams = IM.insert streamref (page,d >> return ()) (streams s)} - return (PDFReference streamref) - - - + hunk ./Graphics/PDF/Draw.hs 27 + , PDFXForm + , PDFXObject(..) + , AnyPdfXForm + , pdfDictMember hunk ./Graphics/PDF/Draw.hs 48 - , xobjects :: M.Map (PDFReference PDFXObject) String + , xobjects :: M.Map (PDFReference AnyPdfXForm) String hunk ./Graphics/PDF/Draw.hs 79 - compressedStream True = [(PDFName "Filter",AnyPdfObject $ [AnyPdfObject . PDFName $ "FlateDecode"])] + compressedStream True = if not (pdfDictMember (PDFName "Filter") d) then [(PDFName "Filter",AnyPdfObject $ [AnyPdfObject . PDFName $ "FlateDecode"])] else [] hunk ./Graphics/PDF/Draw.hs 87 +-- | is member of the dictionary +pdfDictMember :: PDFName -> PDFDictionary -> Bool +pdfDictMember k (PDFDictionary d) = M.member k d + hunk ./Graphics/PDF/Draw.hs 141 +-- | A PDF Xobject which can be drawn +class PDFXObject a where + drawXObject :: PDFReference a -> Draw () + drawXObject (PDFReference r) = do + xobjectMap <- gets xobjects + (newName,newMap) <- setResource "XObject" (PDFReference r) xobjectMap + modifyStrict $ \s -> s { xobjects = newMap } + writeCmd ("\n/" ++ newName ++ " Do") + +-- | An XObject +data AnyPdfXForm = forall a. (PDFXObject a,PdfObject a) => AnyPdfXForm a +instance PdfObject AnyPdfXForm where + toPDF (AnyPdfXForm a) = toPDF a hunk ./Graphics/PDF/Draw.hs 155 +instance PDFXObject AnyPdfXForm + +data PDFXForm +instance PDFXObject PDFXForm +instance PdfObject PDFXForm where + toPDF _ = noPdfObject +instance PdfResourceObject (PDFReference PDFXForm) where + toRsrc = AnyPdfObject + +instance PdfResourceObject (PDFReference AnyPdfXForm) where + toRsrc = AnyPdfObject addfile ./Graphics/PDF/Image.hs hunk ./Graphics/PDF/Image.hs 1 - +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- PDF Images +--------------------------------------------------------- + +module Graphics.PDF.Image( + -- * Images + -- ** Types + -- ** Functions + createPDFImage + ) where + +import Graphics.PDF.LowLevel.Types +import qualified Data.Map as M +import Graphics.PDF.Draw +import Graphics.PDF.Resources +import Graphics.PDF.Pages +import Graphics.PDF.Document +import qualified Data.ByteString.Lazy as B +import Control.Monad.Writer +import System.IO +import Data.Char(ord) +import Data.Bits +import Text.Printf +import Control.Monad.Error + +m_sof0 = 0xc0 +m_sof1 = 0xc1 +m_sof2 = 0xc2 +m_sof3 = 0xc3 + +m_sof5 = 0xc5 +m_sof6 = 0xc6 +m_sof7 = 0xc7 + +m_jpg = 0xc8 +m_sof9 = 0xc9 +m_sof10 = 0xca +m_sof11 = 0xcb + +m_sof13 = 0xcd +m_sof14 = 0xce +m_sof15 = 0xcf + +m_dht = 0xc4 + +m_dac = 0xcc + +m_rst0 = 0xd0 +m_rst1 = 0xd1 +m_rst2 = 0xd2 +m_rst3 = 0xd3 +m_rst4 = 0xd4 +m_rst5 = 0xd5 +m_rst6 = 0xd6 +m_rst7 = 0xd7 + +m_soi = 0xd8 +m_eoi = 0xd9 +m_sos = 0xda +m_dqt = 0xdb +m_dnl = 0xdc +m_dri = 0xdd +m_dhp = 0xde +m_exp = 0xdf + +m_app0 = 0xe0 +m_app1 = 0xe1 +m_app2 = 0xe2 +m_app3 = 0xe3 +m_app4 = 0xe4 +m_app5 = 0xe5 +m_app6 = 0xe6 +m_app7 = 0xe7 +m_app8 = 0xe8 +m_app9 = 0xe9 +m_app10 = 0xea +m_app11 = 0xeb +m_app12 = 0xec +m_app13 = 0xed +m_app14 = 0xee +m_app15 = 0xef + +m_jpg0 = 0xf0 +m_jpg13 = 0xfd +m_com = 0xfe + +m_tem = 0x01 + +m_error = 0x100 + +io :: IO a -> FA a +io = liftIO + +-- | File analyzer monad +newtype FA a = FA {unFA :: ErrorT String PDF a} deriving(Monad,MonadError String,MonadIO,Functor) + +runFA :: FA a -> PDF (Either String a) +runFA = runErrorT . unFA + +readWord16 :: Handle -> FA Int +readWord16 h = io $ do + hi <- hGetChar h + lo <- hGetChar h + return $ ((fromEnum hi) `shiftL` 8) .|. (fromEnum . ord $ lo) + +readWord8 :: Handle -> FA Int +readWord8 h = io $ do + lo <- hGetChar h + return $ fromEnum . ord $ lo + +optional :: FA (Maybe a) -> FA (Maybe a) +optional a = a --`catchError` (\e -> return Nothing) + +jfif :: Handle -> FA (Maybe (Double,Double)) +jfif h = do + header <- readWord16 h + when (header /= 0x0FFE0) $ throwError (strMsg "No JFIF magic number") + readWord16 h + mapM_ check "JFIF" + readWord16 h + unit <- readWord8 h + width <- fromIntegral `fmap` readWord16 h + height <- fromIntegral `fmap` readWord16 h + case unit of + 1 -> return $ Just (width,height) + 2 -> return $ Just (width*2.54,height*2.54) + _ -> return $ Just (0,0) + where + check c' = do + c <- io $ hGetChar h + when (c /= c') $ throwError (strMsg "No JFIF header") + +parseJpegContent :: Handle -> FA (Int,Int,Int,Int) +parseJpegContent h = do + r <- readWord8 h + when (r /= 0x0FF) $ throwError (strMsg "No marker found") + sof <- readWord8 h + case sof of + a | a `elem` [m_sof5,m_sof6,m_sof7,m_sof9,m_sof10,m_sof11,m_sof13,m_sof14,m_sof15] -> throwError (strMsg "Unuspported compression mode") + | a `elem` [m_sof0,m_sof1,m_sof3] -> do + readWord16 h + bits_per_component <- readWord8 h + height <- readWord16 h + width <- readWord16 h + color_space <- readWord8 h + return (bits_per_component,height,width,color_space) + | a `elem` [m_soi,m_eoi,m_tem,m_rst0,m_rst1,m_rst2,m_rst3,m_rst4,m_rst5,m_rst6,m_rst7] -> parseJpegContent h + | otherwise -> do + l <- readWord16 h + io $ hSeek h RelativeSeek (fromIntegral (l-2)) + parseJpegContent h + +analyzeJpeg :: FilePath -> FA (Int,Int,Int,Int) +analyzeJpeg f = do + h <- io $ openBinaryFile f ReadMode + --io $ hSetBuffering h NoBuffering + -- Get Length + io $ hSeek h SeekFromEnd 0 + fileLength <- io $ hTell h + io $ hSeek h AbsoluteSeek 0 + -- Check jpeg + header <- readWord16 h + when (header /= 0x0FFD8) $ throwError (strMsg "Not a JPEG File") + + -- Extract resolution from jfif + res <- optional $ jfif h + + io $ hSeek h AbsoluteSeek 0 + + (bits_per_component,height,width,color_space) <- parseJpegContent h + --io $ print fileLength + --io $ print res + --io $ print bits_per_component + --io $ print height + --io $ print width + --io $ print color_space + --io $ hClose h + unless (color_space `elem` [1,3,4]) $ throwError (strMsg "Color space not supported") + return (bits_per_component,height,width,color_space) + +--test = analyzeJpeg "Test/logo.jpg" + +-- | Create a PDF XObject for a JPEG image +createPDFImage :: FilePath + -> PDF (Either String (PDFReference PDFImage)) +createPDFImage f = do + r <- runFA (analyzeJpeg f) + case r of + Right settings -> do + img <- liftIO $ B.readFile f + PDFReference s <- createContent (a' img settings) Nothing + return (Right $ PDFReference s) + Left s -> return $ Left s + where + color c = case c of + 1 -> [(PDFName "ColorSpace",AnyPdfObject $ PDFName "DeviceGray")] + 3 -> [(PDFName "ColorSpace",AnyPdfObject $ PDFName "DeviceRGB")] + 4 -> [(PDFName "ColorSpace",AnyPdfObject $ PDFName "DeviceCMYK") + ,(PDFName "Decode",AnyPdfObject . map (AnyPdfObject . PDFInteger) $ [1,0,1,0,1,0,1,0]) + ] + a' img (bits_per_component,height,width,color_space) = + do modifyStrict $ \s -> s {otherRsrcs = PDFDictionary. M.fromList $ + [ (PDFName "Type",AnyPdfObject . PDFName $ "XObject") + , (PDFName "SubType",AnyPdfObject . PDFName $ "Image") + , (PDFName "Width",AnyPdfObject . PDFInteger $ width) + , (PDFName "Height",AnyPdfObject . PDFInteger $ height) + , (PDFName "BitsPerComponent",AnyPdfObject . PDFInteger $ bits_per_component) + , (PDFName "Filter",AnyPdfObject . PDFName $ "DCTDecode") + ] ++ color color_space + } + tell img + + +data PDFImage +instance PDFXObject PDFImage +instance PdfObject PDFImage where + toPDF _ = noPdfObject +instance PdfResourceObject (PDFReference PDFImage) where + toRsrc = AnyPdfObject hunk ./Graphics/PDF/Pages.hs 57 + , createContent hunk ./Graphics/PDF/Pages.hs 72 +-- | Create a new empty content for a page +createContent :: Draw a -- ^ List of drawing commands + -> Maybe (PDFReference PDFPage) + -> PDF (PDFReference PDFStream) -- ^ Reference to the drawing +createContent d page = do + -- Create a new stream referenbce + streamref <- supply + modifyStrict $ \s -> s {streams = IM.insert streamref (page,d >> return ()) (streams s)} + return (PDFReference streamref) + hunk ./Graphics/PDF/Resources.hs 23 - , PDFXObject + , PdfResourceObject(..) + , emptyResource hunk ./Graphics/PDF/Resources.hs 87 -instance PdfResourceObject (PDFReference PDFXObject) where - toRsrc = AnyPdfObject hunk ./Graphics/PDF/Resources.hs 96 -emptyRsrc = PDFResource [AnyPdfObject . PDFName $ "PDF"] (M.empty) - +--emptyRsrc = PDFResource [AnyPdfObject . PDFName $ "PDF"] (M.empty) +emptyRsrc = PDFResource [] (M.empty) hunk ./Graphics/PDF/Resources.hs 119 - [(PDFName "ProcSet",AnyPdfObject (procSet r))] ++ + --[(PDFName "ProcSet",AnyPdfObject (procSet r))] ++ hunk ./Graphics/PDF/Resources.hs 122 --- | An XObject -data PDFXObject -instance PdfObject PDFXObject where - toPDF _ = noPdfObject +emptyResource :: PDFResource -> Bool +emptyResource (PDFResource a b) = null a && M.null b hunk ./Test/test.hs 53 - r <- createXObject 0 0 200 200 draw + r <- createPDFXForm 0 0 200 200 draw + Right jpg <- createPDFImage "logo.jpg" hunk ./Test/test.hs 70 + drawXObject jpg hunk ./Graphics/PDF/Document.hs 58 - - hunk ./Graphics/PDF/Document.hs 76 + recordBound s (xb-xa) (yb-ya) hunk ./Graphics/PDF/Draw.hs 31 + , getBound hunk ./Graphics/PDF/Draw.hs 42 +import qualified Data.IntMap as IM hunk ./Graphics/PDF/Draw.hs 56 + , xobjectb :: IM.IntMap (Int,Int) hunk ./Graphics/PDF/Draw.hs 60 -emptyEnvironment = DrawEnvironment 0 +emptyEnvironment = DrawEnvironment 0 IM.empty hunk ./Graphics/PDF/Draw.hs 147 - drawXObject (PDFReference r) = do + bounds :: PDFReference a -> Draw (Int,Int) + + privateDrawXObject :: PDFReference a -> Draw () + privateDrawXObject (PDFReference r) = do hunk ./Graphics/PDF/Draw.hs 155 + drawXObject = privateDrawXObject + + bounds (PDFReference r) = getBound r hunk ./Graphics/PDF/Draw.hs 175 + + +-- | Get the bounds for an xobject +getBound :: Int -- ^ Reference + -> Draw (Int,Int) +getBound ref = do + bounds <- asks xobjectb + return $ IM.findWithDefault (0,0) ref bounds + hunk ./Graphics/PDF/Image.hs 33 - +import Graphics.PDF.Coordinates + hunk ./Graphics/PDF/Image.hs 198 - Right settings -> do + Right settings@(_,height,width,_) -> do hunk ./Graphics/PDF/Image.hs 201 + recordBound s width height hunk ./Graphics/PDF/Image.hs 214 - , (PDFName "SubType",AnyPdfObject . PDFName $ "Image") + , (PDFName "Subtype",AnyPdfObject . PDFName $ "Image") hunk ./Graphics/PDF/Image.hs 225 -instance PDFXObject PDFImage +instance PDFXObject PDFImage where + drawXObject a = withNewContext $ do + (width,height) <- bounds a + applyMatrix (scale (fromIntegral width) (fromIntegral height)) + applyMatrix (translate 0 0) + privateDrawXObject a + hunk ./Graphics/PDF/Pages.hs 58 + , recordBound hunk ./Graphics/PDF/Pages.hs 170 -data PdfState = PdfState { supplySrc :: !Int -- ^ Supply of unique identfiers +data PdfState = PdfState { supplySrc :: !Int -- ^ Supply of unique identifiers hunk ./Graphics/PDF/Pages.hs 178 - , currentPage :: Maybe (PDFReference PDFPage) + , currentPage :: Maybe (PDFReference PDFPage) -- ^ Reference to the current page used to create outlines + , xobjectBound :: !(IM.IntMap (Int,Int)) -- ^ Width and height of xobjects hunk ./Graphics/PDF/Pages.hs 545 + +-- | Record bound of an xobject +recordBound :: Int -- ^ Reference + -> Int -- ^ Width + -> Int -- ^ Height + -> PDF () +recordBound ref width height = modifyStrict $ \s -> s {xobjectBound = IM.insert ref (width,height) (xobjectBound s)} + hunk ./Graphics/PDF.hs 88 - let (state',w') = runDrawing d (emptyEnvironment {streamId = r}) + bounds <- gets xobjectBound + let (state',w') = runDrawing d (emptyEnvironment {streamId = r, xobjectb = bounds }) hunk ./Graphics/PDF.hs 212 + , xobjectBound = IM.empty hunk ./Test/test.hs 65 - drawXObject r) + drawXObject r + ) hunk ./Test/test.hs 71 + setFillAlpha 1.0 hunk ./Graphics/PDF.hs 45 + -- ** Media + , module Graphics.PDF.Media hunk ./Graphics/PDF.hs 49 +import Graphics.PDF.Media hunk ./Graphics/PDF.hs 92 - let (state',w') = runDrawing d (emptyEnvironment {streamId = r, xobjectb = bounds }) + cp <- gets currentPage + let (state',w') = runDrawing d (emptyEnvironment {streamId = r, xobjectb = bounds, currentp = maybe Nothing (\(PDFReference x) -> Just x) cp }) hunk ./Graphics/PDF.hs 191 - let header = toByteString "%PDF-1.4\n" + let header = toByteString "%PDF-1.5\n" hunk ./Graphics/PDF/Action.hs 18 + , RenditionKind(..) hunk ./Graphics/PDF/Action.hs 25 +data Rendition = Rendition + +instance PdfObject Rendition where + toPDF Rendition = noPdfObject + +data RenditionKind = Play + | Stop + | Pause + | Resume + deriving(Enum) + hunk ./Graphics/PDF/Action.hs 37 + | SomeMedia RenditionKind Int Rendition hunk ./Graphics/PDF/Action.hs 45 +actionFields (SomeMedia op an r) = [ (PDFName "S",AnyPdfObject (PDFName "Rendition")) + , (PDFName "R",AnyPdfObject r) + , (PDFName "OP",AnyPdfObject . PDFInteger $ (fromEnum op)) + , (PDFName "AN",AnyPdfObject $ (PDFReference an :: PDFReference AnyPdfObject)) + ] hunk ./Graphics/PDF/Annotation.hs 16 - AnnotationType(..) - , Annotation(..) + TextAnnotation(..) + , URLLink(..) + , PDFLink(..) + , Screen(..) hunk ./Graphics/PDF/Annotation.hs 28 -import Graphics.PDF.Pages(PDFPage) hunk ./Graphics/PDF/Annotation.hs 30 +import Graphics.PDF.Colors +import Graphics.PDF.Pages(addObject) hunk ./Graphics/PDF/Annotation.hs 42 -data AnnotationType = TextAnnotation (Maybe TextIcon) - | PDFLink (PDFReference PDFPage) PDFFloat PDFFloat - | URLLink String - deriving(Eq) - -instance Show AnnotationType where - show (TextAnnotation _) = "Text" - show (PDFLink _ _ _) = "Link" - show (URLLink _) = "Link" - - -data Annotation = Annotation AnnotationType [PDFFloat] PDFString + +data TextAnnotation = TextAnnotation PDFString [PDFFloat] TextIcon +data URLLink = URLLink PDFString [PDFFloat] String Bool +data PDFLink = PDFLink PDFString [PDFFloat] (PDFReference PDFPage) PDFFloat PDFFloat Bool +data Screen = Screen PDFString [PDFFloat] (PDFReference PDFPage) hunk ./Graphics/PDF/Annotation.hs 48 -annotationTypeDictionary :: AnnotationType -> [(PDFName,AnyPdfObject)] -annotationTypeDictionary (TextAnnotation Nothing) = [] -annotationTypeDictionary (TextAnnotation (Just n)) = [(PDFName "Name",AnyPdfObject . PDFName $ show n)] -annotationTypeDictionary (URLLink a) = [(PDFName "A",AnyPdfObject (Action (URI a))) - ,(PDFName "Border",AnyPdfObject . map AnyPdfObject $ [PDFInteger 0,PDFInteger 0,PDFInteger 0])] -annotationTypeDictionary (PDFLink p x y) = let dest = [ AnyPdfObject p - , AnyPdfObject (PDFName "XYZ") - , AnyPdfObject x - , AnyPdfObject y - , AnyPdfObject (PDFInteger 0)] - in - [(PDFName "Dest",AnyPdfObject dest) - ,(PDFName "Border",AnyPdfObject . map AnyPdfObject $ [PDFInteger 0,PDFInteger 0,PDFInteger 0])] +getRgbTriple :: Color -> [Double] +getRgbTriple (Rgb r g b) = [r,g,b] +getRgbTriple (Hsv h s v) = let (r,g,b) = hsvToRgb (h,s,v) in [r,g,b] hunk ./Graphics/PDF/Annotation.hs 52 -instance PdfObject Annotation where - toPDF (Annotation aType rect content) = toPDF . PDFDictionary . M.fromList $ - [(PDFName "Type",AnyPdfObject . PDFName $ "Annot") - , (PDFName "Subtype",AnyPdfObject . PDFName $ (show aType)) - , (PDFName "Rect",AnyPdfObject . map AnyPdfObject $ rect) - , (PDFName "Contents",AnyPdfObject content) - ] ++ annotationTypeDictionary aType +-- | Get the border shqpe depending on the style +getBorder :: Bool -> [PDFInteger] +getBorder False = [0,0,0] +getBorder True = [0,0,1] hunk ./Graphics/PDF/Annotation.hs 57 +standardAnnotationDict :: AnnotationObject a => a -> [(PDFName,AnyPdfObject)] +standardAnnotationDict a = [(PDFName "Type",AnyPdfObject . PDFName $ "Annot") + , (PDFName "Subtype",AnyPdfObject $ annotationType a) + , (PDFName "Rect",AnyPdfObject . map AnyPdfObject $ annotationRect a) + , (PDFName "Contents",AnyPdfObject $ annotationContent a) + ] + +instance PdfObject Screen where + toPDF a@(Screen _ _ p) = toPDF . PDFDictionary . M.fromList $ + standardAnnotationDict a ++ [(PDFName "P",AnyPdfObject p)] + +instance AnnotationObject Screen where + addAnnotation = addObject + annotationType _ = PDFName "Screen" + annotationContent (Screen s _ _) = s + annotationRect (Screen _ r _) = r + +instance PdfObject TextAnnotation where + toPDF a@(TextAnnotation _ _ i) = toPDF . PDFDictionary . M.fromList $ + standardAnnotationDict a ++ [(PDFName "Name",AnyPdfObject . PDFName $ show i)] + +instance AnnotationObject TextAnnotation where + addAnnotation = addObject + annotationType _ = PDFName "Text" + annotationContent (TextAnnotation s _ _) = s + annotationRect (TextAnnotation _ r _) = r + +instance PdfObject URLLink where + toPDF a@(URLLink _ _ url border) = toPDF . PDFDictionary . M.fromList $ + standardAnnotationDict a ++ + [ (PDFName "A",AnyPdfObject (Action (URI url))) + , (PDFName "Border",AnyPdfObject . map AnyPdfObject $ (getBorder border)) + ] + +instance AnnotationObject URLLink where + addAnnotation = addObject + annotationType _ = PDFName "Link" + annotationContent (URLLink s _ _ _) = s + annotationRect (URLLink _ r _ _) = r + +instance PdfObject PDFLink where + toPDF a@(PDFLink _ _ page x y border) = toPDF . PDFDictionary . M.fromList $ + standardAnnotationDict a ++ + [(PDFName "Dest",AnyPdfObject dest) + ,(PDFName "Border",AnyPdfObject . map AnyPdfObject $ (getBorder border))] + where + dest = [ AnyPdfObject page + , AnyPdfObject (PDFName "XYZ") + , AnyPdfObject x + , AnyPdfObject y + , AnyPdfObject (PDFInteger 0)] + + +instance AnnotationObject PDFLink where + addAnnotation = addObject + annotationType _ = PDFName "Link" + annotationContent (PDFLink s _ _ _ _ _) = s + annotationRect (PDFLink _ r _ _ _ _) = r + hunk ./Graphics/PDF/Annotation.hs 117 -newAnnotation :: Annotation -> Draw () +newAnnotation :: (PdfObject a, AnnotationObject a) => a -> Draw () hunk ./Graphics/PDF/Annotation.hs 119 - modifyStrict $ \s -> s {annots = (AnyPdfObject annot):(annots s)} + modifyStrict $ \s -> s {annots = (AnyAnnotation annot):(annots s)} hunk ./Graphics/PDF/Colors.hs 22 + , hsvToRgb + -- ** Some colors + , black + , white + , red + , blue + , green hunk ./Graphics/PDF/Colors.hs 36 --- | A PDF color -data Color = Rgb !Double !Double !Double - | Hsv !Double !Double !Double hunk ./Graphics/PDF/Colors.hs 37 -instance PdfObject Color where - toPDF (Rgb r g b) = toPDF . map (AnyPdfObject . PDFFloat) $ [r,g,b] - toPDF (Hsv h s v) = let (r,g,b) = hsvToRgb (h,s,v) - in toPDF . map (AnyPdfObject . PDFFloat) $ [r,g,b] +black :: Color +black = Rgb 0 0 0 + +white :: Color +white = Rgb 1 1 1 + +red :: Color +red = Rgb 1 0 0 + +green :: Color +green = Rgb 0 1 0 + +blue :: Color +blue = Rgb 0 0 1 + + hunk ./Graphics/PDF/Colors.hs 74 - -hsvToRgb :: (Double,Double,Double) -> (Double,Double,Double) -hsvToRgb (h,s,v) = - let hi = fromIntegral (floor (h / 60) `mod` 6 :: Int) :: Double - f = h/60 - hi - p = v * (1-s) - q = v * (1 - f*s) - t = v * (1 - (1-f)*s) in - case hi of - 0 -> (v,t,p) - 1 -> (q,v,p) - 2 -> (p,v,t) - 3 -> (p,q,v) - 4 -> (t,p,v) - 5 -> (v,p,q) - _ -> error "Hue value incorrect" + hunk ./Graphics/PDF/Document.hs 114 -setPageAnnotations :: [AnyPdfObject] -> PDFReference PDFPage -> PDF () +setPageAnnotations :: [AnyAnnotation] -> PDFReference PDFPage -> PDF () hunk ./Graphics/PDF/Document.hs 124 - refs <- mapM (\x -> addObject x >>= return . AnyPdfObject) an + refs <- mapM (\x -> addAnnotation x >>= return . AnyPdfObject) an hunk ./Graphics/PDF/Draw.hs 32 + -- PDF types + , PDF(..) + , PDFPage(..) + , PDFPages(..) + , PdfState(..) + , PDFCatalog(..) + , Pages(..) + , PDFDocumentPageMode(..) + , PDFDocumentPageLayout(..) + , PDFViewerPreferences(..) + , PDFDocumentInfo(..) + -- ** Page transitions + , PDFTransition(..) + , PDFTransStyle(..) + , PDFTransDirection(..) + , PDFTransDimension(..) + , PDFTransDirection2(..) + -- ** Outlines + , PDFOutline(..) + , OutlineStyle(..) + , PDFOutlineEntry(..) + , Destination(..) + , Outline + , OutlineLoc(..) + , Tree(..) + , OutlineCtx(..) + , AnnotationObject(..) + , Color(..) + , hsvToRgb + , OutlineData + , AnyAnnotation(..) + , AnnotationStyle(..) hunk ./Graphics/PDF/Draw.hs 75 +import Graphics.PDF.Data.PDFTree(PDFTree,Key) +import Data.Maybe + +data AnnotationStyle = AnnotationStyle !(Maybe Color) + +class AnnotationObject a where + addAnnotation :: a -> PDF (PDFReference a) + annotationType :: a -> PDFName + annotationContent :: a -> PDFString + annotationRect :: a -> [PDFFloat] + +data AnyAnnotation = forall a.(PdfObject a,AnnotationObject a) => AnyAnnotation a + +instance PdfObject AnyAnnotation where + toPDF (AnyAnnotation a) = toPDF a + +instance AnnotationObject AnyAnnotation where + addAnnotation (AnyAnnotation a) = do + PDFReference r <- addAnnotation a + return (PDFReference r) + +-- | A PDF color +data Color = Rgb !Double !Double !Double + | Hsv !Double !Double !Double hunk ./Graphics/PDF/Draw.hs 108 - , annots :: [AnyPdfObject] + , annots :: [AnyAnnotation] hunk ./Graphics/PDF/Draw.hs 113 + , currentp :: Maybe Int hunk ./Graphics/PDF/Draw.hs 117 -emptyEnvironment = DrawEnvironment 0 IM.empty +emptyEnvironment = DrawEnvironment 0 IM.empty Nothing hunk ./Graphics/PDF/Draw.hs 240 + +----------- +-- +-- PDF types +-- +------------ + +-- | The PDF Catalog +data PDFCatalog = PDFCatalog + !(Maybe (PDFReference PDFOutline)) + !(PDFReference PDFPages) + !PDFDocumentPageMode + !PDFDocumentPageLayout + !PDFViewerPreferences + +-- | The PDF state +data PdfState = PdfState { supplySrc :: !Int -- ^ Supply of unique identifiers + , objects :: !(IM.IntMap AnyPdfObject) -- ^ Dictionary of PDF objects + , pages :: !Pages -- ^ Pages + , streams :: !(IM.IntMap ((Maybe (PDFReference PDFPage)),Draw ())) -- ^ Draw commands + , catalog :: !(PDFReference PDFCatalog) -- ^ Reference to the PDF catalog + , defaultRect :: !PDFRect -- ^ Default page size + , docInfo :: !PDFDocumentInfo -- ^ Document infos + , outline :: Maybe Outline -- ^ Root outline + , currentPage :: Maybe (PDFReference PDFPage) -- ^ Reference to the current page used to create outlines + , xobjectBound :: !(IM.IntMap (Int,Int)) -- ^ Width and height of xobjects + } + +-- | A PDF Page object +#ifndef __HADDOCK__ +data PDFPage = PDFPage + !(Maybe (PDFReference PDFPages)) -- ^ Reference to parent + !PDFRect -- ^ Media box + !(PDFReference PDFStream) -- ^ Reference to content + !(Maybe (PDFReference PDFResource)) -- ^ Reference to resources + !(Maybe PDFFloat) -- ^ Optional duration + !(Maybe PDFTransition) -- ^ Optional transition + ![AnyPdfObject] -- ^ Annotation array +#else +data PDFPage +#endif + +instance Show PDFPage where + show _ = "PDFPage" + +-- | List of all pages +newtype Pages = Pages (PDFTree PDFPage) + +-- | PDF Pages +#ifndef __HADDOCK__ +data PDFPages = PDFPages + !Int + !(Maybe (PDFReference PDFPages)) -- ^ Reference to parent + [Either (PDFReference PDFPages) (PDFReference PDFPage)] +#else +data PDFPages +#endif + +-- | A PDF Transition +data PDFTransition = PDFTransition !PDFFloat !PDFTransStyle deriving(Eq) + +-- | Dimension of a transition +data PDFTransDimension = Horizontal | Vertical deriving(Eq) + +instance Show PDFTransDimension where + show Horizontal = "H" + show Vertical = "V" + +-- | Direction of a transition +data PDFTransDirection = Inward | Outward deriving(Eq) + +instance Show PDFTransDirection where + show Inward = "I" + show Outward = "O" + +-- | Direction of a transition +data PDFTransDirection2 = LeftToRight + | BottomToTop -- ^ Wipe only + | RightToLeft -- ^ Wipe only + | TopToBottom + | TopLeftToBottomRight -- ^ Glitter only + deriving(Eq) + + -- | The PDF Monad +newtype PDF a = PDF {unPDF :: StateT PdfState IO a} +#ifndef __HADDOCK__ + deriving (Functor, Monad, MonadState PdfState, MonadIO) +#endif + +-- | Transition style +data PDFTransStyle = Split PDFTransDimension PDFTransDirection + | Blinds PDFTransDimension + | Box PDFTransDirection + | Wipe PDFTransDirection2 + | Dissolve + | Glitter PDFTransDirection2 + deriving(Eq) + + -- | Document metadata +data PDFDocumentInfo = PDFDocumentInfo { + author :: PDFString + , subject :: PDFString + , pageMode :: PDFDocumentPageMode + , pageLayout :: PDFDocumentPageLayout + , viewerPreferences :: PDFViewerPreferences + , compressed :: Bool + } + + +-- | Document page mode +data PDFDocumentPageMode = UseNone + | UseOutlines + | UseThumbs + | FullScreen + deriving(Eq,Show) + +-- | Document page layout +data PDFDocumentPageLayout = SinglePage + | OneColumn + | TwoColumnLeft + | TwoColumnRight + | TwoPageLeft + | TwoPageRight + deriving(Eq,Show) + +data PDFViewerPreferences = PDFViewerPreferences { hideToolbar :: Bool + , hideMenuBar :: Bool + , hideWindowUI :: Bool + , fitWindow :: Bool + , centerWindow :: Bool + , displayDoctitle :: Bool + , nonFullScreenPageMode :: PDFDocumentPageMode + } + +data PDFOutline = PDFOutline !(PDFReference PDFOutlineEntry) !(PDFReference PDFOutlineEntry) + +instance PdfObject PDFOutline where + toPDF (PDFOutline first last) = toPDF $ PDFDictionary. M.fromList $ [ + (PDFName "Type",AnyPdfObject . PDFName $ "Outlines") + , (PDFName "First",AnyPdfObject first) + , (PDFName "Last",AnyPdfObject last) + ] + +data OutlineStyle = Normal + | Italic + | Bold + deriving(Eq) hunk ./Graphics/PDF/Draw.hs 388 +data PDFOutlineEntry = PDFOutlineEntry !PDFString + !(PDFReference PDFOutlineEntry) -- Parent + !(Maybe (PDFReference PDFOutlineEntry)) -- Prev + !(Maybe (PDFReference PDFOutlineEntry)) -- Next + !(Maybe (PDFReference PDFOutlineEntry)) -- First + !(Maybe (PDFReference PDFOutlineEntry)) -- Last + Int -- Count of descendent (negative) + Destination + Color -- + OutlineStyle + +data Destination = Destination !(PDFReference PDFPage) deriving(Eq,Show) + +-- Outline types without a position pointer. The true outline is the derivative +type OutlineData = (PDFString,Maybe Color, Maybe OutlineStyle,Destination) +type Outline = OutlineLoc OutlineData + +data Tree a = Node a [Tree a] + +data OutlineCtx a = Top | Child { value :: a + , parent :: OutlineCtx a + , lefts :: [Tree a] + , rights :: [Tree a] + } + + +data OutlineLoc a = OutlineLoc (Tree a) (OutlineCtx a) + +instance PdfObject PDFViewerPreferences where + toPDF (PDFViewerPreferences ht hm hwui fw cw ddt nfspm ) = toPDF $ PDFDictionary. M.fromList $ + [ (PDFName "HideToolbar",AnyPdfObject ht) + , (PDFName "HideMenubar",AnyPdfObject hm) + , (PDFName "HideWindowUI",AnyPdfObject hwui) + , (PDFName "FitWindow",AnyPdfObject fw) + , (PDFName "CenterWindow",AnyPdfObject cw) + , (PDFName "DisplayDocTitle",AnyPdfObject ddt) + , (PDFName "NonFullScreenPageMode",AnyPdfObject . PDFName . show $ nfspm) + ] + + +instance Show PDFTransStyle where + show (Split _ _) = "Split" + show (Blinds _) = "Blinds" + show (Box _) = "Box" + show (Wipe _) = "Wipe" + show (Dissolve) = "Dissolve" + show (Glitter _) = "Glitter" + +instance PdfObject PDFTransition where + toPDF (PDFTransition d t) = toPDF $ PDFDictionary. M.fromList $ + [ (PDFName "Type",AnyPdfObject (PDFName "Trans")) + , (PDFName "S",AnyPdfObject (PDFName (show t))) + , (PDFName "D",AnyPdfObject d) + ] ++ optionalDm t ++ optionalM t ++ optionalDi t + where + optionalDm (Split a _) = [ (PDFName "Dm",AnyPdfObject (PDFName (show a)))] + optionalDm (Blinds a) = [ (PDFName "Dm",AnyPdfObject (PDFName (show a)))] + optionalDm _ = [] + optionalM (Split _ a) = [ (PDFName "M",AnyPdfObject (PDFName (show a)))] + optionalM (Box a) = [ (PDFName "M",AnyPdfObject (PDFName (show a)))] + optionalM _ = [] + optionalDi (Wipe a) = [ (PDFName "Di",AnyPdfObject (floatDirection a))] + optionalDi (Glitter a) = [ (PDFName "Di",AnyPdfObject (floatDirection a))] + optionalDi _ = [] + +-- PDF Pages + +instance PdfObject PDFPages where + toPDF (PDFPages c Nothing l) = toPDF $ PDFDictionary. M.fromList $ + [ (PDFName "Type",AnyPdfObject (PDFName "Pages")) + , (PDFName "Kids",AnyPdfObject $ map AnyPdfObject l) + , (PDFName "Count",AnyPdfObject . PDFInteger $ c) + ] + toPDF (PDFPages c (Just parent) l) = toPDF $ PDFDictionary. M.fromList $ + [ (PDFName "Type",AnyPdfObject (PDFName "Pages")) + , (PDFName "Parent",AnyPdfObject parent) + , (PDFName "Kids",AnyPdfObject $ map AnyPdfObject l) + , (PDFName "Count",AnyPdfObject . PDFInteger $ c) + ] + + +instance PdfObject PDFPage where + toPDF (PDFPage (Just parent) box content rsrc d t annots) = toPDF $ PDFDictionary. M.fromList $ + [ (PDFName "Type",AnyPdfObject (PDFName "Page")) + , (PDFName "Parent",AnyPdfObject parent) + , (PDFName "MediaBox",AnyPdfObject box) + , (PDFName "Contents",AnyPdfObject content) + , if isJust rsrc + then + (PDFName "Resources",AnyPdfObject . fromJust $ rsrc) + else + (PDFName "Resources",AnyPdfObject emptyDictionary) + ] ++ (maybe [] (\x -> [(PDFName "Dur",AnyPdfObject x)]) d) + ++ (maybe [] (\x -> [(PDFName "Trans",AnyPdfObject x)]) t) + ++ ((\x -> if null x then [] else [(PDFName "Annots",AnyPdfObject x)]) annots) + toPDF (PDFPage Nothing _ _ _ _ _ _) = noPdfObject + + +-- Main objects in a PDF document + +instance PdfObject PDFCatalog where + toPDF (PDFCatalog outlines lPages pgMode pgLayout viewerPrefs) = toPDF $ PDFDictionary . M.fromList $ + [ (PDFName "Type",AnyPdfObject (PDFName "Catalog")) + , (PDFName "Pages",AnyPdfObject lPages) + , (PDFName "PageMode", AnyPdfObject . PDFName . show $ pgMode) + , (PDFName "PageLayout", AnyPdfObject . PDFName . show $ pgLayout) + , (PDFName "ViewerPreferences", AnyPdfObject viewerPrefs) + ] ++ (maybe [] (\x -> [(PDFName "Outlines",AnyPdfObject x)]) outlines) + + +instance PdfObject OutlineStyle where + toPDF Normal = toPDF (PDFInteger 0) + toPDF Italic = toPDF (PDFInteger 1) + toPDF Bold = toPDF (PDFInteger 2) + +instance PdfObject PDFOutlineEntry where + toPDF (PDFOutlineEntry title parent prev next first last count dest color style) = + toPDF $ PDFDictionary. M.fromList $ [ + (PDFName "Title",AnyPdfObject title) + , (PDFName "Parent",AnyPdfObject parent) + ] + ++ + maybe [] (\x -> [(PDFName "Prev",AnyPdfObject x)]) prev + ++ + maybe [] (\x -> [(PDFName "Next",AnyPdfObject x)]) next + ++ + maybe [] (\x -> [(PDFName "First",AnyPdfObject x)]) first + ++ + maybe [] (\x -> [(PDFName "Last",AnyPdfObject x)]) last + ++ + [ (PDFName "Count",AnyPdfObject (PDFInteger count)) + , (PDFName "Dest",AnyPdfObject dest) + , (PDFName "C",AnyPdfObject color) + , (PDFName "F",AnyPdfObject style) + ] + + + +instance PdfObject Destination where + toPDF (Destination r) = toPDF [ AnyPdfObject r + , AnyPdfObject . PDFName $ "Fit" + ] + +instance PdfObject Color where + toPDF (Rgb r g b) = toPDF . map (AnyPdfObject . PDFFloat) $ [r,g,b] + toPDF (Hsv h s v) = let (r,g,b) = hsvToRgb (h,s,v) + in toPDF . map (AnyPdfObject . PDFFloat) $ [r,g,b] + +floatDirection :: PDFTransDirection2 -> PDFFloat +floatDirection LeftToRight = 0 +floatDirection BottomToTop = 90 +floatDirection RightToLeft = 180 +floatDirection TopToBottom = 270 +floatDirection TopLeftToBottomRight = 315 + + +hsvToRgb :: (Double,Double,Double) -> (Double,Double,Double) +hsvToRgb (h,s,v) = + let hi = fromIntegral (floor (h / 60) `mod` 6 :: Int) :: Double + f = h/60 - hi + p = v * (1-s) + q = v * (1 - f*s) + t = v * (1 - (1-f)*s) in + case hi of + 0 -> (v,t,p) + 1 -> (q,v,p) + 2 -> (p,v,t) + 3 -> (p,q,v) + 4 -> (t,p,v) + 5 -> (v,p,q) + _ -> error "Hue value incorrect" hunk ./Graphics/PDF/Image.hs 16 + PDFJpeg hunk ./Graphics/PDF/Image.hs 18 - createPDFImage + , createPDFJpeg hunk ./Graphics/PDF/Image.hs 163 -analyzeJpeg :: FilePath -> FA (Int,Int,Int,Int) -analyzeJpeg f = do - h <- io $ openBinaryFile f ReadMode - --io $ hSetBuffering h NoBuffering +analyzeJpeg :: Handle -> FA (Int,Int,Int,Int) +analyzeJpeg h = do hunk ./Graphics/PDF/Image.hs 174 - res <- optional $ jfif h + --res <- optional $ jfif h hunk ./Graphics/PDF/Image.hs 189 ---test = analyzeJpeg "Test/logo.jpg" +--test = analyzePng "Test/logo.png" + hunk ./Graphics/PDF/Image.hs 193 -createPDFImage :: FilePath - -> PDF (Either String (PDFReference PDFImage)) -createPDFImage f = do - r <- runFA (analyzeJpeg f) +createPDFJpeg :: FilePath + -> PDF (Either String (PDFReference PDFJpeg)) +createPDFJpeg f = do + h <- liftIO $ openBinaryFile f ReadMode + r <- runFA (analyzeJpeg h) + liftIO $ hClose h hunk ./Graphics/PDF/Image.hs 226 -data PDFImage -instance PDFXObject PDFImage where +data PDFJpeg +instance PDFXObject PDFJpeg where hunk ./Graphics/PDF/Image.hs 234 -instance PdfObject PDFImage where +instance PdfObject PDFJpeg where hunk ./Graphics/PDF/Image.hs 236 -instance PdfResourceObject (PDFReference PDFImage) where +instance PdfResourceObject (PDFReference PDFJpeg) where hunk ./Graphics/PDF/LowLevel/Types.hs 227 + + addfile ./Graphics/PDF/Media.hs hunk ./Graphics/PDF/Media.hs 1 - +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- PDF Media (video, audio) +--------------------------------------------------------- + +module Graphics.PDF.Media( + -- * Images + -- ** Types + -- ** Functions + createVideoObject + ) where + +import Graphics.PDF.LowLevel.Types +import qualified Data.Map as M +import Graphics.PDF.Draw +import Graphics.PDF.Resources +import Graphics.PDF.Pages +import Graphics.PDF.Document +import qualified Data.ByteString.Lazy as B +import Control.Monad.Writer +import System.IO +import Data.Char(ord) +import Data.Bits +import Text.Printf +import Control.Monad.Error +import Control.Monad.Reader +import Graphics.PDF.Coordinates +import Graphics.PDF.Annotation + + + +createVideoObject :: FilePath + -> PDFFloat + -> PDFFloat + -> PDFFloat + -> PDFFloat + -> Draw () +createVideoObject f xa ya xb yb = do + cp <- asks currentp + case cp of + Nothing -> return () + Just p -> newAnnotation $ Screen (toPDFString "Test") [xa,ya,xb,yb] (PDFReference p) + return () hunk ./Graphics/PDF/Navigation.hs 24 +import Graphics.PDF.Draw hunk ./Graphics/PDF/Pages.hs 15 - -- ** Types - PDFPage(..) - , PDFPages(..) - , PdfState(..) - , PDF(..) - , PDFCatalog(..) - , Pages - , PDFDocumentPageMode(..) - , PDFDocumentPageLayout(..) - , PDFViewerPreferences(..) - , PDFDocumentInfo(..) hunk ./Graphics/PDF/Pages.hs 16 - , standardViewerPrefs + standardViewerPrefs hunk ./Graphics/PDF/Pages.hs 23 - -- ** Page transitions - , PDFTransition(..) - , PDFTransStyle(..) - , PDFTransDirection(..) - , PDFTransDimension(..) - , PDFTransDirection2(..) hunk ./Graphics/PDF/Pages.hs 27 - -- ** Outlines - , PDFOutline(..) - , OutlineStyle(..) - , PDFOutlineEntry(..) - , Destination(..) - , Outline - , OutlineLoc(..) - , Tree(..) - , OutlineCtx(..) hunk ./Graphics/PDF/Pages.hs 41 -import Graphics.PDF.Data.PDFTree(PDFTree,Key) -import Data.Maybe hunk ./Graphics/PDF/Pages.hs 42 -import Graphics.PDF.Colors(Color(..)) hunk ./Graphics/PDF/Pages.hs 44 +import Graphics.PDF.Data.PDFTree(PDFTree,Key) + + hunk ./Graphics/PDF/Pages.hs 56 - --- | The PDF Monad -newtype PDF a = PDF {unPDF :: StateT PdfState IO a} -#ifndef __HADDOCK__ - deriving (Functor, Monad, MonadState PdfState, MonadIO) -#endif hunk ./Graphics/PDF/Pages.hs 79 - -- | Document metadata -data PDFDocumentInfo = PDFDocumentInfo { - author :: PDFString - , subject :: PDFString - , pageMode :: PDFDocumentPageMode - , pageLayout :: PDFDocumentPageLayout - , viewerPreferences :: PDFViewerPreferences - , compressed :: Bool - } hunk ./Graphics/PDF/Pages.hs 80 - --- | Document page mode -data PDFDocumentPageMode = UseNone - | UseOutlines - | UseThumbs - | FullScreen - deriving(Eq,Show) - --- | Document page layout -data PDFDocumentPageLayout = SinglePage - | OneColumn - | TwoColumnLeft - | TwoColumnRight - | TwoPageLeft - | TwoPageRight - deriving(Eq,Show) - -data PDFViewerPreferences = PDFViewerPreferences { hideToolbar :: Bool - , hideMenuBar :: Bool - , hideWindowUI :: Bool - , fitWindow :: Bool - , centerWindow :: Bool - , displayDoctitle :: Bool - , nonFullScreenPageMode :: PDFDocumentPageMode - } hunk ./Graphics/PDF/Pages.hs 81 -instance PdfObject PDFViewerPreferences where - toPDF (PDFViewerPreferences ht hm hwui fw cw ddt nfspm ) = toPDF $ PDFDictionary. M.fromList $ - [ (PDFName "HideToolbar",AnyPdfObject ht) - , (PDFName "HideMenubar",AnyPdfObject hm) - , (PDFName "HideWindowUI",AnyPdfObject hwui) - , (PDFName "FitWindow",AnyPdfObject fw) - , (PDFName "CenterWindow",AnyPdfObject cw) - , (PDFName "DisplayDocTitle",AnyPdfObject ddt) - , (PDFName "NonFullScreenPageMode",AnyPdfObject . PDFName . show $ nfspm) - ] + hunk ./Graphics/PDF/Pages.hs 86 --- | The PDF Catalog -data PDFCatalog = PDFCatalog - !(Maybe (PDFReference PDFOutline)) - !(PDFReference PDFPages) - !PDFDocumentPageMode - !PDFDocumentPageLayout - !PDFViewerPreferences - --- | The PDF state -data PdfState = PdfState { supplySrc :: !Int -- ^ Supply of unique identifiers - , objects :: !(IM.IntMap AnyPdfObject) -- ^ Dictionary of PDF objects - , pages :: !Pages -- ^ Pages - , streams :: !(IM.IntMap ((Maybe (PDFReference PDFPage)),Draw ())) -- ^ Draw commands - , catalog :: !(PDFReference PDFCatalog) -- ^ Reference to the PDF catalog - , defaultRect :: !PDFRect -- ^ Default page size - , docInfo :: !PDFDocumentInfo -- ^ Document infos - , outline :: Maybe Outline -- ^ Root outline - , currentPage :: Maybe (PDFReference PDFPage) -- ^ Reference to the current page used to create outlines - , xobjectBound :: !(IM.IntMap (Int,Int)) -- ^ Width and height of xobjects - } - --- | A PDF Page object -#ifndef __HADDOCK__ -data PDFPage = PDFPage - !(Maybe (PDFReference PDFPages)) -- ^ Reference to parent - !PDFRect -- ^ Media box - !(PDFReference PDFStream) -- ^ Reference to content - !(Maybe (PDFReference PDFResource)) -- ^ Reference to resources - !(Maybe PDFFloat) -- ^ Optional duration - !(Maybe PDFTransition) -- ^ Optional transition - ![AnyPdfObject] -- ^ Annotation array -#else -data PDFPage -#endif hunk ./Graphics/PDF/Pages.hs 87 -instance Show PDFPage where - show _ = "PDFPage" - --- | List of all pages -newtype Pages = Pages (PDFTree PDFPage) - --- | PDF Pages -#ifndef __HADDOCK__ -data PDFPages = PDFPages - !Int - !(Maybe (PDFReference PDFPages)) -- ^ Reference to parent - [Either (PDFReference PDFPages) (PDFReference PDFPage)] -#else -data PDFPages -#endif - --- | A PDF Transition -data PDFTransition = PDFTransition !PDFFloat !PDFTransStyle deriving(Eq) - --- | Dimension of a transition -data PDFTransDimension = Horizontal | Vertical deriving(Eq) - -instance Show PDFTransDimension where - show Horizontal = "H" - show Vertical = "V" - --- | Direction of a transition -data PDFTransDirection = Inward | Outward deriving(Eq) - -instance Show PDFTransDirection where - show Inward = "I" - show Outward = "O" - --- | Direction of a transition -data PDFTransDirection2 = LeftToRight - | BottomToTop -- ^ Wipe only - | RightToLeft -- ^ Wipe only - | TopToBottom - | TopLeftToBottomRight -- ^ Glitter only - deriving(Eq) hunk ./Graphics/PDF/Pages.hs 88 -floatDirection :: PDFTransDirection2 -> PDFFloat -floatDirection LeftToRight = 0 -floatDirection BottomToTop = 90 -floatDirection RightToLeft = 180 -floatDirection TopToBottom = 270 -floatDirection TopLeftToBottomRight = 315 - --- | Transition style -data PDFTransStyle = Split PDFTransDimension PDFTransDirection - | Blinds PDFTransDimension - | Box PDFTransDirection - | Wipe PDFTransDirection2 - | Dissolve - | Glitter PDFTransDirection2 - deriving(Eq) - -instance Show PDFTransStyle where - show (Split _ _) = "Split" - show (Blinds _) = "Blinds" - show (Box _) = "Box" - show (Wipe _) = "Wipe" - show (Dissolve) = "Dissolve" - show (Glitter _) = "Glitter" - -instance PdfObject PDFTransition where - toPDF (PDFTransition d t) = toPDF $ PDFDictionary. M.fromList $ - [ (PDFName "Type",AnyPdfObject (PDFName "Trans")) - , (PDFName "S",AnyPdfObject (PDFName (show t))) - , (PDFName "D",AnyPdfObject d) - ] ++ optionalDm t ++ optionalM t ++ optionalDi t - where - optionalDm (Split a _) = [ (PDFName "Dm",AnyPdfObject (PDFName (show a)))] - optionalDm (Blinds a) = [ (PDFName "Dm",AnyPdfObject (PDFName (show a)))] - optionalDm _ = [] - optionalM (Split _ a) = [ (PDFName "M",AnyPdfObject (PDFName (show a)))] - optionalM (Box a) = [ (PDFName "M",AnyPdfObject (PDFName (show a)))] - optionalM _ = [] - optionalDi (Wipe a) = [ (PDFName "Di",AnyPdfObject (floatDirection a))] - optionalDi (Glitter a) = [ (PDFName "Di",AnyPdfObject (floatDirection a))] - optionalDi _ = [] - --- PDF Pages hunk ./Graphics/PDF/Pages.hs 89 -instance PdfObject PDFPages where - toPDF (PDFPages c Nothing l) = toPDF $ PDFDictionary. M.fromList $ - [ (PDFName "Type",AnyPdfObject (PDFName "Pages")) - , (PDFName "Kids",AnyPdfObject $ map AnyPdfObject l) - , (PDFName "Count",AnyPdfObject . PDFInteger $ c) - ] - toPDF (PDFPages c (Just parent) l) = toPDF $ PDFDictionary. M.fromList $ - [ (PDFName "Type",AnyPdfObject (PDFName "Pages")) - , (PDFName "Parent",AnyPdfObject parent) - , (PDFName "Kids",AnyPdfObject $ map AnyPdfObject l) - , (PDFName "Count",AnyPdfObject . PDFInteger $ c) - ] hunk ./Graphics/PDF/Pages.hs 91 -instance PdfObject PDFPage where - toPDF (PDFPage (Just parent) box content rsrc d t annots) = toPDF $ PDFDictionary. M.fromList $ - [ (PDFName "Type",AnyPdfObject (PDFName "Page")) - , (PDFName "Parent",AnyPdfObject parent) - , (PDFName "MediaBox",AnyPdfObject box) - , (PDFName "Contents",AnyPdfObject content) - , if isJust rsrc - then - (PDFName "Resources",AnyPdfObject . fromJust $ rsrc) - else - (PDFName "Resources",AnyPdfObject emptyDictionary) - ] ++ (maybe [] (\x -> [(PDFName "Dur",AnyPdfObject x)]) d) - ++ (maybe [] (\x -> [(PDFName "Trans",AnyPdfObject x)]) t) - ++ ((\x -> if null x then [] else [(PDFName "Annots",AnyPdfObject x)]) annots) - toPDF (PDFPage Nothing _ _ _ _ _ _) = noPdfObject - - --- Main objects in a PDF document - - - - -instance PdfObject PDFCatalog where - toPDF (PDFCatalog outlines lPages pgMode pgLayout viewerPrefs) = toPDF $ PDFDictionary . M.fromList $ - [ (PDFName "Type",AnyPdfObject (PDFName "Catalog")) - , (PDFName "Pages",AnyPdfObject lPages) - , (PDFName "PageMode", AnyPdfObject . PDFName . show $ pgMode) - , (PDFName "PageLayout", AnyPdfObject . PDFName . show $ pgLayout) - , (PDFName "ViewerPreferences", AnyPdfObject viewerPrefs) - ] ++ (maybe [] (\x -> [(PDFName "Outlines",AnyPdfObject x)]) outlines) hunk ./Graphics/PDF/Pages.hs 153 -data PDFOutline = PDFOutline !(PDFReference PDFOutlineEntry) !(PDFReference PDFOutlineEntry) - -instance PdfObject PDFOutline where - toPDF (PDFOutline first last) = toPDF $ PDFDictionary. M.fromList $ [ - (PDFName "Type",AnyPdfObject . PDFName $ "Outlines") - , (PDFName "First",AnyPdfObject first) - , (PDFName "Last",AnyPdfObject last) - ] - -data OutlineStyle = Normal - | Italic - | Bold - deriving(Eq) - -data PDFOutlineEntry = PDFOutlineEntry !PDFString - !(PDFReference PDFOutlineEntry) -- Parent - !(Maybe (PDFReference PDFOutlineEntry)) -- Prev - !(Maybe (PDFReference PDFOutlineEntry)) -- Next - !(Maybe (PDFReference PDFOutlineEntry)) -- First - !(Maybe (PDFReference PDFOutlineEntry)) -- Last - Int -- Count of descendent (negative) - Destination - Color -- - OutlineStyle - -instance PdfObject OutlineStyle where - toPDF Normal = toPDF (PDFInteger 0) - toPDF Italic = toPDF (PDFInteger 1) - toPDF Bold = toPDF (PDFInteger 2) - -instance PdfObject PDFOutlineEntry where - toPDF (PDFOutlineEntry title parent prev next first last count dest color style) = - toPDF $ PDFDictionary. M.fromList $ [ - (PDFName "Title",AnyPdfObject title) - , (PDFName "Parent",AnyPdfObject parent) - ] - ++ - maybe [] (\x -> [(PDFName "Prev",AnyPdfObject x)]) prev - ++ - maybe [] (\x -> [(PDFName "Next",AnyPdfObject x)]) next - ++ - maybe [] (\x -> [(PDFName "First",AnyPdfObject x)]) first - ++ - maybe [] (\x -> [(PDFName "Last",AnyPdfObject x)]) last - ++ - [ (PDFName "Count",AnyPdfObject (PDFInteger count)) - , (PDFName "Dest",AnyPdfObject dest) - , (PDFName "C",AnyPdfObject color) - , (PDFName "F",AnyPdfObject style) - ] - -data Destination = Destination !(PDFReference PDFPage) deriving(Eq,Show) - -instance PdfObject Destination where - toPDF (Destination r) = toPDF [ AnyPdfObject r - , AnyPdfObject . PDFName $ "Fit" - ] - --- Outline types without a position pointer. The true outline is the derivative -type OutlineData = (PDFString,Maybe Color, Maybe OutlineStyle,Destination) -type Outline = OutlineLoc OutlineData - -data Tree a = Node a [Tree a] - -data OutlineCtx a = Top | Child { value :: a - , parent :: OutlineCtx a - , lefts :: [Tree a] - , rights :: [Tree a] - } - - -data OutlineLoc a = OutlineLoc (Tree a) (OutlineCtx a) - hunk ./Graphics/PDF/Pages.hs 247 + hunk ./Test/Penrose.hs 11 - -blue :: Color -blue = Rgb 0.8 0.8 1 - -green :: Color -green = Rgb 0.8 1 0.8 - -black :: Color -black = Rgb 0 0 0 hunk ./Test/test.hs 40 + hunk ./Test/test.hs 55 - Right jpg <- createPDFImage "logo.jpg" + Right jpg <- createPDFJpeg "logo.jpg" hunk ./Test/test.hs 60 - newAnnotation (Annotation (URLLink "http://www.alpheccar.org") [0,0,100,100] (toPDFString "Test")) + newAnnotation (URLLink (toPDFString "Test") [0,0,100,100] "http://www.alpheccar.org" True) hunk ./Test/test.hs 75 + createVideoObject "17.3gp" 50 50 (50+352) (50+288) hunk ./Graphics/PDF/Action.hs 16 - ActionType(..) - , Action(..) - , RenditionKind(..) + Action(..) + , MediaAction(..) + , GoToURL(..) + , ControlMedia(..) + , Rendition(..) hunk ./Graphics/PDF/Action.hs 27 -data Rendition = Rendition hunk ./Graphics/PDF/Action.hs 28 +-- | Media action +data MediaAction = Play + | Stop + | Pause + | Resume + deriving(Enum) + +class PdfObject a => Action a + +-- | Action to go to an URL +newtype GoToURL = GoToURL String + +data Rendition = Rendition hunk ./Graphics/PDF/Action.hs 42 - toPDF Rendition = noPdfObject + toPDF a = toPDF . PDFDictionary . M.fromList $ + [ (PDFName "Type",AnyPdfObject . PDFName $ "Rendition") + , (PDFName "S",AnyPdfObject . PDFName $ "MR") + , (PDFName "C",AnyPdfObject movie) + ] + where + movie = PDFDictionary . M.fromList $ + [ (PDFName "Type",AnyPdfObject . PDFName $ "MediaClip") + , (PDFName "S",AnyPdfObject . PDFName $ "MCD") + , (PDFName "CT",AnyPdfObject . toPDFString $ "video/3gpp") + , (PDFName "D",AnyPdfObject (toPDFString "/Users/cfavergeon/Documents/haskell_work/HPDF/Test/17.3gp")) + ] + +-- | Action to control a media +data ControlMedia = ControlMedia MediaAction Int (PDFReference Rendition) hunk ./Graphics/PDF/Action.hs 58 -data RenditionKind = Play - | Stop - | Pause - | Resume - deriving(Enum) +instance PdfObject GoToURL where + toPDF (GoToURL s) = toPDF . PDFDictionary . M.fromList $ + [ (PDFName "Type",AnyPdfObject . PDFName $ "Action") + , (PDFName "S",AnyPdfObject (PDFName "URI")) + , (PDFName "URI",AnyPdfObject (toPDFString s)) + ] +instance Action GoToURL hunk ./Graphics/PDF/Action.hs 66 -data ActionType = URI String - | SomeMedia RenditionKind Int Rendition hunk ./Graphics/PDF/Action.hs 67 -newtype Action = Action ActionType +instance PdfObject ControlMedia where + toPDF (ControlMedia operation relatedScreenAnnotation rendition) = toPDF . PDFDictionary . M.fromList $ + [ (PDFName "Type",AnyPdfObject . PDFName $ "Action") + , (PDFName "S",AnyPdfObject (PDFName "Rendition")) + , (PDFName "R",AnyPdfObject rendition) + , (PDFName "OP",AnyPdfObject . PDFInteger $ (fromEnum operation)) + , (PDFName "AN",AnyPdfObject $ (PDFReference relatedScreenAnnotation :: PDFReference AnyPdfObject)) + ] + +instance Action ControlMedia hunk ./Graphics/PDF/Action.hs 78 -actionFields :: ActionType -> [(PDFName,AnyPdfObject)] -actionFields (URI s) = [ (PDFName "S",AnyPdfObject (PDFName "URI")) - , (PDFName "URI",AnyPdfObject (toPDFString s)) - ] -actionFields (SomeMedia op an r) = [ (PDFName "S",AnyPdfObject (PDFName "Rendition")) - , (PDFName "R",AnyPdfObject r) - , (PDFName "OP",AnyPdfObject . PDFInteger $ (fromEnum op)) - , (PDFName "AN",AnyPdfObject $ (PDFReference an :: PDFReference AnyPdfObject)) - ] - -instance PdfObject Action where - toPDF (Action a) = toPDF . PDFDictionary . M.fromList $ - [(PDFName "Type",AnyPdfObject . PDFName $ "Action") - ] ++ actionFields a hunk ./Graphics/PDF/Annotation.hs 31 -import Graphics.PDF.Pages(addObject) +import Graphics.PDF.Pages hunk ./Graphics/PDF/Annotation.hs 46 -data Screen = Screen PDFString [PDFFloat] (PDFReference PDFPage) +data Screen = Screen (PDFReference Rendition) PDFString [PDFFloat] (PDFReference PDFPage) (Maybe (PDFReference ControlMedia)) (Maybe (PDFReference ControlMedia)) hunk ./Graphics/PDF/Annotation.hs 65 - toPDF a@(Screen _ _ p) = toPDF . PDFDictionary . M.fromList $ + toPDF a@(Screen _ _ _ p play stop) = toPDF . PDFDictionary . M.fromList $ hunk ./Graphics/PDF/Annotation.hs 67 + ++ (maybe [] (\x -> [(PDFName "A",AnyPdfObject x)]) play) + ++ (maybe [] (\x -> [(PDFName "AA",AnyPdfObject $ otherActions x)]) stop) + where + otherActions x = PDFDictionary . M.fromList $ [(PDFName "D",AnyPdfObject x)] hunk ./Graphics/PDF/Annotation.hs 73 - addAnnotation = addObject + addAnnotation (Screen video s rect p _ _) = do + r <- supply + playAction <- addObject $ ControlMedia Play r video + stopAction <- addObject $ ControlMedia Stop r video + updateObject (PDFReference r) $ Screen video s rect p (Just playAction) (Just playAction) + return $ PDFReference r hunk ./Graphics/PDF/Annotation.hs 80 - annotationContent (Screen s _ _) = s - annotationRect (Screen _ r _) = r + annotationContent (Screen _ s _ _ _ _) = s + annotationRect (Screen _ _ r _ _ _) = r hunk ./Graphics/PDF/Annotation.hs 96 - [ (PDFName "A",AnyPdfObject (Action (URI url))) + [ (PDFName "A",AnyPdfObject (GoToURL url)) hunk ./Graphics/PDF/Document.hs 22 - , setPageResource - , setPageAnnotations hunk ./Graphics/PDF/Document.hs 111 --- | Set page annotations -setPageAnnotations :: [AnyAnnotation] -> PDFReference PDFPage -> PDF () -setPageAnnotations an page = do - -- Get the page dictionary - lPages <- gets pages - -- Look for the page - let thePage = findPage page lPages - case thePage of - Nothing -> return () - -- If the page is found, get its stream reference and look for the stream - Just (PDFPage a b c d e f _) -> do - refs <- mapM (\x -> addAnnotation x >>= return . AnyPdfObject) an - modifyStrict $ \s -> s {pages = recordPage page (PDFPage a b c d e f refs) lPages} - --- | Set page resource -setPageResource :: PDFReference PDFResource -> PDFReference PDFPage -> PDF () -setPageResource newr page = do - -- Get the page dictionary - lPages <- gets pages - -- Look for the page - let thePage = findPage page lPages - case thePage of - Nothing -> return () - -- If the page is found, get its stream reference and look for the stream - Just (PDFPage a b c _ e f g) -> modifyStrict $ \s -> s {pages = recordPage page (PDFPage a b c (Just newr) e f g) lPages} hunk ./Graphics/PDF/Draw.hs 124 +#ifndef __HADDOCK__ hunk ./Graphics/PDF/Draw.hs 126 +#else +instance Monad Draw +instance MonadWriter B.ByteString Draw +instance MonadReader DrawEnvironment Draw +instance MonadState DrawState Draw +instance Functor Draw +#endif hunk ./Graphics/PDF/Draw.hs 307 -data PDFTransition = PDFTransition !PDFFloat !PDFTransStyle deriving(Eq) +data PDFTransition = PDFTransition !PDFFloat !PDFTransStyle + deriving(Eq) + hunk ./Graphics/PDF/Draw.hs 312 -data PDFTransDimension = Horizontal | Vertical deriving(Eq) +data PDFTransDimension = Horizontal | Vertical + deriving(Eq) + hunk ./Graphics/PDF/Draw.hs 335 - -- | The PDF Monad +-- | The PDF Monad hunk ./Graphics/PDF/Draw.hs 339 +#else +instance Functor PDF +instance Monad PDF +instance MonadState PdfState PDF +instance MonadIO PDF hunk ./Graphics/PDF/Draw.hs 355 - -- | Document metadata +-- | Document metadata hunk ./Graphics/PDF/Draw.hs 382 -data PDFViewerPreferences = PDFViewerPreferences { hideToolbar :: Bool - , hideMenuBar :: Bool - , hideWindowUI :: Bool - , fitWindow :: Bool - , centerWindow :: Bool - , displayDoctitle :: Bool - , nonFullScreenPageMode :: PDFDocumentPageMode +-- | Viewer preferences +data PDFViewerPreferences = PDFViewerPreferences { hideToolbar :: Bool -- ^ To hide the toolbar + , hideMenuBar :: Bool -- ^ To hide the menubar + , hideWindowUI :: Bool -- ^ To hide the window + , fitWindow :: Bool -- ^ Fit window to screen + , centerWindow :: Bool -- ^ Center window on screen + , displayDoctitle :: Bool -- ^ Display the docu,ent title + , nonFullScreenPageMode :: PDFDocumentPageMode -- ^ Display mode when exiting the full screen mode hunk ./Graphics/PDF/Draw.hs 554 +-- Degree for a transition direction hunk ./Graphics/PDF/Image.hs 105 -newtype FA a = FA {unFA :: ErrorT String PDF a} deriving(Monad,MonadError String,MonadIO,Functor) - +newtype FA a = FA {unFA :: ErrorT String PDF a} +#ifndef __HADDOCK__ + deriving(Monad,MonadError String,MonadIO,Functor) +#else +instance Monad FA +instance MonadError String FA +instance MonadIO FA +instance Functor FA +#endif + hunk ./Graphics/PDF/LowLevel/Types.hs 173 + +pdfDictUnion :: PDFDictionary -> PDFDictionary -> PDFDictionary +pdfDictUnion (PDFDictionary a) (PDFDictionary b) = PDFDictionary $ M.union a b + hunk ./Graphics/PDF/LowLevel/Types.hs 229 -pdfDictUnion :: PDFDictionary -> PDFDictionary -> PDFDictionary -pdfDictUnion (PDFDictionary a) (PDFDictionary b) = PDFDictionary $ M.union a b - hunk ./Graphics/PDF/Media.hs 17 - createVideoObject + drawVideo + , newVideo hunk ./Graphics/PDF/Media.hs 37 +import Graphics.PDF.Action hunk ./Graphics/PDF/Media.hs 39 +newVideo :: FilePath + -> PDF (PDFReference Rendition) +newVideo f = addObject Rendition hunk ./Graphics/PDF/Media.hs 43 - -createVideoObject :: FilePath - -> PDFFloat - -> PDFFloat - -> PDFFloat - -> PDFFloat - -> Draw () -createVideoObject f xa ya xb yb = do +drawVideo :: PDFReference Rendition + -> PDFFloat + -> PDFFloat + -> PDFFloat + -> PDFFloat + -> Draw () +drawVideo v xa ya xb yb = do hunk ./Graphics/PDF/Media.hs 53 - Just p -> newAnnotation $ Screen (toPDFString "Test") [xa,ya,xb,yb] (PDFReference p) + Just p -> newAnnotation $ Screen v (toPDFString "Test") [xa,ya,xb,yb] (PDFReference p) Nothing Nothing hunk ./Graphics/PDF/Pages.hs 33 + , setPageResource + , setPageAnnotations hunk ./Graphics/PDF/Pages.hs 48 +-- | Set page annotations +setPageAnnotations :: [AnyAnnotation] -> PDFReference PDFPage -> PDF () +setPageAnnotations an page = do + -- Get the page dictionary + lPages <- gets pages + -- Look for the page + let thePage = findPage page lPages + case thePage of + Nothing -> return () + -- If the page is found, get its stream reference and look for the stream + Just (PDFPage a b c d e f _) -> do + refs <- mapM (\x -> addAnnotation x >>= return . AnyPdfObject) an + modifyStrict $ \s -> s {pages = recordPage page (PDFPage a b c d e f refs) lPages} + +-- | Set page resource +setPageResource :: PDFReference PDFResource -> PDFReference PDFPage -> PDF () +setPageResource newr page = do + -- Get the page dictionary + lPages <- gets pages + -- Look for the page + let thePage = findPage page lPages + case thePage of + Nothing -> return () + -- If the page is found, get its stream reference and look for the stream + Just (PDFPage a b c _ e f g) -> modifyStrict $ \s -> s {pages = recordPage page (PDFPage a b c (Just newr) e f g) lPages} + hunk ./Graphics/PDF/Shapes.hs 17 - , Polygon hunk ./Graphics/PDF/Shapes.hs 20 - -- ** Polygons - , drawPolygon - , fillPolygon - , fillAndDrawPolygon + -- ** Paths + , beginPath + , closePath + , addBezierCubic + , addPolygonToPath + , addLineToPath + , strokePath + , fillPath + , fillAndStrokePath + , fillPathEO + , fillAndStrokePathEO + , endPath + , setAsClipPath + , setAsClipPathEO + -- ** Usual shapes + , Shape(..) + , Line(..) + , Rect(..) + , Polygon(..) + , Ellipse(..) hunk ./Graphics/PDF/Shapes.hs 44 +import Data.List(intersperse) + +class Shape a where + addShape :: a -> Draw () + draw :: a -> Draw () + fill :: a -> Draw () + fillAndStroke :: a -> Draw () + fillEO :: a -> Draw () + fillAndStrokeEO :: a -> Draw () + draw r = do + addShape r + strokePath + fill r = do + addShape r + fillPath + fillAndStroke r = do + addShape r + fillAndStrokePath + fillEO r = do + addShape r + fillPathEO + fillAndStrokeEO r = do + addShape r + fillAndStrokePathEO + +data Line = Line PDFFloat PDFFloat PDFFloat PDFFloat deriving(Eq) +instance Shape Line where + addShape (Line x0 y0 x1 y1)= do + moveto x0 y0 + lineto x1 y1 + endPath + fill _ = error "Can't fill a line !" + fillAndStroke _ = error "Can't fill a line !" + fillEO _ = error "Can't fill a line !" + fillAndStrokeEO _ = error "Can't fill a line !" + +data Rect = Rect PDFFloat PDFFloat PDFFloat PDFFloat deriving(Eq) +instance Shape Rect where + addShape (Rect x0 y0 x1 y1) = do + let poly = [(x0,y0),(x1,y0),(x1,y1),(x0,y1)] + beginPath x0 y0 + addPolygonToPath poly + closePath + +data Ellipse = Ellipse PDFFloat PDFFloat PDFFloat PDFFloat deriving(Eq) +instance Shape Ellipse where + addShape (Ellipse x0 y0 x1 y1) = do + let r2 = y1 - y0 + r1 = x1 - x0 + kappa = 0.5522847498 + beginPath 0 r2 + addBezierCubic (r1*kappa) r2 r1 (r2*kappa) r1 0 + addBezierCubic r1 ((-r2)*kappa) (kappa*r1) (-r2) 0 (-r2) + addBezierCubic ((-kappa)*r1) (-r2) (-r1) ((-kappa)*r2) (-r1) 0 + addBezierCubic (-r1) (kappa*r2) ((-kappa)*r1) (-r2) 0 r2 + endPath + + +newtype Polygon = Polygon [Point] +instance Shape Polygon where + addShape (Polygon l) = addPolygonToPath l + + +-- | Begin a new path at position x y +beginPath :: PDFFloat -- ^ Horizontal coordinate + -> PDFFloat -- ^ Vertical coordinate + -> Draw () +beginPath = moveto + +-- | Close current path +closePath :: Draw () +closePath = writeCmd $ "\nh" + +-- | End current path +endPath :: Draw () +endPath = writeCmd $ "\nn" + +-- | Append a cubic Bezier curve to the current path. The curve extends +-- from the current point to the point (x3 , y3 ), using (x1 , y1 ) and +-- (x2, y2) as the Bezier control points +addBezierCubic :: PDFFloat -- ^ x1 + -> PDFFloat -- ^ y1 + -> PDFFloat -- ^ x2 + -> PDFFloat -- ^ y2 + -> PDFFloat -- ^ x3 + -> PDFFloat -- ^ y3 + -> Draw () +addBezierCubic x1 y1 x2 y2 x3 y3 = writeCmd $ "\n" ++ (concat . intersperse " ". map show $ [x1,y1,x2,y2,x3,y3]) ++ " c" hunk ./Graphics/PDF/Shapes.hs 145 +-- | Add a line from current point to the one specified by lineto +addLineToPath :: PDFFloat -- ^ Horizontal coordinate + -> PDFFloat -- ^ Vertical coordinate + -> Draw () +addLineToPath x y = writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " l" + hunk ./Graphics/PDF/Shapes.hs 154 --- | A polygon -type Polygon = [Point] +-- | Add a polygon to current path +addPolygonToPath :: [Point] + -> Draw () +addPolygonToPath l = do + (uncurry moveto) . head $ l + mapM_ (\(x,y) -> writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " l") (tail l) + +-- | Draw current path +strokePath :: Draw () +strokePath = writeCmd "\nS" + +-- | Fill current path +fillPath :: Draw () +fillPath = writeCmd "\nf" + +-- | Fill current path +fillAndStrokePath :: Draw () +fillAndStrokePath = writeCmd "\nB" + +-- | Set clipping path +setAsClipPathEO :: Draw () +setAsClipPathEO = writeCmd "\nW" + +-- | Set clipping path +setAsClipPath :: Draw () +setAsClipPath = writeCmd "\nW*" + +-- | Fill current path using even odd rule +fillPathEO :: Draw () +fillPathEO = writeCmd "\nf*" hunk ./Graphics/PDF/Shapes.hs 185 --- | Close a polygon and draw it -drawPolygon :: Polygon -> Draw () -drawPolygon l = do - (uncurry moveto) . head $ l - mapM_ (\(x,y) -> writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " l") (tail l) - writeCmd " h S" +-- | Fill current path using even odd rule +fillAndStrokePathEO :: Draw () +fillAndStrokePathEO = writeCmd "\nB*" hunk ./Graphics/PDF/Shapes.hs 189 --- | Close a polygon and fill it -fillPolygon :: Polygon -> Draw () -fillPolygon l = do - (uncurry moveto) . head $ l - mapM_ (\(x,y) -> writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " l") (tail l) - writeCmd " h f" - --- | Close a polygon. Draw and fill it -fillAndDrawPolygon :: Polygon -> Draw () -fillAndDrawPolygon l = do - (uncurry moveto) . head $ l - mapM_ (\(x,y) -> writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " l") (tail l) - writeCmd " h B" hunk ./Graphics/PDF.hs 45 - -- ** Media - , module Graphics.PDF.Media hunk ./HPDF.cabal 21 + Graphics.PDF.Image + Graphics.PDF.Action + Graphics.PDF.Annotation + Graphics.PDF.Media hunk ./Test/Penrose.hs 15 +myBlue = Rgb 0.8 0.8 1 +myGreen = Rgb 0.8 1 0.8 + hunk ./Test/Penrose.hs 62 - fillColor blue - strokeColor blue + setFillAlpha 0.8 + fillColor myBlue + strokeColor myBlue hunk ./Test/Penrose.hs 69 - fillAndDrawPolygon pol + fillAndStroke (Polygon pol) hunk ./Test/Penrose.hs 71 - drawPolygon pol + draw (Polygon pol) hunk ./Test/Penrose.hs 82 - fillColor green - strokeColor green + setFillAlpha 0.8 + fillColor myGreen + strokeColor myGreen hunk ./Test/Penrose.hs 89 - fillAndDrawPolygon pol + fillAndStroke (Polygon pol) hunk ./Test/Penrose.hs 91 - drawPolygon pol + draw (Polygon pol) hunk ./Test/test.hs 54 - r <- createPDFXForm 0 0 200 200 draw + r <- createPDFXForm 0 0 200 200 myDrawing hunk ./Test/test.hs 74 - setFillAlpha 0.4 - createVideoObject "17.3gp" 50 50 (50+352) (50+288) + draw (Ellipse 0 0 300 100) hunk ./Test/test.hs 84 - draw = do - moveto 0 0 - lineto 100 100 - let poly = [(100,100),(200,100),(200,200),(100,200)] - fillPolygon poly - + myDrawing = do + draw (Line 0 0 100 100) + fill (Rect 100 100 200 200) + hunk ./Graphics/PDF/Shapes.hs 31 - , endPath hunk ./Graphics/PDF/Shapes.hs 38 + , Arc(..) hunk ./Graphics/PDF/Shapes.hs 40 + , Circle(..) hunk ./Graphics/PDF/Shapes.hs 75 - endPath hunk ./Graphics/PDF/Shapes.hs 86 - closePath - + +data Arc = Arc PDFFloat PDFFloat PDFFloat PDFFloat deriving(Eq) +instance Shape Arc where + addShape (Arc x0 y0 x1 y1) = do + let height = y1 - y0 + width = x1 - x0 + kappa = 0.5522847498 + beginPath x0 y0 + addBezierCubic (x0+width*kappa) y0 x1 (y1-height*kappa) x1 y1 + hunk ./Graphics/PDF/Shapes.hs 99 - let r2 = y1 - y0 - r1 = x1 - x0 - kappa = 0.5522847498 - beginPath 0 r2 - addBezierCubic (r1*kappa) r2 r1 (r2*kappa) r1 0 - addBezierCubic r1 ((-r2)*kappa) (kappa*r1) (-r2) 0 (-r2) - addBezierCubic ((-kappa)*r1) (-r2) (-r1) ((-kappa)*r2) (-r1) 0 - addBezierCubic (-r1) (kappa*r2) ((-kappa)*r1) (-r2) 0 r2 - endPath - + let xm = (x0+x1)/2.0 + ym = (y0+y1)/2.0 + k = 0.5522847498 + h = k*(abs (y1 - y0)/2.0) + w = k*(abs (x1 - x0)/2.0) + + beginPath xm y0 + addBezierCubic (xm + w) y0 x1 (ym - h) x1 ym + addBezierCubic x1 (ym + h) (xm + w) y1 xm y1 + addBezierCubic (xm - w) y1 x0 (ym + h) x0 ym + addBezierCubic x0 (ym - h) (xm - w) y0 xm y0 hunk ./Graphics/PDF/Shapes.hs 111 +data Circle = Circle PDFFloat PDFFloat PDFFloat deriving(Eq) +instance Shape Circle where + addShape (Circle x0 y0 r) = draw (Ellipse (x0-r/2.0) (y0-r/2.0) (x0+r/2.0) (y0+r/2.0) ) + hunk ./Graphics/PDF/Shapes.hs 130 --- | End current path -endPath :: Draw () -endPath = writeCmd $ "\nn" hunk ./Graphics/PDF/Shapes.hs 185 -setAsClipPathEO = writeCmd "\nW" +setAsClipPathEO = writeCmd "\nW n" hunk ./Graphics/PDF/Shapes.hs 189 -setAsClipPath = writeCmd "\nW*" +setAsClipPath = writeCmd "\nW* n" hunk ./Test/test.hs 74 - draw (Ellipse 0 0 300 100) + --draw (Rect 0 0 300 100) + draw (Circle 100 100 100) hunk ./Graphics/PDF/Shapes.hs 41 + , RoundRectangle(..) + -- ** Style + , CapStyle(..) + , JoinStyle(..) + , DashPattern(..) + , setWidth + , setLineCap + , setLineJoin + , setDash + , setNoDash + , setMiterLimit hunk ./Graphics/PDF/Shapes.hs 121 + +data RoundRectangle = RoundRectangle PDFFloat PDFFloat PDFFloat PDFFloat PDFFloat PDFFloat deriving(Eq) +instance Shape RoundRectangle where + addShape (RoundRectangle rw rh x0 y0 x1 y1) = do + let k = 0.5522847498 + h = k*rw + w = k*rh + + beginPath (x0+rw) y0 + addLineToPath (x1-rw) y0 + addBezierCubic ((x1-rw) + w) y0 x1 (y0+rh - h) x1 (y0+rh) + addLineToPath x1 (y1-rh) + addBezierCubic x1 ((y1-rh) + h) (x1-rw + w) y1 (x1-rw) y1 + addLineToPath (x0+rw) y1 + addBezierCubic (x0 + rw - w) y1 x0 (y1-rh + h) x0 (y1-rh) + addLineToPath x0 (y0+rh) + addBezierCubic x0 (y0 + rh - h) (x0 + rw - w) y0 (x0 + rw) y0 + addLineToPath (x1-rw) y0 hunk ./Graphics/PDF/Shapes.hs 149 +-- | Set pen width +setWidth :: PDFFloat -> Draw () +setWidth w = writeCmd $ "\n " ++ (show w) ++ " w" + +-- | Set pen width +setMiterLimit :: PDFFloat -> Draw () +setMiterLimit w = writeCmd $ "\n " ++ (show w) ++ " M" + +-- | Line cap styles +data CapStyle = ButtCap + | RoundCap + | SquareCap + deriving(Eq,Enum) + +-- | Line join styles +data JoinStyle = MilterJoin + | RoundJoin + | BevelJoin + deriving(Eq,Enum) + +-- | Set line cap +setLineCap :: CapStyle -> Draw () +setLineCap w = writeCmd $ "\n " ++ (show . fromEnum $ w) ++ " J" + +-- | Set line join +setLineJoin :: JoinStyle -> Draw () +setLineJoin w = writeCmd $ "\n " ++ (show . fromEnum $ w) ++ " j" + +data DashPattern = DashPattern ![PDFFloat] PDFFloat deriving(Eq) + +-- | Set the dash pattern +setDash :: DashPattern -> Draw() +setDash (DashPattern a p) = writeCmd $ "\n " ++ show a ++ " " ++ (show p) ++ " d" + +-- | No dash pattern +setNoDash :: Draw () +setNoDash = setDash (DashPattern [] 0) + hunk ./Test/test.hs 75 - draw (Circle 100 100 100) + setWidth 2 + setDash $ DashPattern [3] 0 + draw (RoundRectangle 32 16 0 0 300 200) hunk ./Graphics/PDF.hs 45 + -- ** Patterns + , module Graphics.PDF.Pattern hunk ./Graphics/PDF.hs 49 -import Graphics.PDF.Media +import Graphics.PDF.Pattern hunk ./Graphics/PDF/Document.hs 57 -createPDFXForm :: Int -- ^ Left - -> Int -- ^ Bottom - -> Int -- ^ Right - -> Int -- ^ Top +createPDFXForm :: PDFFloat -- ^ Left + -> PDFFloat -- ^ Bottom + -> PDFFloat -- ^ Right + -> PDFFloat -- ^ Top hunk ./Graphics/PDF/Document.hs 68 - , (PDFName "BBox",AnyPdfObject . (map (AnyPdfObject . PDFInteger)) $ [xa,ya,xb,yb]) + , (PDFName "BBox",AnyPdfObject . (map AnyPdfObject) $ [xa,ya,xb,yb]) hunk ./Graphics/PDF/Draw.hs 109 + , patterns :: M.Map (PDFReference AnyPdfPattern) String + , colorSpaces :: M.Map PDFColorSpace String hunk ./Graphics/PDF/Draw.hs 114 - , xobjectb :: IM.IntMap (Int,Int) + , xobjectb :: IM.IntMap (PDFFloat,PDFFloat) hunk ./Graphics/PDF/Draw.hs 184 - emptyDictionary [] + emptyDictionary [] M.empty M.empty hunk ./Graphics/PDF/Draw.hs 214 - bounds :: PDFReference a -> Draw (Int,Int) + bounds :: PDFReference a -> Draw (PDFFloat,PDFFloat) hunk ./Graphics/PDF/Draw.hs 246 - -> Draw (Int,Int) + -> Draw (PDFFloat,PDFFloat) hunk ./Graphics/PDF/Draw.hs 249 - return $ IM.findWithDefault (0,0) ref bounds + return $ IM.findWithDefault (0.0,0.0) ref bounds hunk ./Graphics/PDF/Draw.hs 275 - , xobjectBound :: !(IM.IntMap (Int,Int)) -- ^ Width and height of xobjects + , xobjectBound :: !(IM.IntMap (PDFFloat,PDFFloat)) -- ^ Width and height of xobjects hunk ./Graphics/PDF/Image.hs 171 -analyzeJpeg :: Handle -> FA (Int,Int,Int,Int) +analyzeJpeg :: Handle -> FA (Int,PDFFloat,PDFFloat,Int) hunk ./Graphics/PDF/Image.hs 195 - return (bits_per_component,height,width,color_space) + return (bits_per_component,(fromIntegral height),(fromIntegral width),color_space) hunk ./Graphics/PDF/Image.hs 225 - , (PDFName "Width",AnyPdfObject . PDFInteger $ width) - , (PDFName "Height",AnyPdfObject . PDFInteger $ height) + , (PDFName "Width",AnyPdfObject width) + , (PDFName "Height",AnyPdfObject height) hunk ./Graphics/PDF/Image.hs 238 - applyMatrix (scale (fromIntegral width) (fromIntegral height)) + applyMatrix (scale width height) hunk ./Graphics/PDF/Pages.hs 270 - -> Int -- ^ Width - -> Int -- ^ Height + -> PDFFloat -- ^ Width + -> PDFFloat -- ^ Height addfile ./Graphics/PDF/Pattern.hs hunk ./Graphics/PDF/Pattern.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- PDF Patterns +--------------------------------------------------------- + +module Graphics.PDF.Pattern( + -- * Pattern + TilingType(..) + , PDFColoredPattern + , PDFUncoloredPattern + , createColoredTiling + , createUncoloredTiling + , setFillPattern + , setStrokePattern + , setUncoloredFillPattern + , setUncoloredStrokePattern + ) where + +import Graphics.PDF.LowLevel.Types +import Graphics.PDF.Draw +import Graphics.PDF.Resources +import qualified Data.Map as M +import Graphics.PDF.Pages(recordBound,createContent) +import Control.Monad.State + +data PaintType = ColoredTiling + | UncoloredTiling + deriving(Eq,Enum) + +-- | Tiling type +data TilingType = ConstantSpacing + | NoDistortion + | ConstantSpacingAndFaster + deriving(Eq,Enum) + +-- | Create a colored tiling pattern +createColoredTiling :: PDFFloat -- ^ Left + -> PDFFloat -- ^ Bottom + -> PDFFloat -- ^ Right + -> PDFFloat -- ^ Top + -> PDFFloat -- ^ Horizontal step + -> PDFFloat -- ^ Vertical step + -> TilingType + -> Draw a -- ^ Drawing commands + -> PDF (PDFReference PDFColoredPattern) +createColoredTiling xa ya xb yb hstep vstep tt d = createTilingPattern xa ya xb yb hstep vstep ColoredTiling tt d >>= return . PDFReference + + -- | Create an uncolored tiling pattern +createUncoloredTiling :: PDFFloat -- ^ Left + -> PDFFloat -- ^ Bottom + -> PDFFloat -- ^ Right + -> PDFFloat -- ^ Top + -> PDFFloat -- ^ Horizontal step + -> PDFFloat -- ^ Vertical step + -> TilingType + -> Draw a -- ^ Drawing commands + -> PDF (PDFReference PDFUncoloredPattern) +createUncoloredTiling xa ya xb yb hstep vstep tt d = createTilingPattern xa ya xb yb hstep vstep UncoloredTiling tt d >>= return . PDFReference + +-- | Create a PDF tiling pattern +createTilingPattern :: PDFFloat -- ^ Left + -> PDFFloat -- ^ Bottom + -> PDFFloat -- ^ Right + -> PDFFloat -- ^ Top + -> PDFFloat -- ^ Horizontal step + -> PDFFloat -- ^ Vertical step + -> PaintType + -> TilingType + -> Draw a -- ^ Drawing commands + -> PDF Int +createTilingPattern xa ya xb yb hstep vstep pt tt d = + let a' = do modifyStrict $ \s -> s {otherRsrcs = PDFDictionary. M.fromList $ + [ (PDFName "Type",AnyPdfObject . PDFName $ "Pattern") + , (PDFName "PatternType",AnyPdfObject . PDFInteger $ 1) + , (PDFName "PaintType",AnyPdfObject . PDFInteger $ (fromEnum pt) + 1) + , (PDFName "TilingType",AnyPdfObject . PDFInteger $ (fromEnum tt) + 1) + , (PDFName "Matrix",AnyPdfObject . (map (AnyPdfObject . PDFInteger)) $ [1,0,0,1,0,0]) + , (PDFName "BBox",AnyPdfObject . map AnyPdfObject $ [xa,ya,xb,yb]) + , (PDFName "XStep",AnyPdfObject hstep) + , (PDFName "YStep",AnyPdfObject vstep) + ] + } + d + in do + PDFReference s <- createContent a' Nothing + recordBound s (xb-xa) (yb-ya) + return s + + +-- | Set the fill pattern +setFillPattern :: PDFReference PDFColoredPattern -> Draw () +setFillPattern (PDFReference a) = do + patternMap <- gets patterns + (newName,newMap) <- setResource "Pattern" (PDFReference a) patternMap + modifyStrict $ \s -> s { patterns = newMap } + writeCmd ("\n/Pattern cs") + writeCmd ("\n/" ++ newName ++ " scn") + +-- | Set the stroke pattern +setStrokePattern :: PDFReference PDFColoredPattern -> Draw () +setStrokePattern (PDFReference a) = do + patternMap <- gets patterns + (newName,newMap) <- setResource "Pattern" (PDFReference a) patternMap + modifyStrict $ \s -> s { patterns = newMap } + writeCmd ("\n/Pattern CS") + writeCmd ("\n/" ++ newName ++ " SCN") + + +getRgbColor :: Color -> (PDFFloat,PDFFloat,PDFFloat) +getRgbColor (Rgb r g b) = (PDFFloat r,PDFFloat g,PDFFloat b) +getRgbColor (Hsv h s v) = let (r,g,b) = hsvToRgb (h,s,v) in (PDFFloat r,PDFFloat g,PDFFloat b) + +-- | Set the fill pattern +setUncoloredFillPattern :: PDFReference PDFUncoloredPattern -> Color -> Draw () +setUncoloredFillPattern (PDFReference a) col = do + let (r,g,b) = getRgbColor col + colorMap <- gets colorSpaces + (newColorName,newColorMap) <- setResource "ColorSpace" PatternRGB colorMap + patternMap <- gets patterns + (newName,newMap) <- setResource "Pattern" (PDFReference a) patternMap + modifyStrict $ \s -> s { patterns = newMap } + writeCmd ("\n/" ++ newColorName ++ " cs") + writeCmd ("\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " /" ++ newName ++ " scn") + +-- | Set the stroke pattern +setUncoloredStrokePattern :: PDFReference PDFUncoloredPattern -> Color -> Draw () +setUncoloredStrokePattern (PDFReference a) col = do + let (r,g,b) = getRgbColor col + colorMap <- gets colorSpaces + (newColorName,newColorMap) <- setResource "ColorSpace" PatternRGB colorMap + patternMap <- gets patterns + (newName,newMap) <- setResource "Pattern" (PDFReference a) patternMap + modifyStrict $ \s -> s { patterns = newMap } + writeCmd ("\n/" ++ newColorName ++ " CS") + writeCmd ("\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " /" ++ newName ++ " SCN") hunk ./Graphics/PDF/Resources.hs 25 + , PDFColoredPattern + , PDFUncoloredPattern + , AnyPdfPattern(..) + , PDFColorSpace(..) hunk ./Graphics/PDF/Resources.hs 128 + +-- | A PDF Pattern +data PDFUncoloredPattern +data PDFColoredPattern +data AnyPdfPattern + + +-- | A PDF Color space +data PDFColorSpace = PatternRGB deriving(Eq,Ord) + +instance PdfResourceObject PDFColorSpace where + toRsrc PatternRGB = AnyPdfObject . map AnyPdfObject $ [PDFName "Pattern",PDFName "DeviceRGB"] + +instance PdfObject PDFColoredPattern where + toPDF _ = noPdfObject +instance PdfResourceObject (PDFReference PDFColoredPattern) where + toRsrc = AnyPdfObject + +instance PdfObject PDFUncoloredPattern where + toPDF _ = noPdfObject +instance PdfResourceObject (PDFReference PDFUncoloredPattern) where + toRsrc = AnyPdfObject + +instance PdfObject AnyPdfPattern where + toPDF _ = noPdfObject +instance PdfResourceObject (PDFReference AnyPdfPattern) where + toRsrc = AnyPdfObject + hunk ./Graphics/PDF/Shapes.hs 36 - , Rect(..) + , Rectangle(..) hunk ./Graphics/PDF/Shapes.hs 60 - draw :: a -> Draw () + stroke :: a -> Draw () hunk ./Graphics/PDF/Shapes.hs 65 - draw r = do + stroke r = do hunk ./Graphics/PDF/Shapes.hs 91 -data Rect = Rect PDFFloat PDFFloat PDFFloat PDFFloat deriving(Eq) -instance Shape Rect where - addShape (Rect x0 y0 x1 y1) = do +data Rectangle = Rectangle PDFFloat PDFFloat PDFFloat PDFFloat deriving(Eq) +instance Shape Rectangle where + addShape (Rectangle x0 y0 x1 y1) = do hunk ./Graphics/PDF/Shapes.hs 142 - addShape (Circle x0 y0 r) = draw (Ellipse (x0-r/2.0) (y0-r/2.0) (x0+r/2.0) (y0+r/2.0) ) + addShape (Circle x0 y0 r) = stroke (Ellipse (x0-r/2.0) (y0-r/2.0) (x0+r/2.0) (y0+r/2.0) ) hunk ./HPDF.cabal 24 - Graphics.PDF.Media + Graphics.PDF.Pattern hunk ./Test/Penrose.hs 71 - draw (Polygon pol) + stroke (Polygon pol) hunk ./Test/Penrose.hs 91 - draw (Polygon pol) + stroke (Polygon pol) hunk ./Test/test.hs 55 + p <- createUncoloredTiling 0 0 100 50 100 50 ConstantSpacing pattern hunk ./Test/test.hs 78 - draw (RoundRectangle 32 16 0 0 300 200) + stroke (RoundRectangle 32 16 0 0 300 200) + setUncoloredFillPattern p (Rgb 1 0 0) + fill (Rectangle 0 0 600 600) hunk ./Test/test.hs 91 - draw (Line 0 0 100 100) - fill (Rect 100 100 200 200) + stroke (Line 0 0 100 100) + fill (Rectangle 100 100 200 200) + pattern = do + stroke (Ellipse 0 0 100 50) hunk ./Graphics/PDF.hs 47 + -- ** Shading + , module Graphics.PDF.Shading hunk ./Graphics/PDF.hs 51 +import Graphics.PDF.Shading hunk ./Graphics/PDF.hs 99 + -- We DO NOT check any more if the resource is empty because Pattern streams NEED a resource entry even if + -- the resource dictionary is empty. Otherwise, they are not displayed in acrobat reader althought they are in Apple preview. hunk ./Graphics/PDF.hs 102 - resources <- if emptyResource (rsrc state') - then do - case p of - -- Not linked to a page - -- otherResource are entries specific to a special stream (like an XObject) so we return empty for a page - Nothing -> return (otherRsrcs state') - -- Linked to a page - Just pageRef -> do - setPageAnnotations (annots state') pageRef - return emptyDictionary - -- Some resource are needed by the stream - else do + --resources <- if emptyResource (rsrc state') + -- then do + -- case p of + -- -- Not linked to a page + -- -- otherResource are entries specific to a special stream (like an XObject) so we return empty for a page + -- Nothing -> return (otherRsrcs state') + -- -- Linked to a page + -- Just pageRef -> do + -- setPageAnnotations (annots state') pageRef + -- return emptyDictionary + -- -- Some resource are needed by the stream + -- else do + resources <- do hunk ./Graphics/PDF/Draw.hs 64 + , PDFShading(..) + , getRgbColor hunk ./Graphics/PDF/Draw.hs 101 + deriving(Eq,Ord) hunk ./Graphics/PDF/Draw.hs 114 + , shadings :: M.Map PDFShading String hunk ./Graphics/PDF/Draw.hs 188 - emptyDictionary [] M.empty M.empty + emptyDictionary [] M.empty M.empty M.empty hunk ./Graphics/PDF/Draw.hs 584 + +getRgbColor :: Color -> (PDFFloat,PDFFloat,PDFFloat) +getRgbColor (Rgb r g b) = (PDFFloat r,PDFFloat g,PDFFloat b) +getRgbColor (Hsv h s v) = let (r,g,b) = hsvToRgb (h,s,v) in (PDFFloat r,PDFFloat g,PDFFloat b) + +-- | Interpolation function +interpole :: Int -> PDFFloat -> PDFFloat -> AnyPdfObject +interpole n x y = AnyPdfObject . PDFDictionary . M.fromList $ + [ (PDFName "FunctionType", AnyPdfObject . PDFInteger $ 2) + , (PDFName "Domain", AnyPdfObject . map AnyPdfObject $ [PDFFloat 0,PDFFloat 1]) + , (PDFName "C0", AnyPdfObject . map AnyPdfObject $ [x]) + , (PDFName "C1", AnyPdfObject . map AnyPdfObject $ [y]) + , (PDFName "N", AnyPdfObject . PDFInteger $ n) + ] + +-- | A shading +data PDFShading = AxialShading PDFFloat PDFFloat PDFFloat PDFFloat Color Color + | RadialShading PDFFloat PDFFloat PDFFloat PDFFloat PDFFloat PDFFloat Color Color + deriving(Eq,Ord) + +instance PdfResourceObject PDFShading where + toRsrc (AxialShading x0 y0 x1 y1 ca cb) = AnyPdfObject . PDFDictionary . M.fromList $ + [ (PDFName "ShadingType",AnyPdfObject . PDFInteger $ 2) + , (PDFName "Coords",AnyPdfObject . map AnyPdfObject $ [x0,y0,x1,y1]) + , (PDFName "ColorSpace",AnyPdfObject . PDFName $ "DeviceRGB") + , (PDFName "Function",AnyPdfObject $ [interpole 1 ra rb,interpole 1 ga gb,interpole 1 ba bb]) + ] + where + (ra,ga,ba) = getRgbColor ca + (rb,gb,bb) = getRgbColor cb + toRsrc (RadialShading x0 y0 r0 x1 y1 r1 ca cb) = AnyPdfObject . PDFDictionary . M.fromList $ + [ (PDFName "ShadingType",AnyPdfObject . PDFInteger $ 3) + , (PDFName "Coords",AnyPdfObject . map AnyPdfObject $ [x0,y0,r0,x1,y1,r1]) + , (PDFName "ColorSpace",AnyPdfObject . PDFName $ "DeviceRGB") + , (PDFName "Function",AnyPdfObject $ [interpole 1 ra rb,interpole 1 ga gb,interpole 1 ba bb]) + ] + where + (ra,ga,ba) = getRgbColor ca + (rb,gb,bb) = getRgbColor cb hunk ./Graphics/PDF/Pattern.hs 20 - , setFillPattern - , setStrokePattern + , setColoredFillPattern + , setColoredStrokePattern hunk ./Graphics/PDF/Pattern.hs 98 -setFillPattern :: PDFReference PDFColoredPattern -> Draw () -setFillPattern (PDFReference a) = do +setColoredFillPattern :: PDFReference PDFColoredPattern -> Draw () +setColoredFillPattern (PDFReference a) = do hunk ./Graphics/PDF/Pattern.hs 107 -setStrokePattern :: PDFReference PDFColoredPattern -> Draw () -setStrokePattern (PDFReference a) = do +setColoredStrokePattern :: PDFReference PDFColoredPattern -> Draw () +setColoredStrokePattern (PDFReference a) = do hunk ./Graphics/PDF/Pattern.hs 116 -getRgbColor :: Color -> (PDFFloat,PDFFloat,PDFFloat) -getRgbColor (Rgb r g b) = (PDFFloat r,PDFFloat g,PDFFloat b) -getRgbColor (Hsv h s v) = let (r,g,b) = hsvToRgb (h,s,v) in (PDFFloat r,PDFFloat g,PDFFloat b) hunk ./Graphics/PDF/Resources.hs 23 - , PdfResourceObject(..) hunk ./Graphics/PDF/Resources.hs 128 + hunk ./Graphics/PDF/Resources.hs 156 + + addfile ./Graphics/PDF/Shading.hs hunk ./Graphics/PDF/Shading.hs 1 - +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- PDF shading +--------------------------------------------------------- +module Graphics.PDF.Shading( + -- * Shading + -- ** Type + PDFShading(..) + , paintWithShading + ) where + +import Graphics.PDF.Draw +import Graphics.PDF.LowLevel.Types +import Control.Monad.State(gets) +import Graphics.PDF.Resources +import Graphics.PDF.Shapes(setAsClipPath) + +-- | Set alpha value for transparency +applyShading :: PDFShading -> Draw () +applyShading shade = do + shadingMap <- gets shadings + (newName,newMap) <- setResource "Shading" shade shadingMap + modifyStrict $ \s -> s { shadings = newMap } + writeCmd ("\n/" ++ newName ++ " sh") + +paintWithShading :: PDFShading -- ^ Shading + -> Draw a -- ^ Shape to paint + -> Draw () +paintWithShading shade d = do + withNewContext $ do + d + setAsClipPath + applyShading shade hunk ./Graphics/PDF/Shapes.hs 252 -setAsClipPathEO = writeCmd "\nW n" +setAsClipPathEO = writeCmd "\nW* n" hunk ./Graphics/PDF/Shapes.hs 256 -setAsClipPath = writeCmd "\nW* n" +setAsClipPath = writeCmd "\nW n" hunk ./HPDF.cabal 25 + Graphics.PDF.Shading hunk ./Test/test.hs 56 + cp <- createColoredTiling 0 0 100 50 100 50 ConstantSpacing cpattern hunk ./Test/test.hs 80 - setUncoloredFillPattern p (Rgb 1 0 0) - fill (Rectangle 0 0 600 600) + --setUncoloredFillPattern p (Rgb 1 0 0) + --setColoredFillPattern cp + paintWithShading (RadialShading 0 0 50 0 0 600 (Rgb 1 0 0) (Rgb 0 0 1)) (addShape $ Rectangle 0 0 300 300) + stroke $ Rectangle 0 0 300 300 hunk ./Test/test.hs 98 + cpattern = do + strokeColor (Rgb 0 0 1) + stroke (Ellipse 0 0 100 50) hunk ./Graphics/PDF/Action.hs 17 - , MediaAction(..) hunk ./Graphics/PDF/Action.hs 18 - , ControlMedia(..) - , Rendition(..) hunk ./Graphics/PDF/Action.hs 49 - , (PDFName "D",AnyPdfObject (toPDFString "/Users/cfavergeon/Documents/haskell_work/HPDF/Test/17.3gp")) + , (PDFName "D",AnyPdfObject (toPDFString "17.3gp")) hunk ./Graphics/PDF/Annotation.hs 19 - , Screen(..) hunk ./Graphics/PDF/Annotation.hs 45 -data Screen = Screen (PDFReference Rendition) PDFString [PDFFloat] (PDFReference PDFPage) (Maybe (PDFReference ControlMedia)) (Maybe (PDFReference ControlMedia)) +--data Screen = Screen (PDFReference Rendition) PDFString [PDFFloat] (PDFReference PDFPage) (Maybe (PDFReference ControlMedia)) (Maybe (PDFReference ControlMedia)) hunk ./Graphics/PDF/Annotation.hs 63 -instance PdfObject Screen where - toPDF a@(Screen _ _ _ p play stop) = toPDF . PDFDictionary . M.fromList $ - standardAnnotationDict a ++ [(PDFName "P",AnyPdfObject p)] - ++ (maybe [] (\x -> [(PDFName "A",AnyPdfObject x)]) play) - ++ (maybe [] (\x -> [(PDFName "AA",AnyPdfObject $ otherActions x)]) stop) - where - otherActions x = PDFDictionary . M.fromList $ [(PDFName "D",AnyPdfObject x)] - -instance AnnotationObject Screen where - addAnnotation (Screen video s rect p _ _) = do - r <- supply - playAction <- addObject $ ControlMedia Play r video - stopAction <- addObject $ ControlMedia Stop r video - updateObject (PDFReference r) $ Screen video s rect p (Just playAction) (Just playAction) - return $ PDFReference r - annotationType _ = PDFName "Screen" - annotationContent (Screen _ s _ _ _ _) = s - annotationRect (Screen _ _ r _ _ _) = r +--instance PdfObject Screen where +-- toPDF a@(Screen _ _ _ p play stop) = toPDF . PDFDictionary . M.fromList $ +-- standardAnnotationDict a ++ [(PDFName "P",AnyPdfObject p)] +-- ++ (maybe [] (\x -> [(PDFName "A",AnyPdfObject x)]) play) +-- ++ (maybe [] (\x -> [(PDFName "AA",AnyPdfObject $ otherActions x)]) stop) +-- where +-- otherActions x = PDFDictionary . M.fromList $ [(PDFName "D",AnyPdfObject x)] +-- +--instance AnnotationObject Screen where +-- addAnnotation (Screen video s rect p _ _) = do +-- r <- supply +-- playAction <- addObject $ ControlMedia Play r video +-- stopAction <- addObject $ ControlMedia Stop r video +-- updateObject (PDFReference r) $ Screen video s rect p (Just playAction) (Just playAction) +-- return $ PDFReference r +-- annotationType _ = PDFName "Screen" +-- annotationContent (Screen _ s _ _ _ _) = s +-- annotationRect (Screen _ _ r _ _ _) = r hunk ./Graphics/PDF/Colors.hs 77 -fillColor :: Color -- ^ Filling color - -> Draw () +fillColor :: MonadPath m => Color -- ^ Filling color + -> m () hunk ./Graphics/PDF/Colors.hs 86 -strokeColor :: Color -- ^ Drawing color - -> Draw () +strokeColor :: MonadPath m => Color -- ^ Drawing color + -> m () hunk ./Graphics/PDF/Coordinates.hs 17 - , Matrix + , Matrix(..) hunk ./Graphics/PDF/Draw.hs 24 - , writeString hunk ./Graphics/PDF/Draw.hs 139 +instance MonadPath Draw + hunk ./Graphics/PDF/Draw.hs 167 -writeCmd :: String -> Draw () +writeCmd :: (MonadWriter B.ByteString m) => String -> m () hunk ./Graphics/PDF/Draw.hs 170 --- | Write a PDF string object to the drawing -writeString :: PDFString -> Draw () -writeString = tell . toPDF - hunk ./Graphics/PDF/Image.hs 225 - , (PDFName "Width",AnyPdfObject width) - , (PDFName "Height",AnyPdfObject height) + , (PDFName "Width",AnyPdfObject . PDFInteger $ round width) + , (PDFName "Height",AnyPdfObject . PDFInteger $ round height) hunk ./Graphics/PDF/LowLevel/Types.hs 22 +import Control.Monad.Writer hunk ./Graphics/PDF/LowLevel/Types.hs 230 - +-- | A monad where path can be created +class MonadWriter B.ByteString m => MonadPath m hunk ./Graphics/PDF/Pattern.hs 55 - -- | Create an uncolored tiling pattern +-- | Create an uncolored tiling pattern hunk ./Graphics/PDF/Shapes.hs 95 - beginPath x0 y0 hunk ./Graphics/PDF/Shapes.hs 96 + closePath hunk ./Graphics/PDF/Shapes.hs 142 - addShape (Circle x0 y0 r) = stroke (Ellipse (x0-r/2.0) (y0-r/2.0) (x0+r/2.0) (y0+r/2.0) ) + addShape (Circle x0 y0 r) = stroke (Ellipse (x0-r) (y0-r) (x0+r) (y0+r) ) hunk ./Graphics/PDF/Shapes.hs 150 -setWidth :: PDFFloat -> Draw () +setWidth :: MonadPath m => PDFFloat -> m () hunk ./Graphics/PDF/Shapes.hs 154 -setMiterLimit :: PDFFloat -> Draw () +setMiterLimit :: MonadPath m => PDFFloat -> m () hunk ./Graphics/PDF/Shapes.hs 170 -setLineCap :: CapStyle -> Draw () +setLineCap :: MonadPath m => CapStyle -> m () hunk ./Graphics/PDF/Shapes.hs 174 -setLineJoin :: JoinStyle -> Draw () +setLineJoin :: MonadPath m => JoinStyle -> m () hunk ./Graphics/PDF/Shapes.hs 180 -setDash :: DashPattern -> Draw() +setDash :: MonadPath m => DashPattern -> m() hunk ./Graphics/PDF/Shapes.hs 184 -setNoDash :: Draw () +setNoDash :: MonadPath m => m () hunk ./Graphics/PDF/Text.hs 10 --- PDF TExt +-- PDF Text hunk ./Graphics/PDF/Text.hs 18 + , TextMode(..) hunk ./Graphics/PDF/Text.hs 21 + , text hunk ./Graphics/PDF/Text.hs 23 + , startNewLine + , displayText + , textStart + , setFont + , leading + , charSpace + , wordSpace + , textScale + , renderMode + , rise + , setTextMatrix hunk ./Graphics/PDF/Text.hs 38 -import Control.Monad.State(gets) +import Control.Monad.State hunk ./Graphics/PDF/Text.hs 40 - -drawText :: PDFFont - -> PDFFloat - -> PDFFloat - -> PDFString - -> Draw () -drawText font@(PDFFont _ size) x y s = do - fontMap <- gets theFonts - (newName,newMap) <- setResource "Font" font fontMap - modifyStrict $ \s -> s { theFonts = newMap } - +import qualified Data.ByteString.Lazy as B +import Control.Monad.Writer +import Control.Monad.Trans +import qualified Data.Set as Set +import Graphics.PDF.Coordinates + +type FontState = (Set.Set FontName) + +data TextParameter = TextParameter { tc :: !PDFFloat + , tw :: !PDFFloat + , tz :: !PDFFloat + , tl :: !PDFFloat + , tf :: !PDFFloat + , ts :: !PDFFloat + , fontState :: FontState + } +defaultParameters :: TextParameter +defaultParameters = TextParameter 0 0 100 0 0 0 (Set.empty) + +newtype PDFText a = PDFText {unText :: WriterT B.ByteString (State TextParameter) a} deriving(Monad,Functor,MonadWriter B.ByteString) + +instance MonadPath PDFText + +type UnscaledUnit = PDFFloat + +data TextMode = FillText + | StrokeText + | FillAndStrokeText + | InvisibleText + | FillTextAndAddToClip + | StrokeTextAndAddToClip + | FillAndStrokeTextAndAddToClip + | AddToClip + deriving(Eq,Ord,Enum) + +setFont :: PDFFont -> PDFText () +setFont (PDFFont n s) = PDFText $ do + lift (modifyStrict $ \s -> s {fontState = Set.insert n (fontState s)}) + writeCmd $ "\n/" ++ (show n) ++ " " ++ (show s) ++ " Tf" + +drawText :: PDFText a + -> Draw a +drawText t = do + let ((a,w),s) = (runState . runWriterT . unText $ t) defaultParameters + mapM_ addFontRsrc (Set.elems (fontState s)) hunk ./Graphics/PDF/Text.hs 86 - writeCmd $ "\n/" ++ newName ++ " " ++ (show size) ++ " Tf" - writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " Td" - writeCmd $ "\n" - writeString s - writeCmd " Tj\nET" + tell w + writeCmd "\nET" + return a + where + addFontRsrc f = modifyStrict $ \s -> s { rsrc = addResource (PDFName "Font") (PDFName (show f)) (toRsrc (PDFFont f 0)) (rsrc s)} + +textStart :: PDFFloat + -> PDFFloat + -> PDFText () +textStart x y = writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " Td" + +displayText :: PDFString + -> PDFText () +displayText t = do + tell . toPDF $ t + writeCmd " Tj" + + + +startNewLine :: PDFText () +startNewLine = writeCmd "\nT*" + +leading :: UnscaledUnit -> PDFText () +leading v = PDFText $ do + lift (modifyStrict $ \s -> s {tl = v}) + writeCmd $ "\n" ++ (show v) ++ " TL" + +charSpace :: UnscaledUnit -> PDFText () +charSpace v = PDFText $ do + lift (modifyStrict $ \s -> s {tc = v}) + writeCmd $ "\n" ++ (show v) ++ " Tc" + +wordSpace :: UnscaledUnit -> PDFText () +wordSpace v = PDFText $ do + lift (modifyStrict $ \s -> s {tw = v}) + writeCmd $ "\n" ++ (show v) ++ " Tw" + +textScale :: PDFFloat -> PDFText () +textScale v = PDFText $ do + lift (modifyStrict $ \s -> s {tz = v}) + writeCmd $ "\n" ++ (show v) ++ " Tz" + +renderMode :: TextMode -> PDFText () +renderMode v = writeCmd $ "\n" ++ (show . fromEnum $ v) ++ " Tr" + +rise :: UnscaledUnit -> PDFText () +rise v = PDFText $ do + lift (modifyStrict $ \s -> s {ts = v}) + writeCmd $ "\n" ++ (show v) ++ " Ts" + +setTextMatrix :: Matrix -> PDFText() +setTextMatrix (Matrix a b c d e f) = + writeCmd $ "\n" ++ show (a) ++ " " ++ show (b) ++ " " ++ show (c) ++ " " ++ show (d) ++ " " ++ show (e) ++ " " ++ show (f) ++ " Tm" + +text :: PDFFont + -> PDFFloat + -> PDFFloat + -> PDFString + -> PDFText () +text f x y t = do + setFont f + textStart x y + displayText t + + hunk ./Graphics/PDF.hs 31 + , PDFXObject(drawXObject,bounds) hunk ./Graphics/PDF.hs 100 - -- We DO NOT check any more if the resource is empty because Pattern streams NEED a resource entry even if - -- the resource dictionary is empty. Otherwise, they are not displayed in acrobat reader althought they are in Apple preview. - -- If no resource needed by this drawing - --resources <- if emptyResource (rsrc state') - -- then do - -- case p of - -- -- Not linked to a page - -- -- otherResource are entries specific to a special stream (like an XObject) so we return empty for a page - -- Nothing -> return (otherRsrcs state') - -- -- Linked to a page - -- Just pageRef -> do - -- setPageAnnotations (annots state') pageRef - -- return emptyDictionary - -- -- Some resource are needed by the stream - -- else do - resources <- do + -- Pattern NEEDS a resource entry even if empty otherwise don't work with acrobat reader + -- Image DON'T want a resource entry if empty otherwise don't work with apple reader + resources <- if (emptyResource (rsrc state')) && (not (pdfDictMember (PDFName "PatternType") (otherRsrcs state'))) + then do + case p of + -- Not linked to a page + -- otherResource are entries specific to a special stream (like an XObject) so we return empty for a page + Nothing -> return (otherRsrcs state') + -- Linked to a page + Just pageRef -> do + setPageAnnotations (annots state') pageRef + return emptyDictionary + -- Some resource are needed by the stream + else do hunk ./Test/test.hs 70 - drawText (PDFFont Helvetica 12) 200 200 (toPDFString "This is a test éèçàù") + drawText $ text (PDFFont Helvetica 12) 200 200 (toPDFString "This is a test éèçàù") hunk ./Test/test.hs 81 - --setColoredFillPattern cp - paintWithShading (RadialShading 0 0 50 0 0 600 (Rgb 1 0 0) (Rgb 0 0 1)) (addShape $ Rectangle 0 0 300 300) - stroke $ Rectangle 0 0 300 300 + setColoredFillPattern cp + --paintWithShading (RadialShading 0 0 50 0 0 600 (Rgb 1 0 0) (Rgb 0 0 1)) (addShape $ Rectangle 0 0 300 300) + fill $ Rectangle 0 0 300 300 hunk ./Test/test.hs 102 - +testText :: IO () +testText = do + let rect = PDFRect 0 0 612 792 + runPdf "text.pdf" (standardDocInfo { author=toPDFString $ "alpheccar (éèçà)" + , compressed = False + }) rect $ do + page <- addPage Nothing + newSibling (toPDFString "Page Main") Nothing Nothing + drawWithPage page $ do + drawText $ do + setFont (PDFFont Times_Roman 48) + leading 40 + textStart 10 400 + renderMode StrokeText + displayText (toPDFString "This is a test éèçàù") + startNewLine + strokeColor $ Rgb 1 0 0 + displayText (toPDFString "Text again") + + + hunk ./Test/test.hs 126 - simple - testPenrose + --simple + --testPenrose + testText adddir ./c hunk ./Graphics/PDF.hs 97 - let (state',w') = runDrawing d (emptyEnvironment {streamId = r, xobjectb = bounds, currentp = maybe Nothing (\(PDFReference x) -> Just x) cp }) + let (value,state',w') = runDrawing d (emptyEnvironment {streamId = r, xobjectb = bounds, currentp = maybe Nothing (\(PDFReference x) -> Just x) cp }) hunk ./Graphics/PDF/Draw.hs 178 -runDrawing :: Draw () -> DrawEnvironment -> (DrawState,B.ByteString) +runDrawing :: Draw a -> DrawEnvironment -> (a,DrawState,B.ByteString) hunk ./Graphics/PDF/Draw.hs 186 - (_,state',w') = (runRWS . unDraw $ drawing) environment state + (a,state',w') = (runRWS . unDraw $ drawing) environment state hunk ./Graphics/PDF/Draw.hs 188 - (state',w') + (a,state',w') hunk ./Graphics/PDF/Text.hs 19 + , PDFText + , UnscaledUnit hunk ./Graphics/PDF/Text.hs 36 + , textWidth + , getDescent + , getLeading + , getHeight hunk ./Graphics/PDF/Text.hs 51 +import Data.Word hunk ./Graphics/PDF/Text.hs 53 +foreign import ccall "ctext.h c_getLeading" getLeading :: Int +foreign import ccall "ctext.h c_getAdvance" getAdvance :: Word8 -> Int +foreign import ccall "ctext.h c_getDescent" cgetDescent :: Int +foreign import ccall "ctext.h c_getHeight" cgetHeight :: Int + +-- pixel size / 2048 gives factor + +-- | Convert a dimension in font unit to device unit +trueSize :: Int -> Int -> PDFFloat +trueSize fontSize textSize = (fromIntegral (textSize*fontSize)) / 2408.0 + +getDescent :: PDFFont -> PDFFloat +getDescent (PDFFont _ s) = trueSize s cgetDescent + +getHeight :: PDFFont -> PDFFloat +getHeight (PDFFont _ s) = trueSize s cgetHeight + +textWidth :: PDFFont -> PDFString -> PDFFloat +textWidth (PDFFont _ s) (PDFString t) = trueSize s (sum . map getAdvance . B.unpack $ t) + hunk ./Graphics/PDF/Text.hs 85 - -newtype PDFText a = PDFText {unText :: WriterT B.ByteString (State TextParameter) a} deriving(Monad,Functor,MonadWriter B.ByteString) - + +-- | The text monad +newtype PDFText a = PDFText {unText :: WriterT B.ByteString (State TextParameter) a} +#ifndef __HADDOCK__ + deriving(Monad,Functor,MonadWriter B.ByteString) +#else +instance Monad PDFText +instance Functor PDFText +instance MonadWriter B.ByteString PDFText +#endif + hunk ./Graphics/PDF/Text.hs 98 +-- | Unscaled unit (not scaled by the font size) hunk ./Graphics/PDF/Text.hs 101 +-- | Rendering mode for text display hunk ./Graphics/PDF/Text.hs 112 +-- | Select a font to use hunk ./Graphics/PDF/Text.hs 118 +-- | Draw a text in the draw monad hunk ./Graphics/PDF/Text.hs 131 +-- | Set position for the text beginning hunk ./Graphics/PDF/Text.hs 137 +-- | Display some text hunk ./Graphics/PDF/Text.hs 145 - +-- | Start a new line (leading value must have been set) hunk ./Graphics/PDF/Text.hs 149 +-- | Set leading value hunk ./Graphics/PDF/Text.hs 155 +-- | Set the additional char space hunk ./Graphics/PDF/Text.hs 161 +-- | Set the additional word space hunk ./Graphics/PDF/Text.hs 167 +-- | Set scaling factor for text hunk ./Graphics/PDF/Text.hs 173 +-- | Choose the text rendering mode hunk ./Graphics/PDF/Text.hs 177 +-- | Set the rise value hunk ./Graphics/PDF/Text.hs 183 +-- | Set the text transformation matrix hunk ./Graphics/PDF/Text.hs 188 +-- | Utility function to quickly display one line of text hunk ./HPDF.cabal 12 -extensions: CPP +extensions: ForeignFunctionInterface, CPP +C-Sources: + c/metrics.c +Include-Dirs: c +Install-Includes: + ctext.h hunk ./Test/Makefile 2 - ghc -o test -cpp -Wall -funbox-strict-fields -fglasgow-exts -O2 -hidir interfaces -odir bin -i.. --make test.hs + ghc -o test -ffi -cpp -Wall -funbox-strict-fields -fglasgow-exts -O2 -hidir interfaces -odir bin -optc-I../c -i.. ../c/metrics.c --make test.hs hunk ./Test/Makefile 6 - ghc -o test -prof -auto-all -cpp -funbox-strict-fields -fglasgow-exts -O2 -hidir interfaces -odir bin -i.. --make test.hs + ghc -o test -ffi -prof -auto-all -cpp -funbox-strict-fields -fglasgow-exts -O2 -hidir interfaces -odir bin -i.. --make test.hs hunk ./Test/test.hs 111 + let f = PDFFont Times_Roman 48 + t = toPDFString "This is a test éèçàù" + fillColor $ Rgb 0 0 0 hunk ./Test/test.hs 115 - setFont (PDFFont Times_Roman 48) - leading 40 - textStart 10 400 - renderMode StrokeText - displayText (toPDFString "This is a test éèçàù") - startNewLine - strokeColor $ Rgb 1 0 0 - displayText (toPDFString "Text again") + setFont f + textStart 10 (400.0 - (getDescent f)) + renderMode FillText + displayText t + strokeColor $ Rgb 1 0 0 + stroke $ Line 10 400 612 400 + fill $ Circle 10 400 10 + stroke $ Rectangle 10 (400.0 - (getDescent f)) (10.0 + textWidth f t) (400.0 - getDescent f + getHeight f) addfile ./c/ctext.h hunk ./c/ctext.h 1 +#ifndef _CTEXT_H_ +#define _CTEXT_H_ +extern unsigned short c_getAdvance(unsigned char c); +extern unsigned short c_getLeading(void); +extern unsigned short c_getDescent(void); +extern unsigned short c_getHeight(void); +#endif addfile ./c/metrics.c hunk ./c/metrics.c 1 - +#include "metrics.h" +#include "ctext.h" + +unsigned short c_getAdvance(unsigned char c) +{ + return(gmetric[c*5+4]); +} + +unsigned short c_getLeading(void) +{ + return(fmetric[1]); +} + +unsigned short c_getDescent(void) +{ + return(fmetric[1] - fmetric[3]); +} + +unsigned short c_getHeight(void) +{ + return(fmetric[1]); +} addfile ./c/metrics.h binary ./c/metrics.h oldhex * newhex *2369666e646566205f4d4554524943535f485f0a23646566696e65205f4d4554524943535f485f *0a2f2a4e6220666163657320320a48656c76657469636120526567756c6172202a2f0a2f2a2063 *6861726d6170203a20756e6963202a2f0a2f2a20636861726d6170203a2061726d6e202a2f0a2f *2a20636861726d6170203a2061726d6e202a2f0a2f2a20636861726d6170203a2061726d6e202a *2f0a2f2a20636861726d6170203a2061726d6e202a2f0a2f2a20636861726d6170203a2061726d *6e202a2f0a2f2a20636861726d6170203a2061726d6e202a2f0a2f2a20636861726d6170203a20 *61726d6e202a2f0a2f2a20636861726d6170203a2000000000202a2f0a2f2a20636861726d6170 *203a2000000000202a2f0a73746174696320636f6e737420756e7369676e6564206c6f6e672067 *6d65747269635b5d3d7b0a2f2a2043686172636f64652030202a2f0a30202f2a20776964746820 *2a2f0a2c30202f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a *2f0a2c30202f2a20686f726942656172696e6759202a2f200a2c30202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f64652038202a2f0a2c30202f2a207769647468202a2f0a *2c30202f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c *30202f2a20686f726942656172696e6759202a2f200a2c30202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f64652039202a2f0a2c30202f2a207769647468202a2f0a2c3020 *2f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f *2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f6465203130202a2f0a2c30202f2a207769647468202a2f0a2c3020 *2f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f *2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f6465203133202a2f0a2c30202f2a207769647468202a2f0a2c3020 *2f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f *2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f6465203239202a2f0a2c30202f2a207769647468202a2f0a2c3020 *2f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f *2a20686f726942656172696e6759202a2f200a2c30202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203332202a2f0a2c30202f2a207769647468202a2f0a2c30202f2a *20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f2a20 *686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203333202a2f0a2c323033202f2a207769647468202a2f0a2c3134 *3639202f2a20686569676874202a2f0a2c323337202f2a20686f726942656172696e6758202a2f *0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f6465203334202a2f0a2c353234202f2a207769 *647468202a2f0a2c353838202f2a20686569676874202a2f0a2c313034202f2a20686f72694265 *6172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c3732 *37202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203335202a2f0a2c *31313337202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3020 *2f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e67 *59202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *6465203336202a2f0a2c393937202f2a207769647468202a2f0a2c31383235202f2a2068656967 *6874202a2f0a2c3634202f2a20686f726942656172696e6758202a2f0a2c31353838202f2a2068 *6f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203337202a2f0a2c31363738202f2a207769647468202a2f0a2c31 *343634202f2a20686569676874202a2f0a2c3636202f2a20686f726942656172696e6758202a2f *0a2c31343236202f2a20686f726942656172696e6759202a2f200a2c31383231202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f6465203338202a2f0a2c31323331202f2a20 *7769647468202a2f0a2c31353031202f2a20686569676874202a2f0a2c3839202f2a20686f7269 *42656172696e6758202a2f0a2c31343637202f2a20686f726942656172696e6759202a2f200a2c *31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203339202a *2f0a2c313832202f2a207769647468202a2f0a2c353838202f2a20686569676874202a2f0a2c31 *3031202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172 *696e6759202a2f200a2c333931202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f6465203430202a2f0a2c343637202f2a207769647468202a2f0a2c31393131202f2a206865 *69676874202a2f0a2c313432202f2a20686f726942656172696e6758202a2f0a2c31343933202f *2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f6465203431202a2f0a2c343637202f2a207769647468202a2f0a2c *31393131202f2a20686569676874202a2f0a2c3638202f2a20686f726942656172696e6758202a *2f0a2c31343933202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f6465203432202a2f0a2c363330202f2a2077 *69647468202a2f0a2c353838202f2a20686569676874202a2f0a2c3738202f2a20686f72694265 *6172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c3739 *37202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203433202a2f0a2c *31303433202f2a207769647468202a2f0a2c31303435202f2a20686569676874202a2f0a2c3736 *202f2a20686f726942656172696e6758202a2f0a2c31303435202f2a20686f726942656172696e *6759202a2f200a2c31313936202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f6465203434202a2f0a2c323134202f2a207769647468202a2f0a2c353232202f2a2068656967 *6874202a2f0a2c313730202f2a20686f726942656172696e6758202a2f0a2c323138202f2a2068 *6f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f6465203435202a2f0a2c353032202f2a207769647468202a2f0a2c313835 *202f2a20686569676874202a2f0a2c3835202f2a20686f726942656172696e6758202a2f0a2c36 *3633202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f6465203436202a2f0a2c323039202f2a20776964746820 *2a2f0a2c323138202f2a20686569676874202a2f0a2c313735202f2a20686f726942656172696e *6758202a2f0a2c323138202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f6465203437202a2f0a2c363138202f *2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c30202f2a20686f72 *6942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a *2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203438202a *2f0a2c393838202f2a207769647468202a2f0a2c31343731202f2a20686569676874202a2f0a2c *3634202f2a20686f726942656172696e6758202a2f0a2c31343332202f2a20686f726942656172 *696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f6465203439202a2f0a2c353239202f2a207769647468202a2f0a2c31343236202f2a2068 *6569676874202a2f0a2c313936202f2a20686f726942656172696e6758202a2f0a2c3134323620 *2f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f6465203530202a2f0a2c393930202f2a207769647468202a2f *0a2c31343337202f2a20686569676874202a2f0a2c3634202f2a20686f726942656172696e6758 *202a2f0a2c31343337202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f6465203531202a2f0a2c3130303120 *2f2a207769647468202a2f0a2c31343733202f2a20686569676874202a2f0a2c3439202f2a2068 *6f726942656172696e6758202a2f0a2c31343334202f2a20686f726942656172696e6759202a2f *200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652035 *32202a2f0a2c31303139202f2a207769647468202a2f0a2c31343336202f2a2068656967687420 *2a2f0a2c3532202f2a20686f726942656172696e6758202a2f0a2c31343336202f2a20686f7269 *42656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a *2043686172636f6465203533202a2f0a2c393836202f2a207769647468202a2f0a2c3134343420 *2f2a20686569676874202a2f0a2c3636202f2a20686f726942656172696e6758202a2f0a2c3134 *3038202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f6465203534202a2f0a2c393832202f2a207769647468 *202a2f0a2c31343735202f2a20686569676874202a2f0a2c3737202f2a20686f72694265617269 *6e6758202a2f0a2c31343338202f2a20686f726942656172696e6759202a2f200a2c3131333920 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203535202a2f0a2c3939 *36202f2a207769647468202a2f0a2c31343038202f2a20686569676874202a2f0a2c3735202f2a *20686f726942656172696e6758202a2f0a2c31343038202f2a20686f726942656172696e675920 *2a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *203536202a2f0a2c393834202f2a207769647468202a2f0a2c31343737202f2a20686569676874 *202a2f0a2c3636202f2a20686f726942656172696e6758202a2f0a2c31343336202f2a20686f72 *6942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f6465203537202a2f0a2c393638202f2a207769647468202a2f0a2c31343734 *202f2a20686569676874202a2f0a2c3733202f2a20686f726942656172696e6758202a2f0a2c31 *343334202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f6465203538202a2f0a2c323039202f2a2077696474 *68202a2f0a2c31303537202f2a20686569676874202a2f0a2c323237202f2a20686f7269426561 *72696e6758202a2f0a2c31303537202f2a20686f726942656172696e6759202a2f200a2c353639 *202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203539202a2f0a2c32 *3133202f2a207769647468202a2f0a2c31333631202f2a20686569676874202a2f0a2c32323720 *2f2a20686f726942656172696e6758202a2f0a2c31303537202f2a20686f726942656172696e67 *59202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64 *65203630202a2f0a2c31313639202f2a207769647468202a2f0a2c31303833202f2a2068656967 *6874202a2f0a2c3134202f2a20686f726942656172696e6758202a2f0a2c31303634202f2a2068 *6f726942656172696e6759202a2f200a2c31313936202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203631202a2f0a2c31303433202f2a207769647468202a2f0a2c36 *3030202f2a20686569676874202a2f0a2c3736202f2a20686f726942656172696e6758202a2f0a *2c383232202f2a20686f726942656172696e6759202a2f200a2c31313936202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f6465203632202a2f0a2c31313639202f2a207769 *647468202a2f0a2c31303833202f2a20686569676874202a2f0a2c3134202f2a20686f72694265 *6172696e6758202a2f0a2c31303634202f2a20686f726942656172696e6759202a2f200a2c3131 *3936202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203633202a2f0a *2c383931202f2a207769647468202a2f0a2c31343838202f2a20686569676874202a2f0a2c3135 *36202f2a20686f726942656172696e6758202a2f0a2c31343838202f2a20686f72694265617269 *6e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f6465203634202a2f0a2c31363236202f2a207769647468202a2f0a2c31353532202f2a2068 *6569676874202a2f0a2c323235202f2a20686f726942656172696e6758202a2f0a2c3135303920 *2f2a20686f726942656172696e6759202a2f200a2c32303739202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f6465203635202a2f0a2c31333131202f2a207769647468202a *2f0a2c31343639202f2a20686569676874202a2f0a2c3330202f2a20686f726942656172696e67 *58202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203636202a2f0a2c31313333 *202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313531202f2a *20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e675920 *2a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *203637202a2f0a2c31333033202f2a207769647468202a2f0a2c31353437202f2a206865696768 *74202a2f0a2c3930202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a20686f *726942656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f6465203638202a2f0a2c31323134202f2a207769647468202a2f0a2c3134 *3639202f2a20686569676874202a2f0a2c313635202f2a20686f726942656172696e6758202a2f *0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f6465203639202a2f0a2c31303836202f2a20 *7769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313735202f2a20686f72 *6942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a *2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520373020 *2a2f0a2c31303139202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f *0a2c313735202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942 *656172696e6759202a2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f6465203731202a2f0a2c31333432202f2a207769647468202a2f0a2c3135343820 *2f2a20686569676874202a2f0a2c3939202f2a20686f726942656172696e6758202a2f0a2c3135 *3039202f2a20686f726942656172696e6759202a2f200a2c31353933202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f6465203732202a2f0a2c31313636202f2a2077696474 *68202a2f0a2c31343639202f2a20686569676874202a2f0a2c313631202f2a20686f7269426561 *72696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c313437 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203733202a2f0a2c *323031202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c323031 *202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e *6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *6465203734202a2f0a2c383432202f2a207769647468202a2f0a2c31353038202f2a2068656967 *6874202a2f0a2c3335202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a2068 *6f726942656172696e6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203735202a2f0a2c31323032202f2a207769647468202a2f0a2c31 *343639202f2a20686569676874202a2f0a2c313536202f2a20686f726942656172696e6758202a *2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f *7269416476616e6365202a2f0a2f2a2043686172636f6465203736202a2f0a2c393433202f2a20 *7769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313536202f2a20686f72 *6942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a *2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520373720 *2a2f0a2c31343038202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f *0a2c313531202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942 *656172696e6759202a2f200a2c31373036202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f6465203738202a2f0a2c31313636202f2a207769647468202a2f0a2c3134363920 *2f2a20686569676874202a2f0a2c313536202f2a20686f726942656172696e6758202a2f0a2c31 *343639202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f6465203739202a2f0a2c31343332202f2a20776964 *7468202a2f0a2c31353532202f2a20686569676874202a2f0a2c3830202f2a20686f7269426561 *72696e6758202a2f0a2c31353039202f2a20686f726942656172696e6759202a2f200a2c313539 *33202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203830202a2f0a2c *31303937202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3137 *35202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f72694265617269 *6e6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f6465203831202a2f0a2c31343332202f2a207769647468202a2f0a2c31363236202f2a2068 *6569676874202a2f0a2c3830202f2a20686f726942656172696e6758202a2f0a2c31353039202f *2a20686f726942656172696e6759202a2f200a2c31353933202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f6465203832202a2f0a2c31323230202f2a207769647468202a2f *0a2c31343639202f2a20686569676874202a2f0a2c313830202f2a20686f726942656172696e67 *58202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203833202a2f0a2c31313734 *202f2a207769647468202a2f0a2c31353532202f2a20686569676874202a2f0a2c3936202f2a20 *686f726942656172696e6758202a2f0a2c31353039202f2a20686f726942656172696e6759202a *2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *3834202a2f0a2c31313932202f2a207769647468202a2f0a2c31343639202f2a20686569676874 *202a2f0a2c3333202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f72 *6942656172696e6759202a2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f6465203835202a2f0a2c31313537202f2a207769647468202a2f0a2c313530 *38202f2a20686569676874202a2f0a2c313730202f2a20686f726942656172696e6758202a2f0a *2c31343639202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f6465203836202a2f0a2c31323832202f2a2077 *69647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3532202f2a20686f726942 *656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31 *333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203837202a2f *0a2c31383638202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c *3337202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172 *696e6759202a2f200a2c31393333202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f6465203838202a2f0a2c31323930202f2a207769647468202a2f0a2c31343639202f2a20 *686569676874202a2f0a2c3432202f2a20686f726942656172696e6758202a2f0a2c3134363920 *2f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f6465203839202a2f0a2c31333039202f2a207769647468202a *2f0a2c31343639202f2a20686569676874202a2f0a2c3432202f2a20686f726942656172696e67 *58202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203930202a2f0a2c31313537 *202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3437202f2a20 *686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a *2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *3931202a2f0a2c333834202f2a207769647468202a2f0a2c31383832202f2a2068656967687420 *2a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31343739202f2a20686f72 *6942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a *2043686172636f6465203932202a2f0a2c373237202f2a207769647468202a2f0a2c3134363920 *2f2a20686569676874202a2f0a2c2d3639202f2a20686f726942656172696e6758202a2f0a2c31 *343639202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f6465203933202a2f0a2c333834202f2a207769647468 *202a2f0a2c31383832202f2a20686569676874202a2f0a2c3437202f2a20686f72694265617269 *6e6758202a2f0a2c31343739202f2a20686f726942656172696e6759202a2f200a2c353639202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203934202a2f0a2c383538 *202f2a207769647468202a2f0a2c383633202f2a20686569676874202a2f0a2c3531202f2a2068 *6f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f *200a2c393631202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203935 *202a2f0a2c31313339202f2a207769647468202a2f0a2c313031202f2a20686569676874202a2f *0a2c30202f2a20686f726942656172696e6758202a2f0a2c2d313535202f2a20686f7269426561 *72696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a204368 *6172636f6465203936202a2f0a2c343035202f2a207769647468202a2f0a2c343035202f2a2068 *6569676874202a2f0a2c3538202f2a20686f726942656172696e6758202a2f0a2c31353032202f *2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f6465203937202a2f0a2c31303133202f2a207769647468202a2f0a *2c31313333202f2a20686569676874202a2f0a2c3832202f2a20686f726942656172696e675820 *2a2f0a2c31303937202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f6465203938202a2f0a2c393433202f2a *207769647468202a2f0a2c31353038202f2a20686569676874202a2f0a2c313138202f2a20686f *726942656172696e6758202a2f0a2c31343734202f2a20686f726942656172696e6759202a2f20 *0a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203939 *202a2f0a2c393137202f2a207769647468202a2f0a2c31313333202f2a20686569676874202a2f *0a2c3539202f2a20686f726942656172696e6758202a2f0a2c31313032202f2a20686f72694265 *6172696e6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a2f2a2043 *686172636f646520313030202a2f0a2c393439202f2a207769647468202a2f0a2c31353132202f *2a20686569676874202a2f0a2c3536202f2a20686f726942656172696e6758202a2f0a2c313437 *34202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520313031202a2f0a2c393738202f2a207769647468 *202a2f0a2c31313335202f2a20686569676874202a2f0a2c3732202f2a20686f72694265617269 *6e6758202a2f0a2c31303937202f2a20686f726942656172696e6759202a2f200a2c3131333920 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313032202a2f0a2c35 *3037202f2a207769647468202a2f0a2c31343930202f2a20686569676874202a2f0a2c3238202f *2a20686f726942656172696e6758202a2f0a2c31343930202f2a20686f726942656172696e6759 *202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *20313033202a2f0a2c393339202f2a207769647468202a2f0a2c31353530202f2a206865696768 *74202a2f0a2c3631202f2a20686f726942656172696e6758202a2f0a2c31303937202f2a20686f *726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520313034202a2f0a2c383733202f2a207769647468202a2f0a2c3134 *3734202f2a20686569676874202a2f0a2c313332202f2a20686f726942656172696e6758202a2f *0a2c31343734202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f646520313035202a2f0a2c313833202f2a20 *7769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313332202f2a20686f72 *6942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a *2c343535202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031303620 *2a2f0a2c333530202f2a207769647468202a2f0a2c31393031202f2a20686569676874202a2f0a *2c2d3338202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f72694265 *6172696e6759202a2f200a2c343535202f2a20686f7269416476616e6365202a2f0a2f2a204368 *6172636f646520313037202a2f0a2c383838202f2a207769647468202a2f0a2c31343639202f2a *20686569676874202a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c313436 *39202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520313038202a2f0a2c313830202f2a207769647468 *202a2f0a2c31343639202f2a20686569676874202a2f0a2c313337202f2a20686f726942656172 *696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c34353520 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313039202a2f0a2c31 *343431202f2a207769647468202a2f0a2c31303935202f2a20686569676874202a2f0a2c313332 *202f2a20686f726942656172696e6758202a2f0a2c31303935202f2a20686f726942656172696e *6759202a2f200a2c31373036202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520313130202a2f0a2c383733202f2a207769647468202a2f0a2c31303937202f2a206865 *69676874202a2f0a2c313332202f2a20686f726942656172696e6758202a2f0a2c31303937202f *2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520313131202a2f0a2c393938202f2a207769647468202a2f *0a2c31313431202f2a20686569676874202a2f0a2c3539202f2a20686f726942656172696e6758 *202a2f0a2c31313032202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f646520313132202a2f0a2c39343320 *2f2a207769647468202a2f0a2c31353234202f2a20686569676874202a2f0a2c313138202f2a20 *686f726942656172696e6758202a2f0a2c31303937202f2a20686f726942656172696e6759202a *2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *313133202a2f0a2c393435202f2a207769647468202a2f0a2c31353232202f2a20686569676874 *202a2f0a2c3630202f2a20686f726942656172696e6758202a2f0a2c31303935202f2a20686f72 *6942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520313134202a2f0a2c353231202f2a207769647468202a2f0a2c313039 *35202f2a20686569676874202a2f0a2c313337202f2a20686f726942656172696e6758202a2f0a *2c31303935202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520313135202a2f0a2c383834202f2a207769 *647468202a2f0a2c31313430202f2a20686569676874202a2f0a2c3636202f2a20686f72694265 *6172696e6758202a2f0a2c31303939202f2a20686f726942656172696e6759202a2f200a2c3130 *3234202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313136202a2f *0a2c343938202f2a207769647468202a2f0a2c31333837202f2a20686569676874202a2f0a2c32 *33202f2a20686f726942656172696e6758202a2f0a2c31333730202f2a20686f72694265617269 *6e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520313137202a2f0a2c383632202f2a207769647468202a2f0a2c31313236202f2a206865 *69676874202a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31303937202f *2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520313138202a2f0a2c393931202f2a207769647468202a2f *0a2c31303731202f2a20686569676874202a2f0a2c3131202f2a20686f726942656172696e6758 *202a2f0a2c31303731202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f646520313139202a2f0a2c31343233 *202f2a207769647468202a2f0a2c31303731202f2a20686569676874202a2f0a2c3138202f2a20 *686f726942656172696e6758202a2f0a2c31303731202f2a20686f726942656172696e6759202a *2f200a2c31343739202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *313230202a2f0a2c393832202f2a207769647468202a2f0a2c31303731202f2a20686569676874 *202a2f0a2c3131202f2a20686f726942656172696e6758202a2f0a2c31303731202f2a20686f72 *6942656172696e6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520313231202a2f0a2c393739202f2a207769647468202a2f0a2c313533 *36202f2a20686569676874202a2f0a2c3231202f2a20686f726942656172696e6758202a2f0a2c *31303937202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520313232202a2f0a2c383936202f2a207769 *647468202a2f0a2c31303937202f2a20686569676874202a2f0a2c3532202f2a20686f72694265 *6172696e6758202a2f0a2c31303937202f2a20686f726942656172696e6759202a2f200a2c3130 *3234202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313233202a2f *0a2c363833202f2a207769647468202a2f0a2c31393133202f2a20686569676874202a2f0a2c2d *3433202f2a20686f726942656172696e6758202a2f0a2c31343935202f2a20686f726942656172 *696e6759202a2f200a2c363834202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520313234202a2f0a2c313731202f2a207769647468202a2f0a2c31343930202f2a2068 *6569676874202a2f0a2c313832202f2a20686f726942656172696e6758202a2f0a2c3134393020 *2f2a20686f726942656172696e6759202a2f200a2c353332202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520313235202a2f0a2c363833202f2a207769647468202a2f *0a2c31393133202f2a20686569676874202a2f0a2c3432202f2a20686f726942656172696e6758 *202a2f0a2c31343935202f2a20686f726942656172696e6759202a2f200a2c363834202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520313236202a2f0a2c3131393020 *2f2a207769647468202a2f0a2c343035202f2a20686569676874202a2f0a2c32202f2a20686f72 *6942656172696e6758202a2f0a2c373235202f2a20686f726942656172696e6759202a2f200a2c *31313936202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031363020 *2a2f0a2c30202f2a207769647468202a2f0a2c30202f2a20686569676874202a2f0a2c30202f2a *20686f726942656172696e6758202a2f0a2c30202f2a20686f726942656172696e6759202a2f20 *0a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313631 *202a2f0a2c323034202f2a207769647468202a2f0a2c31343730202f2a20686569676874202a2f *0a2c323332202f2a20686f726942656172696e6758202a2f0a2c31303731202f2a20686f726942 *656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043 *686172636f646520313632202a2f0a2c393436202f2a207769647468202a2f0a2c31353132202f *2a20686569676874202a2f0a2c313034202f2a20686f726942656172696e6758202a2f0a2c3132 *3735202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f646520313633202a2f0a2c31303336202f2a20776964 *7468202a2f0a2c31353033202f2a20686569676874202a2f0a2c3536202f2a20686f7269426561 *72696e6758202a2f0a2c31343637202f2a20686f726942656172696e6759202a2f200a2c313133 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313634202a2f0a *2c393730202f2a207769647468202a2f0a2c393731202f2a20686569676874202a2f0a2c373520 *2f2a20686f726942656172696e6758202a2f0a2c31313839202f2a20686f726942656172696e67 *59202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *646520313635202a2f0a2c31313738202f2a207769647468202a2f0a2c31343035202f2a206865 *69676874202a2f0a2c2d3331202f2a20686f726942656172696e6758202a2f0a2c31343035202f *2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520313636202a2f0a2c313731202f2a207769647468202a2f *0a2c31343930202f2a20686569676874202a2f0a2c313832202f2a20686f726942656172696e67 *58202a2f0a2c31343930202f2a20686f726942656172696e6759202a2f200a2c353332202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f646520313637202a2f0a2c39373020 *2f2a207769647468202a2f0a2c31393032202f2a20686569676874202a2f0a2c3735202f2a2068 *6f726942656172696e6758202a2f0a2c31343730202f2a20686f726942656172696e6759202a2f *200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031 *3638202a2f0a2c353137202f2a207769647468202a2f0a2c333438202f2a20686569676874202a *2f0a2c3732202f2a20686f726942656172696e6758202a2f0a2c31343435202f2a20686f726942 *656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043 *686172636f646520313639202a2f0a2c31343730202f2a207769647468202a2f0a2c3134363920 *2f2a20686569676874202a2f0a2c3139202f2a20686f726942656172696e6758202a2f0a2c3134 *3639202f2a20686f726942656172696e6759202a2f200a2c31353039202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f646520313730202a2f0a2c363539202f2a2077696474 *68202a2f0a2c363832202f2a20686569676874202a2f0a2c3539202f2a20686f72694265617269 *6e6758202a2f0a2c31353039202f2a20686f726942656172696e6759202a2f200a2c373538202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313731202a2f0a2c3734 *32202f2a207769647468202a2f0a2c363932202f2a20686569676874202a2f0a2c313934202f2a *20686f726942656172696e6758202a2f0a2c393035202f2a20686f726942656172696e6759202a *2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *313732202a2f0a2c31303433202f2a207769647468202a2f0a2c363030202f2a20686569676874 *202a2f0a2c3736202f2a20686f726942656172696e6758202a2f0a2c383232202f2a20686f7269 *42656172696e6759202a2f200a2c31313936202f2a20686f7269416476616e6365202a2f0a2f2a *2043686172636f646520313733202a2f0a2c353032202f2a207769647468202a2f0a2c31383520 *2f2a20686569676874202a2f0a2c3835202f2a20686f726942656172696e6758202a2f0a2c3636 *33202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e *6365202a2f0a2f2a2043686172636f646520313734202a2f0a2c31343637202f2a207769647468 *202a2f0a2c31343639202f2a20686569676874202a2f0a2c3231202f2a20686f72694265617269 *6e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c3135303920 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313735202a2f0a2c36 *3430202f2a207769647468202a2f0a2c313138202f2a20686569676874202a2f0a2c38202f2a20 *686f726942656172696e6758202a2f0a2c31343030202f2a20686f726942656172696e6759202a *2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031 *3736202a2f0a2c363034202f2a207769647468202a2f0a2c363034202f2a20686569676874202a *2f0a2c313131202f2a20686f726942656172696e6758202a2f0a2c31343331202f2a20686f7269 *42656172696e6759202a2f200a2c383139202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f646520313737202a2f0a2c31303433202f2a207769647468202a2f0a2c31303435 *202f2a20686569676874202a2f0a2c3430202f2a20686f726942656172696e6758202a2f0a2c31 *303435202f2a20686f726942656172696e6759202a2f200a2c31313234202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f646520313738202a2f0a2c363430202f2a20776964 *7468202a2f0a2c383631202f2a20686569676874202a2f0a2c3131202f2a20686f726942656172 *696e6758202a2f0a2c31343332202f2a20686f726942656172696e6759202a2f200a2c36383220 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313739202a2f0a2c36 *3437202f2a207769647468202a2f0a2c383839202f2a20686569676874202a2f0a2c37202f2a20 *686f726942656172696e6758202a2f0a2c31343331202f2a20686f726942656172696e6759202a *2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031 *3830202a2f0a2c343035202f2a207769647468202a2f0a2c343035202f2a20686569676874202a *2f0a2c313933202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f7269 *42656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f646520313831202a2f0a2c31313738202f2a207769647468202a2f0a2c31343931 *202f2a20686569676874202a2f0a2c2d3535202f2a20686f726942656172696e6758202a2f0a2c *31303639202f2a20686f726942656172696e6759202a2f200a2c31313830202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520313832202a2f0a2c31303736202f2a2077 *69647468202a2f0a2c31383332202f2a20686569676874202a2f0a2c2d3131202f2a20686f7269 *42656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c *31313030202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031383320 *2a2f0a2c323536202f2a207769647468202a2f0a2c323536202f2a20686569676874202a2f0a2c *313531202f2a20686f726942656172696e6758202a2f0a2c383239202f2a20686f726942656172 *696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520313834202a2f0a2c343430202f2a207769647468202a2f0a2c343631202f2a206865 *69676874202a2f0a2c313031202f2a20686f726942656172696e6758202a2f0a2c30202f2a2068 *6f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520313835202a2f0a2c333832202f2a207769647468202a2f0a2c3835 *35202f2a20686569676874202a2f0a2c3837202f2a20686f726942656172696e6758202a2f0a2c *31343236202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f646520313836202a2f0a2c363532202f2a20776964 *7468202a2f0a2c363832202f2a20686569676874202a2f0a2c3439202f2a20686f726942656172 *696e6758202a2f0a2c31353039202f2a20686f726942656172696e6759202a2f200a2c37343820 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313837202a2f0a2c37 *3432202f2a207769647468202a2f0a2c363932202f2a20686569676874202a2f0a2c313934202f *2a20686f726942656172696e6758202a2f0a2c393035202f2a20686f726942656172696e675920 *2a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *20313838202a2f0a2c31343633202f2a207769647468202a2f0a2c31343639202f2a2068656967 *6874202a2f0a2c313633202f2a20686f726942656172696e6758202a2f0a2c31343331202f2a20 *686f726942656172696e6759202a2f200a2c31373038202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f646520313839202a2f0a2c31353030202f2a207769647468202a2f0a *2c31343639202f2a20686569676874202a2f0a2c3930202f2a20686f726942656172696e675820 *2a2f0a2c31343331202f2a20686f726942656172696e6759202a2f200a2c31373038202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520313930202a2f0a2c3135373020 *2f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3735202f2a2068 *6f726942656172696e6758202a2f0a2c31343331202f2a20686f726942656172696e6759202a2f *200a2c31373038202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031 *3931202a2f0a2c383934202f2a207769647468202a2f0a2c31343839202f2a2068656967687420 *2a2f0a2c313836202f2a20686f726942656172696e6758202a2f0a2c31303736202f2a20686f72 *6942656172696e6759202a2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520313932202a2f0a2c31333131202f2a207769647468202a2f0a2c3138 *3734202f2a20686569676874202a2f0a2c3330202f2a20686f726942656172696e6758202a2f0a *2c31383734202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520313933202a2f0a2c31333131202f2a20 *7769647468202a2f0a2c31383734202f2a20686569676874202a2f0a2c3330202f2a20686f7269 *42656172696e6758202a2f0a2c31383734202f2a20686f726942656172696e6759202a2f200a2c *31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031393420 *2a2f0a2c31333131202f2a207769647468202a2f0a2c31383734202f2a20686569676874202a2f *0a2c3330202f2a20686f726942656172696e6758202a2f0a2c31383734202f2a20686f72694265 *6172696e6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043 *686172636f646520313935202a2f0a2c31333131202f2a207769647468202a2f0a2c3138343120 *2f2a20686569676874202a2f0a2c3330202f2a20686f726942656172696e6758202a2f0a2c3138 *3431202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f646520313936202a2f0a2c31333131202f2a20776964 *7468202a2f0a2c31383137202f2a20686569676874202a2f0a2c3330202f2a20686f7269426561 *72696e6758202a2f0a2c31383137202f2a20686f726942656172696e6759202a2f200a2c313336 *36202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313937202a2f0a *2c31333131202f2a207769647468202a2f0a2c31393436202f2a20686569676874202a2f0a2c33 *30202f2a20686f726942656172696e6758202a2f0a2c31393436202f2a20686f72694265617269 *6e6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520313938202a2f0a2c31393332202f2a207769647468202a2f0a2c31343639202f2a20 *686569676874202a2f0a2c3136202f2a20686f726942656172696e6758202a2f0a2c3134363920 *2f2a20686f726942656172696e6759202a2f200a2c32303438202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f646520313939202a2f0a2c31333033202f2a20776964746820 *2a2f0a2c31393730202f2a20686569676874202a2f0a2c3930202f2a20686f726942656172696e *6758202a2f0a2c31353039202f2a20686f726942656172696e6759202a2f200a2c31343739202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323030202a2f0a2c3130 *3836202f2a207769647468202a2f0a2c31383734202f2a20686569676874202a2f0a2c31373520 *2f2a20686f726942656172696e6758202a2f0a2c31383734202f2a20686f726942656172696e67 *59202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *646520323031202a2f0a2c31303836202f2a207769647468202a2f0a2c31383734202f2a206865 *69676874202a2f0a2c313735202f2a20686f726942656172696e6758202a2f0a2c31383734202f *2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520323032202a2f0a2c31303836202f2a207769647468202a *2f0a2c31383734202f2a20686569676874202a2f0a2c313735202f2a20686f726942656172696e *6758202a2f0a2c31383734202f2a20686f726942656172696e6759202a2f200a2c31333636202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323033202a2f0a2c3130 *3836202f2a207769647468202a2f0a2c31383137202f2a20686569676874202a2f0a2c31373520 *2f2a20686f726942656172696e6758202a2f0a2c31383137202f2a20686f726942656172696e67 *59202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *646520323034202a2f0a2c343035202f2a207769647468202a2f0a2c31383733202f2a20686569 *676874202a2f0a2c32202f2a20686f726942656172696e6758202a2f0a2c31383733202f2a2068 *6f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520323035202a2f0a2c343035202f2a207769647468202a2f0a2c3138 *3730202f2a20686569676874202a2f0a2c313337202f2a20686f726942656172696e6758202a2f *0a2c31383730202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520323036202a2f0a2c353937202f2a2077 *69647468202a2f0a2c31383738202f2a20686569676874202a2f0a2c2d3236202f2a20686f7269 *42656172696e6758202a2f0a2c31383738202f2a20686f726942656172696e6759202a2f200a2c *353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323037202a *2f0a2c353137202f2a207769647468202a2f0a2c31383133202f2a20686569676874202a2f0a2c *3136202f2a20686f726942656172696e6758202a2f0a2c31383133202f2a20686f726942656172 *696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520323038202a2f0a2c31333436202f2a207769647468202a2f0a2c31343639202f2a20 *686569676874202a2f0a2c3333202f2a20686f726942656172696e6758202a2f0a2c3134363920 *2f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f646520323039202a2f0a2c31313636202f2a20776964746820 *2a2f0a2c31383431202f2a20686569676874202a2f0a2c313536202f2a20686f72694265617269 *6e6758202a2f0a2c31383431202f2a20686f726942656172696e6759202a2f200a2c3134373920 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323130202a2f0a2c31 *343332202f2a207769647468202a2f0a2c31393537202f2a20686569676874202a2f0a2c383020 *2f2a20686f726942656172696e6758202a2f0a2c31393134202f2a20686f726942656172696e67 *59202a2f200a2c31353933202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *646520323131202a2f0a2c31343332202f2a207769647468202a2f0a2c31393537202f2a206865 *69676874202a2f0a2c3830202f2a20686f726942656172696e6758202a2f0a2c31393134202f2a *20686f726942656172696e6759202a2f200a2c31353933202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f646520323132202a2f0a2c31343332202f2a207769647468202a2f *0a2c31393537202f2a20686569676874202a2f0a2c3830202f2a20686f726942656172696e6758 *202a2f0a2c31393134202f2a20686f726942656172696e6759202a2f200a2c31353933202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f646520323133202a2f0a2c31343332 *202f2a207769647468202a2f0a2c31393234202f2a20686569676874202a2f0a2c3830202f2a20 *686f726942656172696e6758202a2f0a2c31383831202f2a20686f726942656172696e6759202a *2f200a2c31353933202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *323134202a2f0a2c31343332202f2a207769647468202a2f0a2c31393030202f2a206865696768 *74202a2f0a2c3830202f2a20686f726942656172696e6758202a2f0a2c31383537202f2a20686f *726942656172696e6759202a2f200a2c31353933202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520323135202a2f0a2c393938202f2a207769647468202a2f0a2c3939 *38202f2a20686569676874202a2f0a2c313030202f2a20686f726942656172696e6758202a2f0a *2c31303231202f2a20686f726942656172696e6759202a2f200a2c31313936202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520323136202a2f0a2c31343436202f2a20 *7769647468202a2f0a2c31353533202f2a20686569676874202a2f0a2c3636202f2a20686f7269 *42656172696e6758202a2f0a2c31353130202f2a20686f726942656172696e6759202a2f200a2c *31353933202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032313720 *2a2f0a2c31313537202f2a207769647468202a2f0a2c31393133202f2a20686569676874202a2f *0a2c313730202f2a20686f726942656172696e6758202a2f0a2c31383734202f2a20686f726942 *656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f646520323138202a2f0a2c31313537202f2a207769647468202a2f0a2c31393133 *202f2a20686569676874202a2f0a2c313730202f2a20686f726942656172696e6758202a2f0a2c *31383734202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520323139202a2f0a2c31313537202f2a2077 *69647468202a2f0a2c31393133202f2a20686569676874202a2f0a2c313730202f2a20686f7269 *42656172696e6758202a2f0a2c31383734202f2a20686f726942656172696e6759202a2f200a2c *31343739202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032323020 *2a2f0a2c31313537202f2a207769647468202a2f0a2c31383536202f2a20686569676874202a2f *0a2c313730202f2a20686f726942656172696e6758202a2f0a2c31383137202f2a20686f726942 *656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f646520323231202a2f0a2c31333039202f2a207769647468202a2f0a2c31383734 *202f2a20686569676874202a2f0a2c3432202f2a20686f726942656172696e6758202a2f0a2c31 *383734202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f646520323232202a2f0a2c31303938202f2a207769 *647468202a2f0a2c31343637202f2a20686569676874202a2f0a2c313734202f2a20686f726942 *656172696e6758202a2f0a2c31343637202f2a20686f726942656172696e6759202a2f200a2c31 *333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323233202a *2f0a2c393037202f2a207769647468202a2f0a2c31353230202f2a20686569676874202a2f0a2c *313939202f2a20686f726942656172696e6758202a2f0a2c31343931202f2a20686f7269426561 *72696e6759202a2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f2a204368 *6172636f646520323234202a2f0a2c31303133202f2a207769647468202a2f0a2c31353338202f *2a20686569676874202a2f0a2c3832202f2a20686f726942656172696e6758202a2f0a2c313530 *32202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520323235202a2f0a2c31303133202f2a2077696474 *68202a2f0a2c31353338202f2a20686569676874202a2f0a2c3832202f2a20686f726942656172 *696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c31313339 *202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323236202a2f0a2c *31303133202f2a207769647468202a2f0a2c31353338202f2a20686569676874202a2f0a2c3832 *202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e *6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520323237202a2f0a2c31303133202f2a207769647468202a2f0a2c31353035202f2a2068 *6569676874202a2f0a2c3832202f2a20686f726942656172696e6758202a2f0a2c31343639202f *2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520323238202a2f0a2c31303133202f2a207769647468202a *2f0a2c31343831202f2a20686569676874202a2f0a2c3832202f2a20686f726942656172696e67 *58202a2f0a2c31343435202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323239202a2f0a2c313031 *33202f2a207769647468202a2f0a2c31363632202f2a20686569676874202a2f0a2c3832202f2a *20686f726942656172696e6758202a2f0a2c31363236202f2a20686f726942656172696e675920 *2a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *20323330202a2f0a2c31363632202f2a207769647468202a2f0a2c31313333202f2a2068656967 *6874202a2f0a2c3733202f2a20686f726942656172696e6758202a2f0a2c31303937202f2a2068 *6f726942656172696e6759202a2f200a2c31383231202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f646520323331202a2f0a2c393137202f2a207769647468202a2f0a2c31 *353633202f2a20686569676874202a2f0a2c3539202f2a20686f726942656172696e6758202a2f *0a2c31313032202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f646520323332202a2f0a2c393738202f2a20 *7769647468202a2f0a2c31353430202f2a20686569676874202a2f0a2c3732202f2a20686f7269 *42656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c *31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032333320 *2a2f0a2c393738202f2a207769647468202a2f0a2c31353430202f2a20686569676874202a2f0a *2c3732202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f7269426561 *72696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a204368 *6172636f646520323334202a2f0a2c393738202f2a207769647468202a2f0a2c31353430202f2a *20686569676874202a2f0a2c3732202f2a20686f726942656172696e6758202a2f0a2c31353032 *202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e *6365202a2f0a2f2a2043686172636f646520323335202a2f0a2c393738202f2a20776964746820 *2a2f0a2c31343833202f2a20686569676874202a2f0a2c3732202f2a20686f726942656172696e *6758202a2f0a2c31343435202f2a20686f726942656172696e6759202a2f200a2c31313339202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323336202a2f0a2c3430 *35202f2a207769647468202a2f0a2c31353032202f2a20686569676874202a2f0a2c3133202f2a *20686f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e675920 *2a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *323337202a2f0a2c343035202f2a207769647468202a2f0a2c31353032202f2a20686569676874 *202a2f0a2c313433202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f *726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520323338202a2f0a2c353937202f2a207769647468202a2f0a2c313530 *32202f2a20686569676874202a2f0a2c2d3137202f2a20686f726942656172696e6758202a2f0a *2c31353032202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520323339202a2f0a2c353137202f2a207769 *647468202a2f0a2c31343435202f2a20686569676874202a2f0a2c3232202f2a20686f72694265 *6172696e6758202a2f0a2c31343435202f2a20686f726942656172696e6759202a2f200a2c3536 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323430202a2f0a *2c31303030202f2a207769647468202a2f0a2c31363630202f2a20686569676874202a2f0a2c36 *31202f2a20686f726942656172696e6758202a2f0a2c31363233202f2a20686f72694265617269 *6e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520323431202a2f0a2c383733202f2a207769647468202a2f0a2c31343639202f2a2068 *6569676874202a2f0a2c313332202f2a20686f726942656172696e6758202a2f0a2c3134363920 *2f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f646520323432202a2f0a2c393938202f2a207769647468202a *2f0a2c31353431202f2a20686569676874202a2f0a2c3539202f2a20686f726942656172696e67 *58202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323433202a2f0a2c393938 *202f2a207769647468202a2f0a2c31353431202f2a20686569676874202a2f0a2c3539202f2a20 *686f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a *2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *323434202a2f0a2c393938202f2a207769647468202a2f0a2c31353431202f2a20686569676874 *202a2f0a2c3539202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f72 *6942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520323435202a2f0a2c393938202f2a207769647468202a2f0a2c313530 *38202f2a20686569676874202a2f0a2c3539202f2a20686f726942656172696e6758202a2f0a2c *31343639202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520323436202a2f0a2c393938202f2a207769 *647468202a2f0a2c31343834202f2a20686569676874202a2f0a2c3539202f2a20686f72694265 *6172696e6758202a2f0a2c31343435202f2a20686f726942656172696e6759202a2f200a2c3131 *3339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323437202a2f *0a2c31303433202f2a207769647468202a2f0a2c31303033202f2a20686569676874202a2f0a2c *3430202f2a20686f726942656172696e6758202a2f0a2c31303234202f2a20686f726942656172 *696e6759202a2f200a2c31313234202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f646520323438202a2f0a2c31303435202f2a207769647468202a2f0a2c31313539202f2a *20686569676874202a2f0a2c3932202f2a20686f726942656172696e6758202a2f0a2c31313131 *202f2a20686f726942656172696e6759202a2f200a2c31323531202f2a20686f7269416476616e *6365202a2f0a2f2a2043686172636f646520323439202a2f0a2c383632202f2a20776964746820 *2a2f0a2c31353331202f2a20686569676874202a2f0a2c313238202f2a20686f72694265617269 *6e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c3131333920 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323530202a2f0a2c38 *3632202f2a207769647468202a2f0a2c31353331202f2a20686569676874202a2f0a2c31323820 *2f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e67 *59202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *646520323531202a2f0a2c383632202f2a207769647468202a2f0a2c31353331202f2a20686569 *676874202a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a *20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f646520323532202a2f0a2c383632202f2a207769647468202a2f0a *2c31343734202f2a20686569676874202a2f0a2c313238202f2a20686f726942656172696e6758 *202a2f0a2c31343435202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f646520323533202a2f0a2c39373920 *2f2a207769647468202a2f0a2c31393431202f2a20686569676874202a2f0a2c3231202f2a2068 *6f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f *200a2c31303234202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032 *3534202a2f0a2c393337202f2a207769647468202a2f0a2c31383932202f2a2068656967687420 *2a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31343535202f2a20686f72 *6942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520323535202a2f0a2c393739202f2a207769647468202a2f0a2c313838 *34202f2a20686569676874202a2f0a2c3231202f2a20686f726942656172696e6758202a2f0a2c *31343435202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a20686f726941 *6476616e6365202a2f0a7d3b0a73746174696320636f6e737420756e7369676e6564206c6f6e67 *20666d65747269635b5d3d7b0a31393332202f2a206d61785f7769647468202a2f0a2c31393730 *202f2a206d61785f686569676874202a2f0a2c323337202f2a206d61785f686f72694265617269 *6e6758202a2f0a2c31393436202f2a206d61785f686f726942656172696e6759202a2f0a2c3230 *3739202f2a206d61785f686f7269416476616e6365202a2f0a7d3b0a23656e6469660a adddir ./Core14_AFMs addfile ./Core14_AFMs/Courier-Bold.afm hunk ./Core14_AFMs/Courier-Bold.afm 1 +StartFontMetrics 4.1 +Comment Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Mon Jun 23 16:28:00 1997 +Comment UniqueID 43048 +Comment VMusage 41139 52164 +FontName Courier-Bold +FullName Courier Bold +FamilyName Courier +Weight Bold +ItalicAngle 0 +IsFixedPitch true +CharacterSet ExtendedRoman +FontBBox -113 -250 749 801 +UnderlinePosition -100 +UnderlineThickness 50 +Version 003.000 +Notice Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 562 +XHeight 439 +Ascender 629 +Descender -157 +StdHW 84 +StdVW 106 +StartCharMetrics 315 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 202 -15 398 572 ; +C 34 ; WX 600 ; N quotedbl ; B 135 277 465 562 ; +C 35 ; WX 600 ; N numbersign ; B 56 -45 544 651 ; +C 36 ; WX 600 ; N dollar ; B 82 -126 519 666 ; +C 37 ; WX 600 ; N percent ; B 5 -15 595 616 ; +C 38 ; WX 600 ; N ampersand ; B 36 -15 546 543 ; +C 39 ; WX 600 ; N quoteright ; B 171 277 423 562 ; +C 40 ; WX 600 ; N parenleft ; B 219 -102 461 616 ; +C 41 ; WX 600 ; N parenright ; B 139 -102 381 616 ; +C 42 ; WX 600 ; N asterisk ; B 91 219 509 601 ; +C 43 ; WX 600 ; N plus ; B 71 39 529 478 ; +C 44 ; WX 600 ; N comma ; B 123 -111 393 174 ; +C 45 ; WX 600 ; N hyphen ; B 100 203 500 313 ; +C 46 ; WX 600 ; N period ; B 192 -15 408 171 ; +C 47 ; WX 600 ; N slash ; B 98 -77 502 626 ; +C 48 ; WX 600 ; N zero ; B 87 -15 513 616 ; +C 49 ; WX 600 ; N one ; B 81 0 539 616 ; +C 50 ; WX 600 ; N two ; B 61 0 499 616 ; +C 51 ; WX 600 ; N three ; B 63 -15 501 616 ; +C 52 ; WX 600 ; N four ; B 53 0 507 616 ; +C 53 ; WX 600 ; N five ; B 70 -15 521 601 ; +C 54 ; WX 600 ; N six ; B 90 -15 521 616 ; +C 55 ; WX 600 ; N seven ; B 55 0 494 601 ; +C 56 ; WX 600 ; N eight ; B 83 -15 517 616 ; +C 57 ; WX 600 ; N nine ; B 79 -15 510 616 ; +C 58 ; WX 600 ; N colon ; B 191 -15 407 425 ; +C 59 ; WX 600 ; N semicolon ; B 123 -111 408 425 ; +C 60 ; WX 600 ; N less ; B 66 15 523 501 ; +C 61 ; WX 600 ; N equal ; B 71 118 529 398 ; +C 62 ; WX 600 ; N greater ; B 77 15 534 501 ; +C 63 ; WX 600 ; N question ; B 98 -14 501 580 ; +C 64 ; WX 600 ; N at ; B 16 -15 584 616 ; +C 65 ; WX 600 ; N A ; B -9 0 609 562 ; +C 66 ; WX 600 ; N B ; B 30 0 573 562 ; +C 67 ; WX 600 ; N C ; B 22 -18 560 580 ; +C 68 ; WX 600 ; N D ; B 30 0 594 562 ; +C 69 ; WX 600 ; N E ; B 25 0 560 562 ; +C 70 ; WX 600 ; N F ; B 39 0 570 562 ; +C 71 ; WX 600 ; N G ; B 22 -18 594 580 ; +C 72 ; WX 600 ; N H ; B 20 0 580 562 ; +C 73 ; WX 600 ; N I ; B 77 0 523 562 ; +C 74 ; WX 600 ; N J ; B 37 -18 601 562 ; +C 75 ; WX 600 ; N K ; B 21 0 599 562 ; +C 76 ; WX 600 ; N L ; B 39 0 578 562 ; +C 77 ; WX 600 ; N M ; B -2 0 602 562 ; +C 78 ; WX 600 ; N N ; B 8 -12 610 562 ; +C 79 ; WX 600 ; N O ; B 22 -18 578 580 ; +C 80 ; WX 600 ; N P ; B 48 0 559 562 ; +C 81 ; WX 600 ; N Q ; B 32 -138 578 580 ; +C 82 ; WX 600 ; N R ; B 24 0 599 562 ; +C 83 ; WX 600 ; N S ; B 47 -22 553 582 ; +C 84 ; WX 600 ; N T ; B 21 0 579 562 ; +C 85 ; WX 600 ; N U ; B 4 -18 596 562 ; +C 86 ; WX 600 ; N V ; B -13 0 613 562 ; +C 87 ; WX 600 ; N W ; B -18 0 618 562 ; +C 88 ; WX 600 ; N X ; B 12 0 588 562 ; +C 89 ; WX 600 ; N Y ; B 12 0 589 562 ; +C 90 ; WX 600 ; N Z ; B 62 0 539 562 ; +C 91 ; WX 600 ; N bracketleft ; B 245 -102 475 616 ; +C 92 ; WX 600 ; N backslash ; B 99 -77 503 626 ; +C 93 ; WX 600 ; N bracketright ; B 125 -102 355 616 ; +C 94 ; WX 600 ; N asciicircum ; B 108 250 492 616 ; +C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ; +C 96 ; WX 600 ; N quoteleft ; B 178 277 428 562 ; +C 97 ; WX 600 ; N a ; B 35 -15 570 454 ; +C 98 ; WX 600 ; N b ; B 0 -15 584 626 ; +C 99 ; WX 600 ; N c ; B 40 -15 545 459 ; +C 100 ; WX 600 ; N d ; B 20 -15 591 626 ; +C 101 ; WX 600 ; N e ; B 40 -15 563 454 ; +C 102 ; WX 600 ; N f ; B 83 0 547 626 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 30 -146 580 454 ; +C 104 ; WX 600 ; N h ; B 5 0 592 626 ; +C 105 ; WX 600 ; N i ; B 77 0 523 658 ; +C 106 ; WX 600 ; N j ; B 63 -146 440 658 ; +C 107 ; WX 600 ; N k ; B 20 0 585 626 ; +C 108 ; WX 600 ; N l ; B 77 0 523 626 ; +C 109 ; WX 600 ; N m ; B -22 0 626 454 ; +C 110 ; WX 600 ; N n ; B 18 0 592 454 ; +C 111 ; WX 600 ; N o ; B 30 -15 570 454 ; +C 112 ; WX 600 ; N p ; B -1 -142 570 454 ; +C 113 ; WX 600 ; N q ; B 20 -142 591 454 ; +C 114 ; WX 600 ; N r ; B 47 0 580 454 ; +C 115 ; WX 600 ; N s ; B 68 -17 535 459 ; +C 116 ; WX 600 ; N t ; B 47 -15 532 562 ; +C 117 ; WX 600 ; N u ; B -1 -15 569 439 ; +C 118 ; WX 600 ; N v ; B -1 0 601 439 ; +C 119 ; WX 600 ; N w ; B -18 0 618 439 ; +C 120 ; WX 600 ; N x ; B 6 0 594 439 ; +C 121 ; WX 600 ; N y ; B -4 -142 601 439 ; +C 122 ; WX 600 ; N z ; B 81 0 520 439 ; +C 123 ; WX 600 ; N braceleft ; B 160 -102 464 616 ; +C 124 ; WX 600 ; N bar ; B 255 -250 345 750 ; +C 125 ; WX 600 ; N braceright ; B 136 -102 440 616 ; +C 126 ; WX 600 ; N asciitilde ; B 71 153 530 356 ; +C 161 ; WX 600 ; N exclamdown ; B 202 -146 398 449 ; +C 162 ; WX 600 ; N cent ; B 66 -49 518 614 ; +C 163 ; WX 600 ; N sterling ; B 72 -28 558 611 ; +C 164 ; WX 600 ; N fraction ; B 25 -60 576 661 ; +C 165 ; WX 600 ; N yen ; B 10 0 590 562 ; +C 166 ; WX 600 ; N florin ; B -30 -131 572 616 ; +C 167 ; WX 600 ; N section ; B 83 -70 517 580 ; +C 168 ; WX 600 ; N currency ; B 54 49 546 517 ; +C 169 ; WX 600 ; N quotesingle ; B 227 277 373 562 ; +C 170 ; WX 600 ; N quotedblleft ; B 71 277 535 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 8 70 553 446 ; +C 172 ; WX 600 ; N guilsinglleft ; B 141 70 459 446 ; +C 173 ; WX 600 ; N guilsinglright ; B 141 70 459 446 ; +C 174 ; WX 600 ; N fi ; B 12 0 593 626 ; +C 175 ; WX 600 ; N fl ; B 12 0 593 626 ; +C 177 ; WX 600 ; N endash ; B 65 203 535 313 ; +C 178 ; WX 600 ; N dagger ; B 106 -70 494 580 ; +C 179 ; WX 600 ; N daggerdbl ; B 106 -70 494 580 ; +C 180 ; WX 600 ; N periodcentered ; B 196 165 404 351 ; +C 182 ; WX 600 ; N paragraph ; B 6 -70 576 580 ; +C 183 ; WX 600 ; N bullet ; B 140 132 460 430 ; +C 184 ; WX 600 ; N quotesinglbase ; B 175 -142 427 143 ; +C 185 ; WX 600 ; N quotedblbase ; B 65 -142 529 143 ; +C 186 ; WX 600 ; N quotedblright ; B 61 277 525 562 ; +C 187 ; WX 600 ; N guillemotright ; B 47 70 592 446 ; +C 188 ; WX 600 ; N ellipsis ; B 26 -15 574 116 ; +C 189 ; WX 600 ; N perthousand ; B -113 -15 713 616 ; +C 191 ; WX 600 ; N questiondown ; B 99 -146 502 449 ; +C 193 ; WX 600 ; N grave ; B 132 508 395 661 ; +C 194 ; WX 600 ; N acute ; B 205 508 468 661 ; +C 195 ; WX 600 ; N circumflex ; B 103 483 497 657 ; +C 196 ; WX 600 ; N tilde ; B 89 493 512 636 ; +C 197 ; WX 600 ; N macron ; B 88 505 512 585 ; +C 198 ; WX 600 ; N breve ; B 83 468 517 631 ; +C 199 ; WX 600 ; N dotaccent ; B 230 498 370 638 ; +C 200 ; WX 600 ; N dieresis ; B 128 498 472 638 ; +C 202 ; WX 600 ; N ring ; B 198 481 402 678 ; +C 203 ; WX 600 ; N cedilla ; B 205 -206 387 0 ; +C 205 ; WX 600 ; N hungarumlaut ; B 68 488 588 661 ; +C 206 ; WX 600 ; N ogonek ; B 169 -199 400 0 ; +C 207 ; WX 600 ; N caron ; B 103 493 497 667 ; +C 208 ; WX 600 ; N emdash ; B -10 203 610 313 ; +C 225 ; WX 600 ; N AE ; B -29 0 602 562 ; +C 227 ; WX 600 ; N ordfeminine ; B 147 196 453 580 ; +C 232 ; WX 600 ; N Lslash ; B 39 0 578 562 ; +C 233 ; WX 600 ; N Oslash ; B 22 -22 578 584 ; +C 234 ; WX 600 ; N OE ; B -25 0 595 562 ; +C 235 ; WX 600 ; N ordmasculine ; B 147 196 453 580 ; +C 241 ; WX 600 ; N ae ; B -4 -15 601 454 ; +C 245 ; WX 600 ; N dotlessi ; B 77 0 523 439 ; +C 248 ; WX 600 ; N lslash ; B 77 0 523 626 ; +C 249 ; WX 600 ; N oslash ; B 30 -24 570 463 ; +C 250 ; WX 600 ; N oe ; B -18 -15 611 454 ; +C 251 ; WX 600 ; N germandbls ; B 22 -15 596 626 ; +C -1 ; WX 600 ; N Idieresis ; B 77 0 523 761 ; +C -1 ; WX 600 ; N eacute ; B 40 -15 563 661 ; +C -1 ; WX 600 ; N abreve ; B 35 -15 570 661 ; +C -1 ; WX 600 ; N uhungarumlaut ; B -1 -15 628 661 ; +C -1 ; WX 600 ; N ecaron ; B 40 -15 563 667 ; +C -1 ; WX 600 ; N Ydieresis ; B 12 0 589 761 ; +C -1 ; WX 600 ; N divide ; B 71 16 529 500 ; +C -1 ; WX 600 ; N Yacute ; B 12 0 589 784 ; +C -1 ; WX 600 ; N Acircumflex ; B -9 0 609 780 ; +C -1 ; WX 600 ; N aacute ; B 35 -15 570 661 ; +C -1 ; WX 600 ; N Ucircumflex ; B 4 -18 596 780 ; +C -1 ; WX 600 ; N yacute ; B -4 -142 601 661 ; +C -1 ; WX 600 ; N scommaaccent ; B 68 -250 535 459 ; +C -1 ; WX 600 ; N ecircumflex ; B 40 -15 563 657 ; +C -1 ; WX 600 ; N Uring ; B 4 -18 596 801 ; +C -1 ; WX 600 ; N Udieresis ; B 4 -18 596 761 ; +C -1 ; WX 600 ; N aogonek ; B 35 -199 586 454 ; +C -1 ; WX 600 ; N Uacute ; B 4 -18 596 784 ; +C -1 ; WX 600 ; N uogonek ; B -1 -199 585 439 ; +C -1 ; WX 600 ; N Edieresis ; B 25 0 560 761 ; +C -1 ; WX 600 ; N Dcroat ; B 30 0 594 562 ; +C -1 ; WX 600 ; N commaaccent ; B 205 -250 397 -57 ; +C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N Emacron ; B 25 0 560 708 ; +C -1 ; WX 600 ; N ccaron ; B 40 -15 545 667 ; +C -1 ; WX 600 ; N aring ; B 35 -15 570 678 ; +C -1 ; WX 600 ; N Ncommaaccent ; B 8 -250 610 562 ; +C -1 ; WX 600 ; N lacute ; B 77 0 523 801 ; +C -1 ; WX 600 ; N agrave ; B 35 -15 570 661 ; +C -1 ; WX 600 ; N Tcommaaccent ; B 21 -250 579 562 ; +C -1 ; WX 600 ; N Cacute ; B 22 -18 560 784 ; +C -1 ; WX 600 ; N atilde ; B 35 -15 570 636 ; +C -1 ; WX 600 ; N Edotaccent ; B 25 0 560 761 ; +C -1 ; WX 600 ; N scaron ; B 68 -17 535 667 ; +C -1 ; WX 600 ; N scedilla ; B 68 -206 535 459 ; +C -1 ; WX 600 ; N iacute ; B 77 0 523 661 ; +C -1 ; WX 600 ; N lozenge ; B 66 0 534 740 ; +C -1 ; WX 600 ; N Rcaron ; B 24 0 599 790 ; +C -1 ; WX 600 ; N Gcommaaccent ; B 22 -250 594 580 ; +C -1 ; WX 600 ; N ucircumflex ; B -1 -15 569 657 ; +C -1 ; WX 600 ; N acircumflex ; B 35 -15 570 657 ; +C -1 ; WX 600 ; N Amacron ; B -9 0 609 708 ; +C -1 ; WX 600 ; N rcaron ; B 47 0 580 667 ; +C -1 ; WX 600 ; N ccedilla ; B 40 -206 545 459 ; +C -1 ; WX 600 ; N Zdotaccent ; B 62 0 539 761 ; +C -1 ; WX 600 ; N Thorn ; B 48 0 557 562 ; +C -1 ; WX 600 ; N Omacron ; B 22 -18 578 708 ; +C -1 ; WX 600 ; N Racute ; B 24 0 599 784 ; +C -1 ; WX 600 ; N Sacute ; B 47 -22 553 784 ; +C -1 ; WX 600 ; N dcaron ; B 20 -15 727 626 ; +C -1 ; WX 600 ; N Umacron ; B 4 -18 596 708 ; +C -1 ; WX 600 ; N uring ; B -1 -15 569 678 ; +C -1 ; WX 600 ; N threesuperior ; B 138 222 433 616 ; +C -1 ; WX 600 ; N Ograve ; B 22 -18 578 784 ; +C -1 ; WX 600 ; N Agrave ; B -9 0 609 784 ; +C -1 ; WX 600 ; N Abreve ; B -9 0 609 784 ; +C -1 ; WX 600 ; N multiply ; B 81 39 520 478 ; +C -1 ; WX 600 ; N uacute ; B -1 -15 569 661 ; +C -1 ; WX 600 ; N Tcaron ; B 21 0 579 790 ; +C -1 ; WX 600 ; N partialdiff ; B 63 -38 537 728 ; +C -1 ; WX 600 ; N ydieresis ; B -4 -142 601 638 ; +C -1 ; WX 600 ; N Nacute ; B 8 -12 610 784 ; +C -1 ; WX 600 ; N icircumflex ; B 73 0 523 657 ; +C -1 ; WX 600 ; N Ecircumflex ; B 25 0 560 780 ; +C -1 ; WX 600 ; N adieresis ; B 35 -15 570 638 ; +C -1 ; WX 600 ; N edieresis ; B 40 -15 563 638 ; +C -1 ; WX 600 ; N cacute ; B 40 -15 545 661 ; +C -1 ; WX 600 ; N nacute ; B 18 0 592 661 ; +C -1 ; WX 600 ; N umacron ; B -1 -15 569 585 ; +C -1 ; WX 600 ; N Ncaron ; B 8 -12 610 790 ; +C -1 ; WX 600 ; N Iacute ; B 77 0 523 784 ; +C -1 ; WX 600 ; N plusminus ; B 71 24 529 515 ; +C -1 ; WX 600 ; N brokenbar ; B 255 -175 345 675 ; +C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N Gbreve ; B 22 -18 594 784 ; +C -1 ; WX 600 ; N Idotaccent ; B 77 0 523 761 ; +C -1 ; WX 600 ; N summation ; B 15 -10 586 706 ; +C -1 ; WX 600 ; N Egrave ; B 25 0 560 784 ; +C -1 ; WX 600 ; N racute ; B 47 0 580 661 ; +C -1 ; WX 600 ; N omacron ; B 30 -15 570 585 ; +C -1 ; WX 600 ; N Zacute ; B 62 0 539 784 ; +C -1 ; WX 600 ; N Zcaron ; B 62 0 539 790 ; +C -1 ; WX 600 ; N greaterequal ; B 26 0 523 696 ; +C -1 ; WX 600 ; N Eth ; B 30 0 594 562 ; +C -1 ; WX 600 ; N Ccedilla ; B 22 -206 560 580 ; +C -1 ; WX 600 ; N lcommaaccent ; B 77 -250 523 626 ; +C -1 ; WX 600 ; N tcaron ; B 47 -15 532 703 ; +C -1 ; WX 600 ; N eogonek ; B 40 -199 563 454 ; +C -1 ; WX 600 ; N Uogonek ; B 4 -199 596 562 ; +C -1 ; WX 600 ; N Aacute ; B -9 0 609 784 ; +C -1 ; WX 600 ; N Adieresis ; B -9 0 609 761 ; +C -1 ; WX 600 ; N egrave ; B 40 -15 563 661 ; +C -1 ; WX 600 ; N zacute ; B 81 0 520 661 ; +C -1 ; WX 600 ; N iogonek ; B 77 -199 523 658 ; +C -1 ; WX 600 ; N Oacute ; B 22 -18 578 784 ; +C -1 ; WX 600 ; N oacute ; B 30 -15 570 661 ; +C -1 ; WX 600 ; N amacron ; B 35 -15 570 585 ; +C -1 ; WX 600 ; N sacute ; B 68 -17 535 661 ; +C -1 ; WX 600 ; N idieresis ; B 77 0 523 618 ; +C -1 ; WX 600 ; N Ocircumflex ; B 22 -18 578 780 ; +C -1 ; WX 600 ; N Ugrave ; B 4 -18 596 784 ; +C -1 ; WX 600 ; N Delta ; B 6 0 594 688 ; +C -1 ; WX 600 ; N thorn ; B -14 -142 570 626 ; +C -1 ; WX 600 ; N twosuperior ; B 143 230 436 616 ; +C -1 ; WX 600 ; N Odieresis ; B 22 -18 578 761 ; +C -1 ; WX 600 ; N mu ; B -1 -142 569 439 ; +C -1 ; WX 600 ; N igrave ; B 77 0 523 661 ; +C -1 ; WX 600 ; N ohungarumlaut ; B 30 -15 668 661 ; +C -1 ; WX 600 ; N Eogonek ; B 25 -199 576 562 ; +C -1 ; WX 600 ; N dcroat ; B 20 -15 591 626 ; +C -1 ; WX 600 ; N threequarters ; B -47 -60 648 661 ; +C -1 ; WX 600 ; N Scedilla ; B 47 -206 553 582 ; +C -1 ; WX 600 ; N lcaron ; B 77 0 597 626 ; +C -1 ; WX 600 ; N Kcommaaccent ; B 21 -250 599 562 ; +C -1 ; WX 600 ; N Lacute ; B 39 0 578 784 ; +C -1 ; WX 600 ; N trademark ; B -9 230 749 562 ; +C -1 ; WX 600 ; N edotaccent ; B 40 -15 563 638 ; +C -1 ; WX 600 ; N Igrave ; B 77 0 523 784 ; +C -1 ; WX 600 ; N Imacron ; B 77 0 523 708 ; +C -1 ; WX 600 ; N Lcaron ; B 39 0 637 562 ; +C -1 ; WX 600 ; N onehalf ; B -47 -60 648 661 ; +C -1 ; WX 600 ; N lessequal ; B 26 0 523 696 ; +C -1 ; WX 600 ; N ocircumflex ; B 30 -15 570 657 ; +C -1 ; WX 600 ; N ntilde ; B 18 0 592 636 ; +C -1 ; WX 600 ; N Uhungarumlaut ; B 4 -18 638 784 ; +C -1 ; WX 600 ; N Eacute ; B 25 0 560 784 ; +C -1 ; WX 600 ; N emacron ; B 40 -15 563 585 ; +C -1 ; WX 600 ; N gbreve ; B 30 -146 580 661 ; +C -1 ; WX 600 ; N onequarter ; B -56 -60 656 661 ; +C -1 ; WX 600 ; N Scaron ; B 47 -22 553 790 ; +C -1 ; WX 600 ; N Scommaaccent ; B 47 -250 553 582 ; +C -1 ; WX 600 ; N Ohungarumlaut ; B 22 -18 628 784 ; +C -1 ; WX 600 ; N degree ; B 86 243 474 616 ; +C -1 ; WX 600 ; N ograve ; B 30 -15 570 661 ; +C -1 ; WX 600 ; N Ccaron ; B 22 -18 560 790 ; +C -1 ; WX 600 ; N ugrave ; B -1 -15 569 661 ; +C -1 ; WX 600 ; N radical ; B -19 -104 473 778 ; +C -1 ; WX 600 ; N Dcaron ; B 30 0 594 790 ; +C -1 ; WX 600 ; N rcommaaccent ; B 47 -250 580 454 ; +C -1 ; WX 600 ; N Ntilde ; B 8 -12 610 759 ; +C -1 ; WX 600 ; N otilde ; B 30 -15 570 636 ; +C -1 ; WX 600 ; N Rcommaaccent ; B 24 -250 599 562 ; +C -1 ; WX 600 ; N Lcommaaccent ; B 39 -250 578 562 ; +C -1 ; WX 600 ; N Atilde ; B -9 0 609 759 ; +C -1 ; WX 600 ; N Aogonek ; B -9 -199 625 562 ; +C -1 ; WX 600 ; N Aring ; B -9 0 609 801 ; +C -1 ; WX 600 ; N Otilde ; B 22 -18 578 759 ; +C -1 ; WX 600 ; N zdotaccent ; B 81 0 520 638 ; +C -1 ; WX 600 ; N Ecaron ; B 25 0 560 790 ; +C -1 ; WX 600 ; N Iogonek ; B 77 -199 523 562 ; +C -1 ; WX 600 ; N kcommaaccent ; B 20 -250 585 626 ; +C -1 ; WX 600 ; N minus ; B 71 203 529 313 ; +C -1 ; WX 600 ; N Icircumflex ; B 77 0 523 780 ; +C -1 ; WX 600 ; N ncaron ; B 18 0 592 667 ; +C -1 ; WX 600 ; N tcommaaccent ; B 47 -250 532 562 ; +C -1 ; WX 600 ; N logicalnot ; B 71 103 529 413 ; +C -1 ; WX 600 ; N odieresis ; B 30 -15 570 638 ; +C -1 ; WX 600 ; N udieresis ; B -1 -15 569 638 ; +C -1 ; WX 600 ; N notequal ; B 12 -47 537 563 ; +C -1 ; WX 600 ; N gcommaaccent ; B 30 -146 580 714 ; +C -1 ; WX 600 ; N eth ; B 58 -27 543 626 ; +C -1 ; WX 600 ; N zcaron ; B 81 0 520 667 ; +C -1 ; WX 600 ; N ncommaaccent ; B 18 -250 592 454 ; +C -1 ; WX 600 ; N onesuperior ; B 153 230 447 616 ; +C -1 ; WX 600 ; N imacron ; B 77 0 523 585 ; +C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics addfile ./Core14_AFMs/Courier-BoldOblique.afm hunk ./Core14_AFMs/Courier-BoldOblique.afm 1 +StartFontMetrics 4.1 +Comment Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Mon Jun 23 16:28:46 1997 +Comment UniqueID 43049 +Comment VMusage 17529 79244 +FontName Courier-BoldOblique +FullName Courier Bold Oblique +FamilyName Courier +Weight Bold +ItalicAngle -12 +IsFixedPitch true +CharacterSet ExtendedRoman +FontBBox -57 -250 869 801 +UnderlinePosition -100 +UnderlineThickness 50 +Version 003.000 +Notice Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 562 +XHeight 439 +Ascender 629 +Descender -157 +StdHW 84 +StdVW 106 +StartCharMetrics 315 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 215 -15 495 572 ; +C 34 ; WX 600 ; N quotedbl ; B 211 277 585 562 ; +C 35 ; WX 600 ; N numbersign ; B 88 -45 641 651 ; +C 36 ; WX 600 ; N dollar ; B 87 -126 630 666 ; +C 37 ; WX 600 ; N percent ; B 101 -15 625 616 ; +C 38 ; WX 600 ; N ampersand ; B 61 -15 595 543 ; +C 39 ; WX 600 ; N quoteright ; B 229 277 543 562 ; +C 40 ; WX 600 ; N parenleft ; B 265 -102 592 616 ; +C 41 ; WX 600 ; N parenright ; B 117 -102 444 616 ; +C 42 ; WX 600 ; N asterisk ; B 179 219 598 601 ; +C 43 ; WX 600 ; N plus ; B 114 39 596 478 ; +C 44 ; WX 600 ; N comma ; B 99 -111 430 174 ; +C 45 ; WX 600 ; N hyphen ; B 143 203 567 313 ; +C 46 ; WX 600 ; N period ; B 206 -15 427 171 ; +C 47 ; WX 600 ; N slash ; B 90 -77 626 626 ; +C 48 ; WX 600 ; N zero ; B 135 -15 593 616 ; +C 49 ; WX 600 ; N one ; B 93 0 562 616 ; +C 50 ; WX 600 ; N two ; B 61 0 594 616 ; +C 51 ; WX 600 ; N three ; B 71 -15 571 616 ; +C 52 ; WX 600 ; N four ; B 81 0 559 616 ; +C 53 ; WX 600 ; N five ; B 77 -15 621 601 ; +C 54 ; WX 600 ; N six ; B 135 -15 652 616 ; +C 55 ; WX 600 ; N seven ; B 147 0 622 601 ; +C 56 ; WX 600 ; N eight ; B 115 -15 604 616 ; +C 57 ; WX 600 ; N nine ; B 75 -15 592 616 ; +C 58 ; WX 600 ; N colon ; B 205 -15 480 425 ; +C 59 ; WX 600 ; N semicolon ; B 99 -111 481 425 ; +C 60 ; WX 600 ; N less ; B 120 15 613 501 ; +C 61 ; WX 600 ; N equal ; B 96 118 614 398 ; +C 62 ; WX 600 ; N greater ; B 97 15 589 501 ; +C 63 ; WX 600 ; N question ; B 183 -14 592 580 ; +C 64 ; WX 600 ; N at ; B 65 -15 642 616 ; +C 65 ; WX 600 ; N A ; B -9 0 632 562 ; +C 66 ; WX 600 ; N B ; B 30 0 630 562 ; +C 67 ; WX 600 ; N C ; B 74 -18 675 580 ; +C 68 ; WX 600 ; N D ; B 30 0 664 562 ; +C 69 ; WX 600 ; N E ; B 25 0 670 562 ; +C 70 ; WX 600 ; N F ; B 39 0 684 562 ; +C 71 ; WX 600 ; N G ; B 74 -18 675 580 ; +C 72 ; WX 600 ; N H ; B 20 0 700 562 ; +C 73 ; WX 600 ; N I ; B 77 0 643 562 ; +C 74 ; WX 600 ; N J ; B 58 -18 721 562 ; +C 75 ; WX 600 ; N K ; B 21 0 692 562 ; +C 76 ; WX 600 ; N L ; B 39 0 636 562 ; +C 77 ; WX 600 ; N M ; B -2 0 722 562 ; +C 78 ; WX 600 ; N N ; B 8 -12 730 562 ; +C 79 ; WX 600 ; N O ; B 74 -18 645 580 ; +C 80 ; WX 600 ; N P ; B 48 0 643 562 ; +C 81 ; WX 600 ; N Q ; B 83 -138 636 580 ; +C 82 ; WX 600 ; N R ; B 24 0 617 562 ; +C 83 ; WX 600 ; N S ; B 54 -22 673 582 ; +C 84 ; WX 600 ; N T ; B 86 0 679 562 ; +C 85 ; WX 600 ; N U ; B 101 -18 716 562 ; +C 86 ; WX 600 ; N V ; B 84 0 733 562 ; +C 87 ; WX 600 ; N W ; B 79 0 738 562 ; +C 88 ; WX 600 ; N X ; B 12 0 690 562 ; +C 89 ; WX 600 ; N Y ; B 109 0 709 562 ; +C 90 ; WX 600 ; N Z ; B 62 0 637 562 ; +C 91 ; WX 600 ; N bracketleft ; B 223 -102 606 616 ; +C 92 ; WX 600 ; N backslash ; B 222 -77 496 626 ; +C 93 ; WX 600 ; N bracketright ; B 103 -102 486 616 ; +C 94 ; WX 600 ; N asciicircum ; B 171 250 556 616 ; +C 95 ; WX 600 ; N underscore ; B -27 -125 585 -75 ; +C 96 ; WX 600 ; N quoteleft ; B 297 277 487 562 ; +C 97 ; WX 600 ; N a ; B 61 -15 593 454 ; +C 98 ; WX 600 ; N b ; B 13 -15 636 626 ; +C 99 ; WX 600 ; N c ; B 81 -15 631 459 ; +C 100 ; WX 600 ; N d ; B 60 -15 645 626 ; +C 101 ; WX 600 ; N e ; B 81 -15 605 454 ; +C 102 ; WX 600 ; N f ; B 83 0 677 626 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 40 -146 674 454 ; +C 104 ; WX 600 ; N h ; B 18 0 615 626 ; +C 105 ; WX 600 ; N i ; B 77 0 546 658 ; +C 106 ; WX 600 ; N j ; B 36 -146 580 658 ; +C 107 ; WX 600 ; N k ; B 33 0 643 626 ; +C 108 ; WX 600 ; N l ; B 77 0 546 626 ; +C 109 ; WX 600 ; N m ; B -22 0 649 454 ; +C 110 ; WX 600 ; N n ; B 18 0 615 454 ; +C 111 ; WX 600 ; N o ; B 71 -15 622 454 ; +C 112 ; WX 600 ; N p ; B -32 -142 622 454 ; +C 113 ; WX 600 ; N q ; B 60 -142 685 454 ; +C 114 ; WX 600 ; N r ; B 47 0 655 454 ; +C 115 ; WX 600 ; N s ; B 66 -17 608 459 ; +C 116 ; WX 600 ; N t ; B 118 -15 567 562 ; +C 117 ; WX 600 ; N u ; B 70 -15 592 439 ; +C 118 ; WX 600 ; N v ; B 70 0 695 439 ; +C 119 ; WX 600 ; N w ; B 53 0 712 439 ; +C 120 ; WX 600 ; N x ; B 6 0 671 439 ; +C 121 ; WX 600 ; N y ; B -21 -142 695 439 ; +C 122 ; WX 600 ; N z ; B 81 0 614 439 ; +C 123 ; WX 600 ; N braceleft ; B 203 -102 595 616 ; +C 124 ; WX 600 ; N bar ; B 201 -250 505 750 ; +C 125 ; WX 600 ; N braceright ; B 114 -102 506 616 ; +C 126 ; WX 600 ; N asciitilde ; B 120 153 590 356 ; +C 161 ; WX 600 ; N exclamdown ; B 196 -146 477 449 ; +C 162 ; WX 600 ; N cent ; B 121 -49 605 614 ; +C 163 ; WX 600 ; N sterling ; B 106 -28 650 611 ; +C 164 ; WX 600 ; N fraction ; B 22 -60 708 661 ; +C 165 ; WX 600 ; N yen ; B 98 0 710 562 ; +C 166 ; WX 600 ; N florin ; B -57 -131 702 616 ; +C 167 ; WX 600 ; N section ; B 74 -70 620 580 ; +C 168 ; WX 600 ; N currency ; B 77 49 644 517 ; +C 169 ; WX 600 ; N quotesingle ; B 303 277 493 562 ; +C 170 ; WX 600 ; N quotedblleft ; B 190 277 594 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 62 70 639 446 ; +C 172 ; WX 600 ; N guilsinglleft ; B 195 70 545 446 ; +C 173 ; WX 600 ; N guilsinglright ; B 165 70 514 446 ; +C 174 ; WX 600 ; N fi ; B 12 0 644 626 ; +C 175 ; WX 600 ; N fl ; B 12 0 644 626 ; +C 177 ; WX 600 ; N endash ; B 108 203 602 313 ; +C 178 ; WX 600 ; N dagger ; B 175 -70 586 580 ; +C 179 ; WX 600 ; N daggerdbl ; B 121 -70 587 580 ; +C 180 ; WX 600 ; N periodcentered ; B 248 165 461 351 ; +C 182 ; WX 600 ; N paragraph ; B 61 -70 700 580 ; +C 183 ; WX 600 ; N bullet ; B 196 132 523 430 ; +C 184 ; WX 600 ; N quotesinglbase ; B 144 -142 458 143 ; +C 185 ; WX 600 ; N quotedblbase ; B 34 -142 560 143 ; +C 186 ; WX 600 ; N quotedblright ; B 119 277 645 562 ; +C 187 ; WX 600 ; N guillemotright ; B 71 70 647 446 ; +C 188 ; WX 600 ; N ellipsis ; B 35 -15 587 116 ; +C 189 ; WX 600 ; N perthousand ; B -45 -15 743 616 ; +C 191 ; WX 600 ; N questiondown ; B 100 -146 509 449 ; +C 193 ; WX 600 ; N grave ; B 272 508 503 661 ; +C 194 ; WX 600 ; N acute ; B 312 508 609 661 ; +C 195 ; WX 600 ; N circumflex ; B 212 483 607 657 ; +C 196 ; WX 600 ; N tilde ; B 199 493 643 636 ; +C 197 ; WX 600 ; N macron ; B 195 505 637 585 ; +C 198 ; WX 600 ; N breve ; B 217 468 652 631 ; +C 199 ; WX 600 ; N dotaccent ; B 348 498 493 638 ; +C 200 ; WX 600 ; N dieresis ; B 246 498 595 638 ; +C 202 ; WX 600 ; N ring ; B 319 481 528 678 ; +C 203 ; WX 600 ; N cedilla ; B 168 -206 368 0 ; +C 205 ; WX 600 ; N hungarumlaut ; B 171 488 729 661 ; +C 206 ; WX 600 ; N ogonek ; B 143 -199 367 0 ; +C 207 ; WX 600 ; N caron ; B 238 493 633 667 ; +C 208 ; WX 600 ; N emdash ; B 33 203 677 313 ; +C 225 ; WX 600 ; N AE ; B -29 0 708 562 ; +C 227 ; WX 600 ; N ordfeminine ; B 188 196 526 580 ; +C 232 ; WX 600 ; N Lslash ; B 39 0 636 562 ; +C 233 ; WX 600 ; N Oslash ; B 48 -22 673 584 ; +C 234 ; WX 600 ; N OE ; B 26 0 701 562 ; +C 235 ; WX 600 ; N ordmasculine ; B 188 196 543 580 ; +C 241 ; WX 600 ; N ae ; B 21 -15 652 454 ; +C 245 ; WX 600 ; N dotlessi ; B 77 0 546 439 ; +C 248 ; WX 600 ; N lslash ; B 77 0 587 626 ; +C 249 ; WX 600 ; N oslash ; B 54 -24 638 463 ; +C 250 ; WX 600 ; N oe ; B 18 -15 662 454 ; +C 251 ; WX 600 ; N germandbls ; B 22 -15 629 626 ; +C -1 ; WX 600 ; N Idieresis ; B 77 0 643 761 ; +C -1 ; WX 600 ; N eacute ; B 81 -15 609 661 ; +C -1 ; WX 600 ; N abreve ; B 61 -15 658 661 ; +C -1 ; WX 600 ; N uhungarumlaut ; B 70 -15 769 661 ; +C -1 ; WX 600 ; N ecaron ; B 81 -15 633 667 ; +C -1 ; WX 600 ; N Ydieresis ; B 109 0 709 761 ; +C -1 ; WX 600 ; N divide ; B 114 16 596 500 ; +C -1 ; WX 600 ; N Yacute ; B 109 0 709 784 ; +C -1 ; WX 600 ; N Acircumflex ; B -9 0 632 780 ; +C -1 ; WX 600 ; N aacute ; B 61 -15 609 661 ; +C -1 ; WX 600 ; N Ucircumflex ; B 101 -18 716 780 ; +C -1 ; WX 600 ; N yacute ; B -21 -142 695 661 ; +C -1 ; WX 600 ; N scommaaccent ; B 66 -250 608 459 ; +C -1 ; WX 600 ; N ecircumflex ; B 81 -15 607 657 ; +C -1 ; WX 600 ; N Uring ; B 101 -18 716 801 ; +C -1 ; WX 600 ; N Udieresis ; B 101 -18 716 761 ; +C -1 ; WX 600 ; N aogonek ; B 61 -199 593 454 ; +C -1 ; WX 600 ; N Uacute ; B 101 -18 716 784 ; +C -1 ; WX 600 ; N uogonek ; B 70 -199 592 439 ; +C -1 ; WX 600 ; N Edieresis ; B 25 0 670 761 ; +C -1 ; WX 600 ; N Dcroat ; B 30 0 664 562 ; +C -1 ; WX 600 ; N commaaccent ; B 151 -250 385 -57 ; +C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N Emacron ; B 25 0 670 708 ; +C -1 ; WX 600 ; N ccaron ; B 81 -15 633 667 ; +C -1 ; WX 600 ; N aring ; B 61 -15 593 678 ; +C -1 ; WX 600 ; N Ncommaaccent ; B 8 -250 730 562 ; +C -1 ; WX 600 ; N lacute ; B 77 0 639 801 ; +C -1 ; WX 600 ; N agrave ; B 61 -15 593 661 ; +C -1 ; WX 600 ; N Tcommaaccent ; B 86 -250 679 562 ; +C -1 ; WX 600 ; N Cacute ; B 74 -18 675 784 ; +C -1 ; WX 600 ; N atilde ; B 61 -15 643 636 ; +C -1 ; WX 600 ; N Edotaccent ; B 25 0 670 761 ; +C -1 ; WX 600 ; N scaron ; B 66 -17 633 667 ; +C -1 ; WX 600 ; N scedilla ; B 66 -206 608 459 ; +C -1 ; WX 600 ; N iacute ; B 77 0 609 661 ; +C -1 ; WX 600 ; N lozenge ; B 145 0 614 740 ; +C -1 ; WX 600 ; N Rcaron ; B 24 0 659 790 ; +C -1 ; WX 600 ; N Gcommaaccent ; B 74 -250 675 580 ; +C -1 ; WX 600 ; N ucircumflex ; B 70 -15 597 657 ; +C -1 ; WX 600 ; N acircumflex ; B 61 -15 607 657 ; +C -1 ; WX 600 ; N Amacron ; B -9 0 633 708 ; +C -1 ; WX 600 ; N rcaron ; B 47 0 655 667 ; +C -1 ; WX 600 ; N ccedilla ; B 81 -206 631 459 ; +C -1 ; WX 600 ; N Zdotaccent ; B 62 0 637 761 ; +C -1 ; WX 600 ; N Thorn ; B 48 0 620 562 ; +C -1 ; WX 600 ; N Omacron ; B 74 -18 663 708 ; +C -1 ; WX 600 ; N Racute ; B 24 0 665 784 ; +C -1 ; WX 600 ; N Sacute ; B 54 -22 673 784 ; +C -1 ; WX 600 ; N dcaron ; B 60 -15 861 626 ; +C -1 ; WX 600 ; N Umacron ; B 101 -18 716 708 ; +C -1 ; WX 600 ; N uring ; B 70 -15 592 678 ; +C -1 ; WX 600 ; N threesuperior ; B 193 222 526 616 ; +C -1 ; WX 600 ; N Ograve ; B 74 -18 645 784 ; +C -1 ; WX 600 ; N Agrave ; B -9 0 632 784 ; +C -1 ; WX 600 ; N Abreve ; B -9 0 684 784 ; +C -1 ; WX 600 ; N multiply ; B 104 39 606 478 ; +C -1 ; WX 600 ; N uacute ; B 70 -15 599 661 ; +C -1 ; WX 600 ; N Tcaron ; B 86 0 679 790 ; +C -1 ; WX 600 ; N partialdiff ; B 91 -38 627 728 ; +C -1 ; WX 600 ; N ydieresis ; B -21 -142 695 638 ; +C -1 ; WX 600 ; N Nacute ; B 8 -12 730 784 ; +C -1 ; WX 600 ; N icircumflex ; B 77 0 577 657 ; +C -1 ; WX 600 ; N Ecircumflex ; B 25 0 670 780 ; +C -1 ; WX 600 ; N adieresis ; B 61 -15 595 638 ; +C -1 ; WX 600 ; N edieresis ; B 81 -15 605 638 ; +C -1 ; WX 600 ; N cacute ; B 81 -15 649 661 ; +C -1 ; WX 600 ; N nacute ; B 18 0 639 661 ; +C -1 ; WX 600 ; N umacron ; B 70 -15 637 585 ; +C -1 ; WX 600 ; N Ncaron ; B 8 -12 730 790 ; +C -1 ; WX 600 ; N Iacute ; B 77 0 643 784 ; +C -1 ; WX 600 ; N plusminus ; B 76 24 614 515 ; +C -1 ; WX 600 ; N brokenbar ; B 217 -175 489 675 ; +C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N Gbreve ; B 74 -18 684 784 ; +C -1 ; WX 600 ; N Idotaccent ; B 77 0 643 761 ; +C -1 ; WX 600 ; N summation ; B 15 -10 672 706 ; +C -1 ; WX 600 ; N Egrave ; B 25 0 670 784 ; +C -1 ; WX 600 ; N racute ; B 47 0 655 661 ; +C -1 ; WX 600 ; N omacron ; B 71 -15 637 585 ; +C -1 ; WX 600 ; N Zacute ; B 62 0 665 784 ; +C -1 ; WX 600 ; N Zcaron ; B 62 0 659 790 ; +C -1 ; WX 600 ; N greaterequal ; B 26 0 627 696 ; +C -1 ; WX 600 ; N Eth ; B 30 0 664 562 ; +C -1 ; WX 600 ; N Ccedilla ; B 74 -206 675 580 ; +C -1 ; WX 600 ; N lcommaaccent ; B 77 -250 546 626 ; +C -1 ; WX 600 ; N tcaron ; B 118 -15 627 703 ; +C -1 ; WX 600 ; N eogonek ; B 81 -199 605 454 ; +C -1 ; WX 600 ; N Uogonek ; B 101 -199 716 562 ; +C -1 ; WX 600 ; N Aacute ; B -9 0 655 784 ; +C -1 ; WX 600 ; N Adieresis ; B -9 0 632 761 ; +C -1 ; WX 600 ; N egrave ; B 81 -15 605 661 ; +C -1 ; WX 600 ; N zacute ; B 81 0 614 661 ; +C -1 ; WX 600 ; N iogonek ; B 77 -199 546 658 ; +C -1 ; WX 600 ; N Oacute ; B 74 -18 645 784 ; +C -1 ; WX 600 ; N oacute ; B 71 -15 649 661 ; +C -1 ; WX 600 ; N amacron ; B 61 -15 637 585 ; +C -1 ; WX 600 ; N sacute ; B 66 -17 609 661 ; +C -1 ; WX 600 ; N idieresis ; B 77 0 561 618 ; +C -1 ; WX 600 ; N Ocircumflex ; B 74 -18 645 780 ; +C -1 ; WX 600 ; N Ugrave ; B 101 -18 716 784 ; +C -1 ; WX 600 ; N Delta ; B 6 0 594 688 ; +C -1 ; WX 600 ; N thorn ; B -32 -142 622 626 ; +C -1 ; WX 600 ; N twosuperior ; B 191 230 542 616 ; +C -1 ; WX 600 ; N Odieresis ; B 74 -18 645 761 ; +C -1 ; WX 600 ; N mu ; B 49 -142 592 439 ; +C -1 ; WX 600 ; N igrave ; B 77 0 546 661 ; +C -1 ; WX 600 ; N ohungarumlaut ; B 71 -15 809 661 ; +C -1 ; WX 600 ; N Eogonek ; B 25 -199 670 562 ; +C -1 ; WX 600 ; N dcroat ; B 60 -15 712 626 ; +C -1 ; WX 600 ; N threequarters ; B 8 -60 699 661 ; +C -1 ; WX 600 ; N Scedilla ; B 54 -206 673 582 ; +C -1 ; WX 600 ; N lcaron ; B 77 0 731 626 ; +C -1 ; WX 600 ; N Kcommaaccent ; B 21 -250 692 562 ; +C -1 ; WX 600 ; N Lacute ; B 39 0 636 784 ; +C -1 ; WX 600 ; N trademark ; B 86 230 869 562 ; +C -1 ; WX 600 ; N edotaccent ; B 81 -15 605 638 ; +C -1 ; WX 600 ; N Igrave ; B 77 0 643 784 ; +C -1 ; WX 600 ; N Imacron ; B 77 0 663 708 ; +C -1 ; WX 600 ; N Lcaron ; B 39 0 757 562 ; +C -1 ; WX 600 ; N onehalf ; B 22 -60 716 661 ; +C -1 ; WX 600 ; N lessequal ; B 26 0 671 696 ; +C -1 ; WX 600 ; N ocircumflex ; B 71 -15 622 657 ; +C -1 ; WX 600 ; N ntilde ; B 18 0 643 636 ; +C -1 ; WX 600 ; N Uhungarumlaut ; B 101 -18 805 784 ; +C -1 ; WX 600 ; N Eacute ; B 25 0 670 784 ; +C -1 ; WX 600 ; N emacron ; B 81 -15 637 585 ; +C -1 ; WX 600 ; N gbreve ; B 40 -146 674 661 ; +C -1 ; WX 600 ; N onequarter ; B 13 -60 707 661 ; +C -1 ; WX 600 ; N Scaron ; B 54 -22 689 790 ; +C -1 ; WX 600 ; N Scommaaccent ; B 54 -250 673 582 ; +C -1 ; WX 600 ; N Ohungarumlaut ; B 74 -18 795 784 ; +C -1 ; WX 600 ; N degree ; B 173 243 570 616 ; +C -1 ; WX 600 ; N ograve ; B 71 -15 622 661 ; +C -1 ; WX 600 ; N Ccaron ; B 74 -18 689 790 ; +C -1 ; WX 600 ; N ugrave ; B 70 -15 592 661 ; +C -1 ; WX 600 ; N radical ; B 67 -104 635 778 ; +C -1 ; WX 600 ; N Dcaron ; B 30 0 664 790 ; +C -1 ; WX 600 ; N rcommaaccent ; B 47 -250 655 454 ; +C -1 ; WX 600 ; N Ntilde ; B 8 -12 730 759 ; +C -1 ; WX 600 ; N otilde ; B 71 -15 643 636 ; +C -1 ; WX 600 ; N Rcommaaccent ; B 24 -250 617 562 ; +C -1 ; WX 600 ; N Lcommaaccent ; B 39 -250 636 562 ; +C -1 ; WX 600 ; N Atilde ; B -9 0 669 759 ; +C -1 ; WX 600 ; N Aogonek ; B -9 -199 632 562 ; +C -1 ; WX 600 ; N Aring ; B -9 0 632 801 ; +C -1 ; WX 600 ; N Otilde ; B 74 -18 669 759 ; +C -1 ; WX 600 ; N zdotaccent ; B 81 0 614 638 ; +C -1 ; WX 600 ; N Ecaron ; B 25 0 670 790 ; +C -1 ; WX 600 ; N Iogonek ; B 77 -199 643 562 ; +C -1 ; WX 600 ; N kcommaaccent ; B 33 -250 643 626 ; +C -1 ; WX 600 ; N minus ; B 114 203 596 313 ; +C -1 ; WX 600 ; N Icircumflex ; B 77 0 643 780 ; +C -1 ; WX 600 ; N ncaron ; B 18 0 633 667 ; +C -1 ; WX 600 ; N tcommaaccent ; B 118 -250 567 562 ; +C -1 ; WX 600 ; N logicalnot ; B 135 103 617 413 ; +C -1 ; WX 600 ; N odieresis ; B 71 -15 622 638 ; +C -1 ; WX 600 ; N udieresis ; B 70 -15 595 638 ; +C -1 ; WX 600 ; N notequal ; B 30 -47 626 563 ; +C -1 ; WX 600 ; N gcommaaccent ; B 40 -146 674 714 ; +C -1 ; WX 600 ; N eth ; B 93 -27 661 626 ; +C -1 ; WX 600 ; N zcaron ; B 81 0 643 667 ; +C -1 ; WX 600 ; N ncommaaccent ; B 18 -250 615 454 ; +C -1 ; WX 600 ; N onesuperior ; B 212 230 514 616 ; +C -1 ; WX 600 ; N imacron ; B 77 0 575 585 ; +C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics addfile ./Core14_AFMs/Courier-Oblique.afm hunk ./Core14_AFMs/Courier-Oblique.afm 1 +StartFontMetrics 4.1 +Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 17:37:52 1997 +Comment UniqueID 43051 +Comment VMusage 16248 75829 +FontName Courier-Oblique +FullName Courier Oblique +FamilyName Courier +Weight Medium +ItalicAngle -12 +IsFixedPitch true +CharacterSet ExtendedRoman +FontBBox -27 -250 849 805 +UnderlinePosition -100 +UnderlineThickness 50 +Version 003.000 +Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 562 +XHeight 426 +Ascender 629 +Descender -157 +StdHW 51 +StdVW 51 +StartCharMetrics 315 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 243 -15 464 572 ; +C 34 ; WX 600 ; N quotedbl ; B 273 328 532 562 ; +C 35 ; WX 600 ; N numbersign ; B 133 -32 596 639 ; +C 36 ; WX 600 ; N dollar ; B 108 -126 596 662 ; +C 37 ; WX 600 ; N percent ; B 134 -15 599 622 ; +C 38 ; WX 600 ; N ampersand ; B 87 -15 580 543 ; +C 39 ; WX 600 ; N quoteright ; B 283 328 495 562 ; +C 40 ; WX 600 ; N parenleft ; B 313 -108 572 622 ; +C 41 ; WX 600 ; N parenright ; B 137 -108 396 622 ; +C 42 ; WX 600 ; N asterisk ; B 212 257 580 607 ; +C 43 ; WX 600 ; N plus ; B 129 44 580 470 ; +C 44 ; WX 600 ; N comma ; B 157 -112 370 122 ; +C 45 ; WX 600 ; N hyphen ; B 152 231 558 285 ; +C 46 ; WX 600 ; N period ; B 238 -15 382 109 ; +C 47 ; WX 600 ; N slash ; B 112 -80 604 629 ; +C 48 ; WX 600 ; N zero ; B 154 -15 575 622 ; +C 49 ; WX 600 ; N one ; B 98 0 515 622 ; +C 50 ; WX 600 ; N two ; B 70 0 568 622 ; +C 51 ; WX 600 ; N three ; B 82 -15 538 622 ; +C 52 ; WX 600 ; N four ; B 108 0 541 622 ; +C 53 ; WX 600 ; N five ; B 99 -15 589 607 ; +C 54 ; WX 600 ; N six ; B 155 -15 629 622 ; +C 55 ; WX 600 ; N seven ; B 182 0 612 607 ; +C 56 ; WX 600 ; N eight ; B 132 -15 588 622 ; +C 57 ; WX 600 ; N nine ; B 93 -15 574 622 ; +C 58 ; WX 600 ; N colon ; B 238 -15 441 385 ; +C 59 ; WX 600 ; N semicolon ; B 157 -112 441 385 ; +C 60 ; WX 600 ; N less ; B 96 42 610 472 ; +C 61 ; WX 600 ; N equal ; B 109 138 600 376 ; +C 62 ; WX 600 ; N greater ; B 85 42 599 472 ; +C 63 ; WX 600 ; N question ; B 222 -15 583 572 ; +C 64 ; WX 600 ; N at ; B 127 -15 582 622 ; +C 65 ; WX 600 ; N A ; B 3 0 607 562 ; +C 66 ; WX 600 ; N B ; B 43 0 616 562 ; +C 67 ; WX 600 ; N C ; B 93 -18 655 580 ; +C 68 ; WX 600 ; N D ; B 43 0 645 562 ; +C 69 ; WX 600 ; N E ; B 53 0 660 562 ; +C 70 ; WX 600 ; N F ; B 53 0 660 562 ; +C 71 ; WX 600 ; N G ; B 83 -18 645 580 ; +C 72 ; WX 600 ; N H ; B 32 0 687 562 ; +C 73 ; WX 600 ; N I ; B 96 0 623 562 ; +C 74 ; WX 600 ; N J ; B 52 -18 685 562 ; +C 75 ; WX 600 ; N K ; B 38 0 671 562 ; +C 76 ; WX 600 ; N L ; B 47 0 607 562 ; +C 77 ; WX 600 ; N M ; B 4 0 715 562 ; +C 78 ; WX 600 ; N N ; B 7 -13 712 562 ; +C 79 ; WX 600 ; N O ; B 94 -18 625 580 ; +C 80 ; WX 600 ; N P ; B 79 0 644 562 ; +C 81 ; WX 600 ; N Q ; B 95 -138 625 580 ; +C 82 ; WX 600 ; N R ; B 38 0 598 562 ; +C 83 ; WX 600 ; N S ; B 76 -20 650 580 ; +C 84 ; WX 600 ; N T ; B 108 0 665 562 ; +C 85 ; WX 600 ; N U ; B 125 -18 702 562 ; +C 86 ; WX 600 ; N V ; B 105 -13 723 562 ; +C 87 ; WX 600 ; N W ; B 106 -13 722 562 ; +C 88 ; WX 600 ; N X ; B 23 0 675 562 ; +C 89 ; WX 600 ; N Y ; B 133 0 695 562 ; +C 90 ; WX 600 ; N Z ; B 86 0 610 562 ; +C 91 ; WX 600 ; N bracketleft ; B 246 -108 574 622 ; +C 92 ; WX 600 ; N backslash ; B 249 -80 468 629 ; +C 93 ; WX 600 ; N bracketright ; B 135 -108 463 622 ; +C 94 ; WX 600 ; N asciicircum ; B 175 354 587 622 ; +C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ; +C 96 ; WX 600 ; N quoteleft ; B 343 328 457 562 ; +C 97 ; WX 600 ; N a ; B 76 -15 569 441 ; +C 98 ; WX 600 ; N b ; B 29 -15 625 629 ; +C 99 ; WX 600 ; N c ; B 106 -15 608 441 ; +C 100 ; WX 600 ; N d ; B 85 -15 640 629 ; +C 101 ; WX 600 ; N e ; B 106 -15 598 441 ; +C 102 ; WX 600 ; N f ; B 114 0 662 629 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 61 -157 657 441 ; +C 104 ; WX 600 ; N h ; B 33 0 592 629 ; +C 105 ; WX 600 ; N i ; B 95 0 515 657 ; +C 106 ; WX 600 ; N j ; B 52 -157 550 657 ; +C 107 ; WX 600 ; N k ; B 58 0 633 629 ; +C 108 ; WX 600 ; N l ; B 95 0 515 629 ; +C 109 ; WX 600 ; N m ; B -5 0 615 441 ; +C 110 ; WX 600 ; N n ; B 26 0 585 441 ; +C 111 ; WX 600 ; N o ; B 102 -15 588 441 ; +C 112 ; WX 600 ; N p ; B -24 -157 605 441 ; +C 113 ; WX 600 ; N q ; B 85 -157 682 441 ; +C 114 ; WX 600 ; N r ; B 60 0 636 441 ; +C 115 ; WX 600 ; N s ; B 78 -15 584 441 ; +C 116 ; WX 600 ; N t ; B 167 -15 561 561 ; +C 117 ; WX 600 ; N u ; B 101 -15 572 426 ; +C 118 ; WX 600 ; N v ; B 90 -10 681 426 ; +C 119 ; WX 600 ; N w ; B 76 -10 695 426 ; +C 120 ; WX 600 ; N x ; B 20 0 655 426 ; +C 121 ; WX 600 ; N y ; B -4 -157 683 426 ; +C 122 ; WX 600 ; N z ; B 99 0 593 426 ; +C 123 ; WX 600 ; N braceleft ; B 233 -108 569 622 ; +C 124 ; WX 600 ; N bar ; B 222 -250 485 750 ; +C 125 ; WX 600 ; N braceright ; B 140 -108 477 622 ; +C 126 ; WX 600 ; N asciitilde ; B 116 197 600 320 ; +C 161 ; WX 600 ; N exclamdown ; B 225 -157 445 430 ; +C 162 ; WX 600 ; N cent ; B 151 -49 588 614 ; +C 163 ; WX 600 ; N sterling ; B 124 -21 621 611 ; +C 164 ; WX 600 ; N fraction ; B 84 -57 646 665 ; +C 165 ; WX 600 ; N yen ; B 120 0 693 562 ; +C 166 ; WX 600 ; N florin ; B -26 -143 671 622 ; +C 167 ; WX 600 ; N section ; B 104 -78 590 580 ; +C 168 ; WX 600 ; N currency ; B 94 58 628 506 ; +C 169 ; WX 600 ; N quotesingle ; B 345 328 460 562 ; +C 170 ; WX 600 ; N quotedblleft ; B 262 328 541 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 92 70 652 446 ; +C 172 ; WX 600 ; N guilsinglleft ; B 204 70 540 446 ; +C 173 ; WX 600 ; N guilsinglright ; B 170 70 506 446 ; +C 174 ; WX 600 ; N fi ; B 3 0 619 629 ; +C 175 ; WX 600 ; N fl ; B 3 0 619 629 ; +C 177 ; WX 600 ; N endash ; B 124 231 586 285 ; +C 178 ; WX 600 ; N dagger ; B 217 -78 546 580 ; +C 179 ; WX 600 ; N daggerdbl ; B 163 -78 546 580 ; +C 180 ; WX 600 ; N periodcentered ; B 275 189 434 327 ; +C 182 ; WX 600 ; N paragraph ; B 100 -78 630 562 ; +C 183 ; WX 600 ; N bullet ; B 224 130 485 383 ; +C 184 ; WX 600 ; N quotesinglbase ; B 185 -134 397 100 ; +C 185 ; WX 600 ; N quotedblbase ; B 115 -134 478 100 ; +C 186 ; WX 600 ; N quotedblright ; B 213 328 576 562 ; +C 187 ; WX 600 ; N guillemotright ; B 58 70 618 446 ; +C 188 ; WX 600 ; N ellipsis ; B 46 -15 575 111 ; +C 189 ; WX 600 ; N perthousand ; B 59 -15 627 622 ; +C 191 ; WX 600 ; N questiondown ; B 105 -157 466 430 ; +C 193 ; WX 600 ; N grave ; B 294 497 484 672 ; +C 194 ; WX 600 ; N acute ; B 348 497 612 672 ; +C 195 ; WX 600 ; N circumflex ; B 229 477 581 654 ; +C 196 ; WX 600 ; N tilde ; B 212 489 629 606 ; +C 197 ; WX 600 ; N macron ; B 232 525 600 565 ; +C 198 ; WX 600 ; N breve ; B 279 501 576 609 ; +C 199 ; WX 600 ; N dotaccent ; B 373 537 478 640 ; +C 200 ; WX 600 ; N dieresis ; B 272 537 579 640 ; +C 202 ; WX 600 ; N ring ; B 332 463 500 627 ; +C 203 ; WX 600 ; N cedilla ; B 197 -151 344 10 ; +C 205 ; WX 600 ; N hungarumlaut ; B 239 497 683 672 ; +C 206 ; WX 600 ; N ogonek ; B 189 -172 377 4 ; +C 207 ; WX 600 ; N caron ; B 262 492 614 669 ; +C 208 ; WX 600 ; N emdash ; B 49 231 661 285 ; +C 225 ; WX 600 ; N AE ; B 3 0 655 562 ; +C 227 ; WX 600 ; N ordfeminine ; B 209 249 512 580 ; +C 232 ; WX 600 ; N Lslash ; B 47 0 607 562 ; +C 233 ; WX 600 ; N Oslash ; B 94 -80 625 629 ; +C 234 ; WX 600 ; N OE ; B 59 0 672 562 ; +C 235 ; WX 600 ; N ordmasculine ; B 210 249 535 580 ; +C 241 ; WX 600 ; N ae ; B 41 -15 626 441 ; +C 245 ; WX 600 ; N dotlessi ; B 95 0 515 426 ; +C 248 ; WX 600 ; N lslash ; B 95 0 587 629 ; +C 249 ; WX 600 ; N oslash ; B 102 -80 588 506 ; +C 250 ; WX 600 ; N oe ; B 54 -15 615 441 ; +C 251 ; WX 600 ; N germandbls ; B 48 -15 617 629 ; +C -1 ; WX 600 ; N Idieresis ; B 96 0 623 753 ; +C -1 ; WX 600 ; N eacute ; B 106 -15 612 672 ; +C -1 ; WX 600 ; N abreve ; B 76 -15 576 609 ; +C -1 ; WX 600 ; N uhungarumlaut ; B 101 -15 723 672 ; +C -1 ; WX 600 ; N ecaron ; B 106 -15 614 669 ; +C -1 ; WX 600 ; N Ydieresis ; B 133 0 695 753 ; +C -1 ; WX 600 ; N divide ; B 136 48 573 467 ; +C -1 ; WX 600 ; N Yacute ; B 133 0 695 805 ; +C -1 ; WX 600 ; N Acircumflex ; B 3 0 607 787 ; +C -1 ; WX 600 ; N aacute ; B 76 -15 612 672 ; +C -1 ; WX 600 ; N Ucircumflex ; B 125 -18 702 787 ; +C -1 ; WX 600 ; N yacute ; B -4 -157 683 672 ; +C -1 ; WX 600 ; N scommaaccent ; B 78 -250 584 441 ; +C -1 ; WX 600 ; N ecircumflex ; B 106 -15 598 654 ; +C -1 ; WX 600 ; N Uring ; B 125 -18 702 760 ; +C -1 ; WX 600 ; N Udieresis ; B 125 -18 702 753 ; +C -1 ; WX 600 ; N aogonek ; B 76 -172 569 441 ; +C -1 ; WX 600 ; N Uacute ; B 125 -18 702 805 ; +C -1 ; WX 600 ; N uogonek ; B 101 -172 572 426 ; +C -1 ; WX 600 ; N Edieresis ; B 53 0 660 753 ; +C -1 ; WX 600 ; N Dcroat ; B 43 0 645 562 ; +C -1 ; WX 600 ; N commaaccent ; B 145 -250 323 -58 ; +C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N Emacron ; B 53 0 660 698 ; +C -1 ; WX 600 ; N ccaron ; B 106 -15 614 669 ; +C -1 ; WX 600 ; N aring ; B 76 -15 569 627 ; +C -1 ; WX 600 ; N Ncommaaccent ; B 7 -250 712 562 ; +C -1 ; WX 600 ; N lacute ; B 95 0 640 805 ; +C -1 ; WX 600 ; N agrave ; B 76 -15 569 672 ; +C -1 ; WX 600 ; N Tcommaaccent ; B 108 -250 665 562 ; +C -1 ; WX 600 ; N Cacute ; B 93 -18 655 805 ; +C -1 ; WX 600 ; N atilde ; B 76 -15 629 606 ; +C -1 ; WX 600 ; N Edotaccent ; B 53 0 660 753 ; +C -1 ; WX 600 ; N scaron ; B 78 -15 614 669 ; +C -1 ; WX 600 ; N scedilla ; B 78 -151 584 441 ; +C -1 ; WX 600 ; N iacute ; B 95 0 612 672 ; +C -1 ; WX 600 ; N lozenge ; B 94 0 519 706 ; +C -1 ; WX 600 ; N Rcaron ; B 38 0 642 802 ; +C -1 ; WX 600 ; N Gcommaaccent ; B 83 -250 645 580 ; +C -1 ; WX 600 ; N ucircumflex ; B 101 -15 572 654 ; +C -1 ; WX 600 ; N acircumflex ; B 76 -15 581 654 ; +C -1 ; WX 600 ; N Amacron ; B 3 0 607 698 ; +C -1 ; WX 600 ; N rcaron ; B 60 0 636 669 ; +C -1 ; WX 600 ; N ccedilla ; B 106 -151 614 441 ; +C -1 ; WX 600 ; N Zdotaccent ; B 86 0 610 753 ; +C -1 ; WX 600 ; N Thorn ; B 79 0 606 562 ; +C -1 ; WX 600 ; N Omacron ; B 94 -18 628 698 ; +C -1 ; WX 600 ; N Racute ; B 38 0 670 805 ; +C -1 ; WX 600 ; N Sacute ; B 76 -20 650 805 ; +C -1 ; WX 600 ; N dcaron ; B 85 -15 849 629 ; +C -1 ; WX 600 ; N Umacron ; B 125 -18 702 698 ; +C -1 ; WX 600 ; N uring ; B 101 -15 572 627 ; +C -1 ; WX 600 ; N threesuperior ; B 213 240 501 622 ; +C -1 ; WX 600 ; N Ograve ; B 94 -18 625 805 ; +C -1 ; WX 600 ; N Agrave ; B 3 0 607 805 ; +C -1 ; WX 600 ; N Abreve ; B 3 0 607 732 ; +C -1 ; WX 600 ; N multiply ; B 103 43 607 470 ; +C -1 ; WX 600 ; N uacute ; B 101 -15 602 672 ; +C -1 ; WX 600 ; N Tcaron ; B 108 0 665 802 ; +C -1 ; WX 600 ; N partialdiff ; B 45 -38 546 710 ; +C -1 ; WX 600 ; N ydieresis ; B -4 -157 683 620 ; +C -1 ; WX 600 ; N Nacute ; B 7 -13 712 805 ; +C -1 ; WX 600 ; N icircumflex ; B 95 0 551 654 ; +C -1 ; WX 600 ; N Ecircumflex ; B 53 0 660 787 ; +C -1 ; WX 600 ; N adieresis ; B 76 -15 575 620 ; +C -1 ; WX 600 ; N edieresis ; B 106 -15 598 620 ; +C -1 ; WX 600 ; N cacute ; B 106 -15 612 672 ; +C -1 ; WX 600 ; N nacute ; B 26 0 602 672 ; +C -1 ; WX 600 ; N umacron ; B 101 -15 600 565 ; +C -1 ; WX 600 ; N Ncaron ; B 7 -13 712 802 ; +C -1 ; WX 600 ; N Iacute ; B 96 0 640 805 ; +C -1 ; WX 600 ; N plusminus ; B 96 44 594 558 ; +C -1 ; WX 600 ; N brokenbar ; B 238 -175 469 675 ; +C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N Gbreve ; B 83 -18 645 732 ; +C -1 ; WX 600 ; N Idotaccent ; B 96 0 623 753 ; +C -1 ; WX 600 ; N summation ; B 15 -10 670 706 ; +C -1 ; WX 600 ; N Egrave ; B 53 0 660 805 ; +C -1 ; WX 600 ; N racute ; B 60 0 636 672 ; +C -1 ; WX 600 ; N omacron ; B 102 -15 600 565 ; +C -1 ; WX 600 ; N Zacute ; B 86 0 670 805 ; +C -1 ; WX 600 ; N Zcaron ; B 86 0 642 802 ; +C -1 ; WX 600 ; N greaterequal ; B 98 0 594 710 ; +C -1 ; WX 600 ; N Eth ; B 43 0 645 562 ; +C -1 ; WX 600 ; N Ccedilla ; B 93 -151 658 580 ; +C -1 ; WX 600 ; N lcommaaccent ; B 95 -250 515 629 ; +C -1 ; WX 600 ; N tcaron ; B 167 -15 587 717 ; +C -1 ; WX 600 ; N eogonek ; B 106 -172 598 441 ; +C -1 ; WX 600 ; N Uogonek ; B 124 -172 702 562 ; +C -1 ; WX 600 ; N Aacute ; B 3 0 660 805 ; +C -1 ; WX 600 ; N Adieresis ; B 3 0 607 753 ; +C -1 ; WX 600 ; N egrave ; B 106 -15 598 672 ; +C -1 ; WX 600 ; N zacute ; B 99 0 612 672 ; +C -1 ; WX 600 ; N iogonek ; B 95 -172 515 657 ; +C -1 ; WX 600 ; N Oacute ; B 94 -18 640 805 ; +C -1 ; WX 600 ; N oacute ; B 102 -15 612 672 ; +C -1 ; WX 600 ; N amacron ; B 76 -15 600 565 ; +C -1 ; WX 600 ; N sacute ; B 78 -15 612 672 ; +C -1 ; WX 600 ; N idieresis ; B 95 0 545 620 ; +C -1 ; WX 600 ; N Ocircumflex ; B 94 -18 625 787 ; +C -1 ; WX 600 ; N Ugrave ; B 125 -18 702 805 ; +C -1 ; WX 600 ; N Delta ; B 6 0 598 688 ; +C -1 ; WX 600 ; N thorn ; B -24 -157 605 629 ; +C -1 ; WX 600 ; N twosuperior ; B 230 249 535 622 ; +C -1 ; WX 600 ; N Odieresis ; B 94 -18 625 753 ; +C -1 ; WX 600 ; N mu ; B 72 -157 572 426 ; +C -1 ; WX 600 ; N igrave ; B 95 0 515 672 ; +C -1 ; WX 600 ; N ohungarumlaut ; B 102 -15 723 672 ; +C -1 ; WX 600 ; N Eogonek ; B 53 -172 660 562 ; +C -1 ; WX 600 ; N dcroat ; B 85 -15 704 629 ; +C -1 ; WX 600 ; N threequarters ; B 73 -56 659 666 ; +C -1 ; WX 600 ; N Scedilla ; B 76 -151 650 580 ; +C -1 ; WX 600 ; N lcaron ; B 95 0 667 629 ; +C -1 ; WX 600 ; N Kcommaaccent ; B 38 -250 671 562 ; +C -1 ; WX 600 ; N Lacute ; B 47 0 607 805 ; +C -1 ; WX 600 ; N trademark ; B 75 263 742 562 ; +C -1 ; WX 600 ; N edotaccent ; B 106 -15 598 620 ; +C -1 ; WX 600 ; N Igrave ; B 96 0 623 805 ; +C -1 ; WX 600 ; N Imacron ; B 96 0 628 698 ; +C -1 ; WX 600 ; N Lcaron ; B 47 0 632 562 ; +C -1 ; WX 600 ; N onehalf ; B 65 -57 669 665 ; +C -1 ; WX 600 ; N lessequal ; B 98 0 645 710 ; +C -1 ; WX 600 ; N ocircumflex ; B 102 -15 588 654 ; +C -1 ; WX 600 ; N ntilde ; B 26 0 629 606 ; +C -1 ; WX 600 ; N Uhungarumlaut ; B 125 -18 761 805 ; +C -1 ; WX 600 ; N Eacute ; B 53 0 670 805 ; +C -1 ; WX 600 ; N emacron ; B 106 -15 600 565 ; +C -1 ; WX 600 ; N gbreve ; B 61 -157 657 609 ; +C -1 ; WX 600 ; N onequarter ; B 65 -57 674 665 ; +C -1 ; WX 600 ; N Scaron ; B 76 -20 672 802 ; +C -1 ; WX 600 ; N Scommaaccent ; B 76 -250 650 580 ; +C -1 ; WX 600 ; N Ohungarumlaut ; B 94 -18 751 805 ; +C -1 ; WX 600 ; N degree ; B 214 269 576 622 ; +C -1 ; WX 600 ; N ograve ; B 102 -15 588 672 ; +C -1 ; WX 600 ; N Ccaron ; B 93 -18 672 802 ; +C -1 ; WX 600 ; N ugrave ; B 101 -15 572 672 ; +C -1 ; WX 600 ; N radical ; B 85 -15 765 792 ; +C -1 ; WX 600 ; N Dcaron ; B 43 0 645 802 ; +C -1 ; WX 600 ; N rcommaaccent ; B 60 -250 636 441 ; +C -1 ; WX 600 ; N Ntilde ; B 7 -13 712 729 ; +C -1 ; WX 600 ; N otilde ; B 102 -15 629 606 ; +C -1 ; WX 600 ; N Rcommaaccent ; B 38 -250 598 562 ; +C -1 ; WX 600 ; N Lcommaaccent ; B 47 -250 607 562 ; +C -1 ; WX 600 ; N Atilde ; B 3 0 655 729 ; +C -1 ; WX 600 ; N Aogonek ; B 3 -172 607 562 ; +C -1 ; WX 600 ; N Aring ; B 3 0 607 750 ; +C -1 ; WX 600 ; N Otilde ; B 94 -18 655 729 ; +C -1 ; WX 600 ; N zdotaccent ; B 99 0 593 620 ; +C -1 ; WX 600 ; N Ecaron ; B 53 0 660 802 ; +C -1 ; WX 600 ; N Iogonek ; B 96 -172 623 562 ; +C -1 ; WX 600 ; N kcommaaccent ; B 58 -250 633 629 ; +C -1 ; WX 600 ; N minus ; B 129 232 580 283 ; +C -1 ; WX 600 ; N Icircumflex ; B 96 0 623 787 ; +C -1 ; WX 600 ; N ncaron ; B 26 0 614 669 ; +C -1 ; WX 600 ; N tcommaaccent ; B 165 -250 561 561 ; +C -1 ; WX 600 ; N logicalnot ; B 155 108 591 369 ; +C -1 ; WX 600 ; N odieresis ; B 102 -15 588 620 ; +C -1 ; WX 600 ; N udieresis ; B 101 -15 575 620 ; +C -1 ; WX 600 ; N notequal ; B 43 -16 621 529 ; +C -1 ; WX 600 ; N gcommaaccent ; B 61 -157 657 708 ; +C -1 ; WX 600 ; N eth ; B 102 -15 639 629 ; +C -1 ; WX 600 ; N zcaron ; B 99 0 624 669 ; +C -1 ; WX 600 ; N ncommaaccent ; B 26 -250 585 441 ; +C -1 ; WX 600 ; N onesuperior ; B 231 249 491 622 ; +C -1 ; WX 600 ; N imacron ; B 95 0 543 565 ; +C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics addfile ./Core14_AFMs/Courier.afm hunk ./Core14_AFMs/Courier.afm 1 +StartFontMetrics 4.1 +Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 17:27:09 1997 +Comment UniqueID 43050 +Comment VMusage 39754 50779 +FontName Courier +FullName Courier +FamilyName Courier +Weight Medium +ItalicAngle 0 +IsFixedPitch true +CharacterSet ExtendedRoman +FontBBox -23 -250 715 805 +UnderlinePosition -100 +UnderlineThickness 50 +Version 003.000 +Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme AdobeStandardEncoding +CapHeight 562 +XHeight 426 +Ascender 629 +Descender -157 +StdHW 51 +StdVW 51 +StartCharMetrics 315 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 236 -15 364 572 ; +C 34 ; WX 600 ; N quotedbl ; B 187 328 413 562 ; +C 35 ; WX 600 ; N numbersign ; B 93 -32 507 639 ; +C 36 ; WX 600 ; N dollar ; B 105 -126 496 662 ; +C 37 ; WX 600 ; N percent ; B 81 -15 518 622 ; +C 38 ; WX 600 ; N ampersand ; B 63 -15 538 543 ; +C 39 ; WX 600 ; N quoteright ; B 213 328 376 562 ; +C 40 ; WX 600 ; N parenleft ; B 269 -108 440 622 ; +C 41 ; WX 600 ; N parenright ; B 160 -108 331 622 ; +C 42 ; WX 600 ; N asterisk ; B 116 257 484 607 ; +C 43 ; WX 600 ; N plus ; B 80 44 520 470 ; +C 44 ; WX 600 ; N comma ; B 181 -112 344 122 ; +C 45 ; WX 600 ; N hyphen ; B 103 231 497 285 ; +C 46 ; WX 600 ; N period ; B 229 -15 371 109 ; +C 47 ; WX 600 ; N slash ; B 125 -80 475 629 ; +C 48 ; WX 600 ; N zero ; B 106 -15 494 622 ; +C 49 ; WX 600 ; N one ; B 96 0 505 622 ; +C 50 ; WX 600 ; N two ; B 70 0 471 622 ; +C 51 ; WX 600 ; N three ; B 75 -15 466 622 ; +C 52 ; WX 600 ; N four ; B 78 0 500 622 ; +C 53 ; WX 600 ; N five ; B 92 -15 497 607 ; +C 54 ; WX 600 ; N six ; B 111 -15 497 622 ; +C 55 ; WX 600 ; N seven ; B 82 0 483 607 ; +C 56 ; WX 600 ; N eight ; B 102 -15 498 622 ; +C 57 ; WX 600 ; N nine ; B 96 -15 489 622 ; +C 58 ; WX 600 ; N colon ; B 229 -15 371 385 ; +C 59 ; WX 600 ; N semicolon ; B 181 -112 371 385 ; +C 60 ; WX 600 ; N less ; B 41 42 519 472 ; +C 61 ; WX 600 ; N equal ; B 80 138 520 376 ; +C 62 ; WX 600 ; N greater ; B 66 42 544 472 ; +C 63 ; WX 600 ; N question ; B 129 -15 492 572 ; +C 64 ; WX 600 ; N at ; B 77 -15 533 622 ; +C 65 ; WX 600 ; N A ; B 3 0 597 562 ; +C 66 ; WX 600 ; N B ; B 43 0 559 562 ; +C 67 ; WX 600 ; N C ; B 41 -18 540 580 ; +C 68 ; WX 600 ; N D ; B 43 0 574 562 ; +C 69 ; WX 600 ; N E ; B 53 0 550 562 ; +C 70 ; WX 600 ; N F ; B 53 0 545 562 ; +C 71 ; WX 600 ; N G ; B 31 -18 575 580 ; +C 72 ; WX 600 ; N H ; B 32 0 568 562 ; +C 73 ; WX 600 ; N I ; B 96 0 504 562 ; +C 74 ; WX 600 ; N J ; B 34 -18 566 562 ; +C 75 ; WX 600 ; N K ; B 38 0 582 562 ; +C 76 ; WX 600 ; N L ; B 47 0 554 562 ; +C 77 ; WX 600 ; N M ; B 4 0 596 562 ; +C 78 ; WX 600 ; N N ; B 7 -13 593 562 ; +C 79 ; WX 600 ; N O ; B 43 -18 557 580 ; +C 80 ; WX 600 ; N P ; B 79 0 558 562 ; +C 81 ; WX 600 ; N Q ; B 43 -138 557 580 ; +C 82 ; WX 600 ; N R ; B 38 0 588 562 ; +C 83 ; WX 600 ; N S ; B 72 -20 529 580 ; +C 84 ; WX 600 ; N T ; B 38 0 563 562 ; +C 85 ; WX 600 ; N U ; B 17 -18 583 562 ; +C 86 ; WX 600 ; N V ; B -4 -13 604 562 ; +C 87 ; WX 600 ; N W ; B -3 -13 603 562 ; +C 88 ; WX 600 ; N X ; B 23 0 577 562 ; +C 89 ; WX 600 ; N Y ; B 24 0 576 562 ; +C 90 ; WX 600 ; N Z ; B 86 0 514 562 ; +C 91 ; WX 600 ; N bracketleft ; B 269 -108 442 622 ; +C 92 ; WX 600 ; N backslash ; B 118 -80 482 629 ; +C 93 ; WX 600 ; N bracketright ; B 158 -108 331 622 ; +C 94 ; WX 600 ; N asciicircum ; B 94 354 506 622 ; +C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ; +C 96 ; WX 600 ; N quoteleft ; B 224 328 387 562 ; +C 97 ; WX 600 ; N a ; B 53 -15 559 441 ; +C 98 ; WX 600 ; N b ; B 14 -15 575 629 ; +C 99 ; WX 600 ; N c ; B 66 -15 529 441 ; +C 100 ; WX 600 ; N d ; B 45 -15 591 629 ; +C 101 ; WX 600 ; N e ; B 66 -15 548 441 ; +C 102 ; WX 600 ; N f ; B 114 0 531 629 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 45 -157 566 441 ; +C 104 ; WX 600 ; N h ; B 18 0 582 629 ; +C 105 ; WX 600 ; N i ; B 95 0 505 657 ; +C 106 ; WX 600 ; N j ; B 82 -157 410 657 ; +C 107 ; WX 600 ; N k ; B 43 0 580 629 ; +C 108 ; WX 600 ; N l ; B 95 0 505 629 ; +C 109 ; WX 600 ; N m ; B -5 0 605 441 ; +C 110 ; WX 600 ; N n ; B 26 0 575 441 ; +C 111 ; WX 600 ; N o ; B 62 -15 538 441 ; +C 112 ; WX 600 ; N p ; B 9 -157 555 441 ; +C 113 ; WX 600 ; N q ; B 45 -157 591 441 ; +C 114 ; WX 600 ; N r ; B 60 0 559 441 ; +C 115 ; WX 600 ; N s ; B 80 -15 513 441 ; +C 116 ; WX 600 ; N t ; B 87 -15 530 561 ; +C 117 ; WX 600 ; N u ; B 21 -15 562 426 ; +C 118 ; WX 600 ; N v ; B 10 -10 590 426 ; +C 119 ; WX 600 ; N w ; B -4 -10 604 426 ; +C 120 ; WX 600 ; N x ; B 20 0 580 426 ; +C 121 ; WX 600 ; N y ; B 7 -157 592 426 ; +C 122 ; WX 600 ; N z ; B 99 0 502 426 ; +C 123 ; WX 600 ; N braceleft ; B 182 -108 437 622 ; +C 124 ; WX 600 ; N bar ; B 275 -250 326 750 ; +C 125 ; WX 600 ; N braceright ; B 163 -108 418 622 ; +C 126 ; WX 600 ; N asciitilde ; B 63 197 540 320 ; +C 161 ; WX 600 ; N exclamdown ; B 236 -157 364 430 ; +C 162 ; WX 600 ; N cent ; B 96 -49 500 614 ; +C 163 ; WX 600 ; N sterling ; B 84 -21 521 611 ; +C 164 ; WX 600 ; N fraction ; B 92 -57 509 665 ; +C 165 ; WX 600 ; N yen ; B 26 0 574 562 ; +C 166 ; WX 600 ; N florin ; B 4 -143 539 622 ; +C 167 ; WX 600 ; N section ; B 113 -78 488 580 ; +C 168 ; WX 600 ; N currency ; B 73 58 527 506 ; +C 169 ; WX 600 ; N quotesingle ; B 259 328 341 562 ; +C 170 ; WX 600 ; N quotedblleft ; B 143 328 471 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 37 70 563 446 ; +C 172 ; WX 600 ; N guilsinglleft ; B 149 70 451 446 ; +C 173 ; WX 600 ; N guilsinglright ; B 149 70 451 446 ; +C 174 ; WX 600 ; N fi ; B 3 0 597 629 ; +C 175 ; WX 600 ; N fl ; B 3 0 597 629 ; +C 177 ; WX 600 ; N endash ; B 75 231 525 285 ; +C 178 ; WX 600 ; N dagger ; B 141 -78 459 580 ; +C 179 ; WX 600 ; N daggerdbl ; B 141 -78 459 580 ; +C 180 ; WX 600 ; N periodcentered ; B 222 189 378 327 ; +C 182 ; WX 600 ; N paragraph ; B 50 -78 511 562 ; +C 183 ; WX 600 ; N bullet ; B 172 130 428 383 ; +C 184 ; WX 600 ; N quotesinglbase ; B 213 -134 376 100 ; +C 185 ; WX 600 ; N quotedblbase ; B 143 -134 457 100 ; +C 186 ; WX 600 ; N quotedblright ; B 143 328 457 562 ; +C 187 ; WX 600 ; N guillemotright ; B 37 70 563 446 ; +C 188 ; WX 600 ; N ellipsis ; B 37 -15 563 111 ; +C 189 ; WX 600 ; N perthousand ; B 3 -15 600 622 ; +C 191 ; WX 600 ; N questiondown ; B 108 -157 471 430 ; +C 193 ; WX 600 ; N grave ; B 151 497 378 672 ; +C 194 ; WX 600 ; N acute ; B 242 497 469 672 ; +C 195 ; WX 600 ; N circumflex ; B 124 477 476 654 ; +C 196 ; WX 600 ; N tilde ; B 105 489 503 606 ; +C 197 ; WX 600 ; N macron ; B 120 525 480 565 ; +C 198 ; WX 600 ; N breve ; B 153 501 447 609 ; +C 199 ; WX 600 ; N dotaccent ; B 249 537 352 640 ; +C 200 ; WX 600 ; N dieresis ; B 148 537 453 640 ; +C 202 ; WX 600 ; N ring ; B 218 463 382 627 ; +C 203 ; WX 600 ; N cedilla ; B 224 -151 362 10 ; +C 205 ; WX 600 ; N hungarumlaut ; B 133 497 540 672 ; +C 206 ; WX 600 ; N ogonek ; B 211 -172 407 4 ; +C 207 ; WX 600 ; N caron ; B 124 492 476 669 ; +C 208 ; WX 600 ; N emdash ; B 0 231 600 285 ; +C 225 ; WX 600 ; N AE ; B 3 0 550 562 ; +C 227 ; WX 600 ; N ordfeminine ; B 156 249 442 580 ; +C 232 ; WX 600 ; N Lslash ; B 47 0 554 562 ; +C 233 ; WX 600 ; N Oslash ; B 43 -80 557 629 ; +C 234 ; WX 600 ; N OE ; B 7 0 567 562 ; +C 235 ; WX 600 ; N ordmasculine ; B 157 249 443 580 ; +C 241 ; WX 600 ; N ae ; B 19 -15 570 441 ; +C 245 ; WX 600 ; N dotlessi ; B 95 0 505 426 ; +C 248 ; WX 600 ; N lslash ; B 95 0 505 629 ; +C 249 ; WX 600 ; N oslash ; B 62 -80 538 506 ; +C 250 ; WX 600 ; N oe ; B 19 -15 559 441 ; +C 251 ; WX 600 ; N germandbls ; B 48 -15 588 629 ; +C -1 ; WX 600 ; N Idieresis ; B 96 0 504 753 ; +C -1 ; WX 600 ; N eacute ; B 66 -15 548 672 ; +C -1 ; WX 600 ; N abreve ; B 53 -15 559 609 ; +C -1 ; WX 600 ; N uhungarumlaut ; B 21 -15 580 672 ; +C -1 ; WX 600 ; N ecaron ; B 66 -15 548 669 ; +C -1 ; WX 600 ; N Ydieresis ; B 24 0 576 753 ; +C -1 ; WX 600 ; N divide ; B 87 48 513 467 ; +C -1 ; WX 600 ; N Yacute ; B 24 0 576 805 ; +C -1 ; WX 600 ; N Acircumflex ; B 3 0 597 787 ; +C -1 ; WX 600 ; N aacute ; B 53 -15 559 672 ; +C -1 ; WX 600 ; N Ucircumflex ; B 17 -18 583 787 ; +C -1 ; WX 600 ; N yacute ; B 7 -157 592 672 ; +C -1 ; WX 600 ; N scommaaccent ; B 80 -250 513 441 ; +C -1 ; WX 600 ; N ecircumflex ; B 66 -15 548 654 ; +C -1 ; WX 600 ; N Uring ; B 17 -18 583 760 ; +C -1 ; WX 600 ; N Udieresis ; B 17 -18 583 753 ; +C -1 ; WX 600 ; N aogonek ; B 53 -172 587 441 ; +C -1 ; WX 600 ; N Uacute ; B 17 -18 583 805 ; +C -1 ; WX 600 ; N uogonek ; B 21 -172 590 426 ; +C -1 ; WX 600 ; N Edieresis ; B 53 0 550 753 ; +C -1 ; WX 600 ; N Dcroat ; B 30 0 574 562 ; +C -1 ; WX 600 ; N commaaccent ; B 198 -250 335 -58 ; +C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N Emacron ; B 53 0 550 698 ; +C -1 ; WX 600 ; N ccaron ; B 66 -15 529 669 ; +C -1 ; WX 600 ; N aring ; B 53 -15 559 627 ; +C -1 ; WX 600 ; N Ncommaaccent ; B 7 -250 593 562 ; +C -1 ; WX 600 ; N lacute ; B 95 0 505 805 ; +C -1 ; WX 600 ; N agrave ; B 53 -15 559 672 ; +C -1 ; WX 600 ; N Tcommaaccent ; B 38 -250 563 562 ; +C -1 ; WX 600 ; N Cacute ; B 41 -18 540 805 ; +C -1 ; WX 600 ; N atilde ; B 53 -15 559 606 ; +C -1 ; WX 600 ; N Edotaccent ; B 53 0 550 753 ; +C -1 ; WX 600 ; N scaron ; B 80 -15 513 669 ; +C -1 ; WX 600 ; N scedilla ; B 80 -151 513 441 ; +C -1 ; WX 600 ; N iacute ; B 95 0 505 672 ; +C -1 ; WX 600 ; N lozenge ; B 18 0 443 706 ; +C -1 ; WX 600 ; N Rcaron ; B 38 0 588 802 ; +C -1 ; WX 600 ; N Gcommaaccent ; B 31 -250 575 580 ; +C -1 ; WX 600 ; N ucircumflex ; B 21 -15 562 654 ; +C -1 ; WX 600 ; N acircumflex ; B 53 -15 559 654 ; +C -1 ; WX 600 ; N Amacron ; B 3 0 597 698 ; +C -1 ; WX 600 ; N rcaron ; B 60 0 559 669 ; +C -1 ; WX 600 ; N ccedilla ; B 66 -151 529 441 ; +C -1 ; WX 600 ; N Zdotaccent ; B 86 0 514 753 ; +C -1 ; WX 600 ; N Thorn ; B 79 0 538 562 ; +C -1 ; WX 600 ; N Omacron ; B 43 -18 557 698 ; +C -1 ; WX 600 ; N Racute ; B 38 0 588 805 ; +C -1 ; WX 600 ; N Sacute ; B 72 -20 529 805 ; +C -1 ; WX 600 ; N dcaron ; B 45 -15 715 629 ; +C -1 ; WX 600 ; N Umacron ; B 17 -18 583 698 ; +C -1 ; WX 600 ; N uring ; B 21 -15 562 627 ; +C -1 ; WX 600 ; N threesuperior ; B 155 240 406 622 ; +C -1 ; WX 600 ; N Ograve ; B 43 -18 557 805 ; +C -1 ; WX 600 ; N Agrave ; B 3 0 597 805 ; +C -1 ; WX 600 ; N Abreve ; B 3 0 597 732 ; +C -1 ; WX 600 ; N multiply ; B 87 43 515 470 ; +C -1 ; WX 600 ; N uacute ; B 21 -15 562 672 ; +C -1 ; WX 600 ; N Tcaron ; B 38 0 563 802 ; +C -1 ; WX 600 ; N partialdiff ; B 17 -38 459 710 ; +C -1 ; WX 600 ; N ydieresis ; B 7 -157 592 620 ; +C -1 ; WX 600 ; N Nacute ; B 7 -13 593 805 ; +C -1 ; WX 600 ; N icircumflex ; B 94 0 505 654 ; +C -1 ; WX 600 ; N Ecircumflex ; B 53 0 550 787 ; +C -1 ; WX 600 ; N adieresis ; B 53 -15 559 620 ; +C -1 ; WX 600 ; N edieresis ; B 66 -15 548 620 ; +C -1 ; WX 600 ; N cacute ; B 66 -15 529 672 ; +C -1 ; WX 600 ; N nacute ; B 26 0 575 672 ; +C -1 ; WX 600 ; N umacron ; B 21 -15 562 565 ; +C -1 ; WX 600 ; N Ncaron ; B 7 -13 593 802 ; +C -1 ; WX 600 ; N Iacute ; B 96 0 504 805 ; +C -1 ; WX 600 ; N plusminus ; B 87 44 513 558 ; +C -1 ; WX 600 ; N brokenbar ; B 275 -175 326 675 ; +C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N Gbreve ; B 31 -18 575 732 ; +C -1 ; WX 600 ; N Idotaccent ; B 96 0 504 753 ; +C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ; +C -1 ; WX 600 ; N Egrave ; B 53 0 550 805 ; +C -1 ; WX 600 ; N racute ; B 60 0 559 672 ; +C -1 ; WX 600 ; N omacron ; B 62 -15 538 565 ; +C -1 ; WX 600 ; N Zacute ; B 86 0 514 805 ; +C -1 ; WX 600 ; N Zcaron ; B 86 0 514 802 ; +C -1 ; WX 600 ; N greaterequal ; B 98 0 502 710 ; +C -1 ; WX 600 ; N Eth ; B 30 0 574 562 ; +C -1 ; WX 600 ; N Ccedilla ; B 41 -151 540 580 ; +C -1 ; WX 600 ; N lcommaaccent ; B 95 -250 505 629 ; +C -1 ; WX 600 ; N tcaron ; B 87 -15 530 717 ; +C -1 ; WX 600 ; N eogonek ; B 66 -172 548 441 ; +C -1 ; WX 600 ; N Uogonek ; B 17 -172 583 562 ; +C -1 ; WX 600 ; N Aacute ; B 3 0 597 805 ; +C -1 ; WX 600 ; N Adieresis ; B 3 0 597 753 ; +C -1 ; WX 600 ; N egrave ; B 66 -15 548 672 ; +C -1 ; WX 600 ; N zacute ; B 99 0 502 672 ; +C -1 ; WX 600 ; N iogonek ; B 95 -172 505 657 ; +C -1 ; WX 600 ; N Oacute ; B 43 -18 557 805 ; +C -1 ; WX 600 ; N oacute ; B 62 -15 538 672 ; +C -1 ; WX 600 ; N amacron ; B 53 -15 559 565 ; +C -1 ; WX 600 ; N sacute ; B 80 -15 513 672 ; +C -1 ; WX 600 ; N idieresis ; B 95 0 505 620 ; +C -1 ; WX 600 ; N Ocircumflex ; B 43 -18 557 787 ; +C -1 ; WX 600 ; N Ugrave ; B 17 -18 583 805 ; +C -1 ; WX 600 ; N Delta ; B 6 0 598 688 ; +C -1 ; WX 600 ; N thorn ; B -6 -157 555 629 ; +C -1 ; WX 600 ; N twosuperior ; B 177 249 424 622 ; +C -1 ; WX 600 ; N Odieresis ; B 43 -18 557 753 ; +C -1 ; WX 600 ; N mu ; B 21 -157 562 426 ; +C -1 ; WX 600 ; N igrave ; B 95 0 505 672 ; +C -1 ; WX 600 ; N ohungarumlaut ; B 62 -15 580 672 ; +C -1 ; WX 600 ; N Eogonek ; B 53 -172 561 562 ; +C -1 ; WX 600 ; N dcroat ; B 45 -15 591 629 ; +C -1 ; WX 600 ; N threequarters ; B 8 -56 593 666 ; +C -1 ; WX 600 ; N Scedilla ; B 72 -151 529 580 ; +C -1 ; WX 600 ; N lcaron ; B 95 0 533 629 ; +C -1 ; WX 600 ; N Kcommaaccent ; B 38 -250 582 562 ; +C -1 ; WX 600 ; N Lacute ; B 47 0 554 805 ; +C -1 ; WX 600 ; N trademark ; B -23 263 623 562 ; +C -1 ; WX 600 ; N edotaccent ; B 66 -15 548 620 ; +C -1 ; WX 600 ; N Igrave ; B 96 0 504 805 ; +C -1 ; WX 600 ; N Imacron ; B 96 0 504 698 ; +C -1 ; WX 600 ; N Lcaron ; B 47 0 554 562 ; +C -1 ; WX 600 ; N onehalf ; B 0 -57 611 665 ; +C -1 ; WX 600 ; N lessequal ; B 98 0 502 710 ; +C -1 ; WX 600 ; N ocircumflex ; B 62 -15 538 654 ; +C -1 ; WX 600 ; N ntilde ; B 26 0 575 606 ; +C -1 ; WX 600 ; N Uhungarumlaut ; B 17 -18 590 805 ; +C -1 ; WX 600 ; N Eacute ; B 53 0 550 805 ; +C -1 ; WX 600 ; N emacron ; B 66 -15 548 565 ; +C -1 ; WX 600 ; N gbreve ; B 45 -157 566 609 ; +C -1 ; WX 600 ; N onequarter ; B 0 -57 600 665 ; +C -1 ; WX 600 ; N Scaron ; B 72 -20 529 802 ; +C -1 ; WX 600 ; N Scommaaccent ; B 72 -250 529 580 ; +C -1 ; WX 600 ; N Ohungarumlaut ; B 43 -18 580 805 ; +C -1 ; WX 600 ; N degree ; B 123 269 477 622 ; +C -1 ; WX 600 ; N ograve ; B 62 -15 538 672 ; +C -1 ; WX 600 ; N Ccaron ; B 41 -18 540 802 ; +C -1 ; WX 600 ; N ugrave ; B 21 -15 562 672 ; +C -1 ; WX 600 ; N radical ; B 3 -15 597 792 ; +C -1 ; WX 600 ; N Dcaron ; B 43 0 574 802 ; +C -1 ; WX 600 ; N rcommaaccent ; B 60 -250 559 441 ; +C -1 ; WX 600 ; N Ntilde ; B 7 -13 593 729 ; +C -1 ; WX 600 ; N otilde ; B 62 -15 538 606 ; +C -1 ; WX 600 ; N Rcommaaccent ; B 38 -250 588 562 ; +C -1 ; WX 600 ; N Lcommaaccent ; B 47 -250 554 562 ; +C -1 ; WX 600 ; N Atilde ; B 3 0 597 729 ; +C -1 ; WX 600 ; N Aogonek ; B 3 -172 608 562 ; +C -1 ; WX 600 ; N Aring ; B 3 0 597 750 ; +C -1 ; WX 600 ; N Otilde ; B 43 -18 557 729 ; +C -1 ; WX 600 ; N zdotaccent ; B 99 0 502 620 ; +C -1 ; WX 600 ; N Ecaron ; B 53 0 550 802 ; +C -1 ; WX 600 ; N Iogonek ; B 96 -172 504 562 ; +C -1 ; WX 600 ; N kcommaaccent ; B 43 -250 580 629 ; +C -1 ; WX 600 ; N minus ; B 80 232 520 283 ; +C -1 ; WX 600 ; N Icircumflex ; B 96 0 504 787 ; +C -1 ; WX 600 ; N ncaron ; B 26 0 575 669 ; +C -1 ; WX 600 ; N tcommaaccent ; B 87 -250 530 561 ; +C -1 ; WX 600 ; N logicalnot ; B 87 108 513 369 ; +C -1 ; WX 600 ; N odieresis ; B 62 -15 538 620 ; +C -1 ; WX 600 ; N udieresis ; B 21 -15 562 620 ; +C -1 ; WX 600 ; N notequal ; B 15 -16 540 529 ; +C -1 ; WX 600 ; N gcommaaccent ; B 45 -157 566 708 ; +C -1 ; WX 600 ; N eth ; B 62 -15 538 629 ; +C -1 ; WX 600 ; N zcaron ; B 99 0 502 669 ; +C -1 ; WX 600 ; N ncommaaccent ; B 26 -250 575 441 ; +C -1 ; WX 600 ; N onesuperior ; B 172 249 428 622 ; +C -1 ; WX 600 ; N imacron ; B 95 0 505 565 ; +C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics addfile ./Core14_AFMs/Helvetica-Bold.afm hunk ./Core14_AFMs/Helvetica-Bold.afm 1 +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 12:43:52 1997 +Comment UniqueID 43052 +Comment VMusage 37169 48194 +FontName Helvetica-Bold +FullName Helvetica Bold +FamilyName Helvetica +Weight Bold +ItalicAngle 0 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -170 -228 1003 962 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 532 +Ascender 718 +Descender -207 +StdHW 118 +StdVW 140 +StartCharMetrics 315 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 90 0 244 718 ; +C 34 ; WX 474 ; N quotedbl ; B 98 447 376 718 ; +C 35 ; WX 556 ; N numbersign ; B 18 0 538 698 ; +C 36 ; WX 556 ; N dollar ; B 30 -115 523 775 ; +C 37 ; WX 889 ; N percent ; B 28 -19 861 710 ; +C 38 ; WX 722 ; N ampersand ; B 54 -19 701 718 ; +C 39 ; WX 278 ; N quoteright ; B 69 445 209 718 ; +C 40 ; WX 333 ; N parenleft ; B 35 -208 314 734 ; +C 41 ; WX 333 ; N parenright ; B 19 -208 298 734 ; +C 42 ; WX 389 ; N asterisk ; B 27 387 362 718 ; +C 43 ; WX 584 ; N plus ; B 40 0 544 506 ; +C 44 ; WX 278 ; N comma ; B 64 -168 214 146 ; +C 45 ; WX 333 ; N hyphen ; B 27 215 306 345 ; +C 46 ; WX 278 ; N period ; B 64 0 214 146 ; +C 47 ; WX 278 ; N slash ; B -33 -19 311 737 ; +C 48 ; WX 556 ; N zero ; B 32 -19 524 710 ; +C 49 ; WX 556 ; N one ; B 69 0 378 710 ; +C 50 ; WX 556 ; N two ; B 26 0 511 710 ; +C 51 ; WX 556 ; N three ; B 27 -19 516 710 ; +C 52 ; WX 556 ; N four ; B 27 0 526 710 ; +C 53 ; WX 556 ; N five ; B 27 -19 516 698 ; +C 54 ; WX 556 ; N six ; B 31 -19 520 710 ; +C 55 ; WX 556 ; N seven ; B 25 0 528 698 ; +C 56 ; WX 556 ; N eight ; B 32 -19 524 710 ; +C 57 ; WX 556 ; N nine ; B 30 -19 522 710 ; +C 58 ; WX 333 ; N colon ; B 92 0 242 512 ; +C 59 ; WX 333 ; N semicolon ; B 92 -168 242 512 ; +C 60 ; WX 584 ; N less ; B 38 -8 546 514 ; +C 61 ; WX 584 ; N equal ; B 40 87 544 419 ; +C 62 ; WX 584 ; N greater ; B 38 -8 546 514 ; +C 63 ; WX 611 ; N question ; B 60 0 556 727 ; +C 64 ; WX 975 ; N at ; B 118 -19 856 737 ; +C 65 ; WX 722 ; N A ; B 20 0 702 718 ; +C 66 ; WX 722 ; N B ; B 76 0 669 718 ; +C 67 ; WX 722 ; N C ; B 44 -19 684 737 ; +C 68 ; WX 722 ; N D ; B 76 0 685 718 ; +C 69 ; WX 667 ; N E ; B 76 0 621 718 ; +C 70 ; WX 611 ; N F ; B 76 0 587 718 ; +C 71 ; WX 778 ; N G ; B 44 -19 713 737 ; +C 72 ; WX 722 ; N H ; B 71 0 651 718 ; +C 73 ; WX 278 ; N I ; B 64 0 214 718 ; +C 74 ; WX 556 ; N J ; B 22 -18 484 718 ; +C 75 ; WX 722 ; N K ; B 87 0 722 718 ; +C 76 ; WX 611 ; N L ; B 76 0 583 718 ; +C 77 ; WX 833 ; N M ; B 69 0 765 718 ; +C 78 ; WX 722 ; N N ; B 69 0 654 718 ; +C 79 ; WX 778 ; N O ; B 44 -19 734 737 ; +C 80 ; WX 667 ; N P ; B 76 0 627 718 ; +C 81 ; WX 778 ; N Q ; B 44 -52 737 737 ; +C 82 ; WX 722 ; N R ; B 76 0 677 718 ; +C 83 ; WX 667 ; N S ; B 39 -19 629 737 ; +C 84 ; WX 611 ; N T ; B 14 0 598 718 ; +C 85 ; WX 722 ; N U ; B 72 -19 651 718 ; +C 86 ; WX 667 ; N V ; B 19 0 648 718 ; +C 87 ; WX 944 ; N W ; B 16 0 929 718 ; +C 88 ; WX 667 ; N X ; B 14 0 653 718 ; +C 89 ; WX 667 ; N Y ; B 15 0 653 718 ; +C 90 ; WX 611 ; N Z ; B 25 0 586 718 ; +C 91 ; WX 333 ; N bracketleft ; B 63 -196 309 722 ; +C 92 ; WX 278 ; N backslash ; B -33 -19 311 737 ; +C 93 ; WX 333 ; N bracketright ; B 24 -196 270 722 ; +C 94 ; WX 584 ; N asciicircum ; B 62 323 522 698 ; +C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ; +C 96 ; WX 278 ; N quoteleft ; B 69 454 209 727 ; +C 97 ; WX 556 ; N a ; B 29 -14 527 546 ; +C 98 ; WX 611 ; N b ; B 61 -14 578 718 ; +C 99 ; WX 556 ; N c ; B 34 -14 524 546 ; +C 100 ; WX 611 ; N d ; B 34 -14 551 718 ; +C 101 ; WX 556 ; N e ; B 23 -14 528 546 ; +C 102 ; WX 333 ; N f ; B 10 0 318 727 ; L i fi ; L l fl ; +C 103 ; WX 611 ; N g ; B 40 -217 553 546 ; +C 104 ; WX 611 ; N h ; B 65 0 546 718 ; +C 105 ; WX 278 ; N i ; B 69 0 209 725 ; +C 106 ; WX 278 ; N j ; B 3 -214 209 725 ; +C 107 ; WX 556 ; N k ; B 69 0 562 718 ; +C 108 ; WX 278 ; N l ; B 69 0 209 718 ; +C 109 ; WX 889 ; N m ; B 64 0 826 546 ; +C 110 ; WX 611 ; N n ; B 65 0 546 546 ; +C 111 ; WX 611 ; N o ; B 34 -14 578 546 ; +C 112 ; WX 611 ; N p ; B 62 -207 578 546 ; +C 113 ; WX 611 ; N q ; B 34 -207 552 546 ; +C 114 ; WX 389 ; N r ; B 64 0 373 546 ; +C 115 ; WX 556 ; N s ; B 30 -14 519 546 ; +C 116 ; WX 333 ; N t ; B 10 -6 309 676 ; +C 117 ; WX 611 ; N u ; B 66 -14 545 532 ; +C 118 ; WX 556 ; N v ; B 13 0 543 532 ; +C 119 ; WX 778 ; N w ; B 10 0 769 532 ; +C 120 ; WX 556 ; N x ; B 15 0 541 532 ; +C 121 ; WX 556 ; N y ; B 10 -214 539 532 ; +C 122 ; WX 500 ; N z ; B 20 0 480 532 ; +C 123 ; WX 389 ; N braceleft ; B 48 -196 365 722 ; +C 124 ; WX 280 ; N bar ; B 84 -225 196 775 ; +C 125 ; WX 389 ; N braceright ; B 24 -196 341 722 ; +C 126 ; WX 584 ; N asciitilde ; B 61 163 523 343 ; +C 161 ; WX 333 ; N exclamdown ; B 90 -186 244 532 ; +C 162 ; WX 556 ; N cent ; B 34 -118 524 628 ; +C 163 ; WX 556 ; N sterling ; B 28 -16 541 718 ; +C 164 ; WX 167 ; N fraction ; B -170 -19 336 710 ; +C 165 ; WX 556 ; N yen ; B -9 0 565 698 ; +C 166 ; WX 556 ; N florin ; B -10 -210 516 737 ; +C 167 ; WX 556 ; N section ; B 34 -184 522 727 ; +C 168 ; WX 556 ; N currency ; B -3 76 559 636 ; +C 169 ; WX 238 ; N quotesingle ; B 70 447 168 718 ; +C 170 ; WX 500 ; N quotedblleft ; B 64 454 436 727 ; +C 171 ; WX 556 ; N guillemotleft ; B 88 76 468 484 ; +C 172 ; WX 333 ; N guilsinglleft ; B 83 76 250 484 ; +C 173 ; WX 333 ; N guilsinglright ; B 83 76 250 484 ; +C 174 ; WX 611 ; N fi ; B 10 0 542 727 ; +C 175 ; WX 611 ; N fl ; B 10 0 542 727 ; +C 177 ; WX 556 ; N endash ; B 0 227 556 333 ; +C 178 ; WX 556 ; N dagger ; B 36 -171 520 718 ; +C 179 ; WX 556 ; N daggerdbl ; B 36 -171 520 718 ; +C 180 ; WX 278 ; N periodcentered ; B 58 172 220 334 ; +C 182 ; WX 556 ; N paragraph ; B -8 -191 539 700 ; +C 183 ; WX 350 ; N bullet ; B 10 194 340 524 ; +C 184 ; WX 278 ; N quotesinglbase ; B 69 -146 209 127 ; +C 185 ; WX 500 ; N quotedblbase ; B 64 -146 436 127 ; +C 186 ; WX 500 ; N quotedblright ; B 64 445 436 718 ; +C 187 ; WX 556 ; N guillemotright ; B 88 76 468 484 ; +C 188 ; WX 1000 ; N ellipsis ; B 92 0 908 146 ; +C 189 ; WX 1000 ; N perthousand ; B -3 -19 1003 710 ; +C 191 ; WX 611 ; N questiondown ; B 55 -195 551 532 ; +C 193 ; WX 333 ; N grave ; B -23 604 225 750 ; +C 194 ; WX 333 ; N acute ; B 108 604 356 750 ; +C 195 ; WX 333 ; N circumflex ; B -10 604 343 750 ; +C 196 ; WX 333 ; N tilde ; B -17 610 350 737 ; +C 197 ; WX 333 ; N macron ; B -6 604 339 678 ; +C 198 ; WX 333 ; N breve ; B -2 604 335 750 ; +C 199 ; WX 333 ; N dotaccent ; B 104 614 230 729 ; +C 200 ; WX 333 ; N dieresis ; B 6 614 327 729 ; +C 202 ; WX 333 ; N ring ; B 59 568 275 776 ; +C 203 ; WX 333 ; N cedilla ; B 6 -228 245 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 9 604 486 750 ; +C 206 ; WX 333 ; N ogonek ; B 71 -228 304 0 ; +C 207 ; WX 333 ; N caron ; B -10 604 343 750 ; +C 208 ; WX 1000 ; N emdash ; B 0 227 1000 333 ; +C 225 ; WX 1000 ; N AE ; B 5 0 954 718 ; +C 227 ; WX 370 ; N ordfeminine ; B 22 401 347 737 ; +C 232 ; WX 611 ; N Lslash ; B -20 0 583 718 ; +C 233 ; WX 778 ; N Oslash ; B 33 -27 744 745 ; +C 234 ; WX 1000 ; N OE ; B 37 -19 961 737 ; +C 235 ; WX 365 ; N ordmasculine ; B 6 401 360 737 ; +C 241 ; WX 889 ; N ae ; B 29 -14 858 546 ; +C 245 ; WX 278 ; N dotlessi ; B 69 0 209 532 ; +C 248 ; WX 278 ; N lslash ; B -18 0 296 718 ; +C 249 ; WX 611 ; N oslash ; B 22 -29 589 560 ; +C 250 ; WX 944 ; N oe ; B 34 -14 912 546 ; +C 251 ; WX 611 ; N germandbls ; B 69 -14 579 731 ; +C -1 ; WX 278 ; N Idieresis ; B -21 0 300 915 ; +C -1 ; WX 556 ; N eacute ; B 23 -14 528 750 ; +C -1 ; WX 556 ; N abreve ; B 29 -14 527 750 ; +C -1 ; WX 611 ; N uhungarumlaut ; B 66 -14 625 750 ; +C -1 ; WX 556 ; N ecaron ; B 23 -14 528 750 ; +C -1 ; WX 667 ; N Ydieresis ; B 15 0 653 915 ; +C -1 ; WX 584 ; N divide ; B 40 -42 544 548 ; +C -1 ; WX 667 ; N Yacute ; B 15 0 653 936 ; +C -1 ; WX 722 ; N Acircumflex ; B 20 0 702 936 ; +C -1 ; WX 556 ; N aacute ; B 29 -14 527 750 ; +C -1 ; WX 722 ; N Ucircumflex ; B 72 -19 651 936 ; +C -1 ; WX 556 ; N yacute ; B 10 -214 539 750 ; +C -1 ; WX 556 ; N scommaaccent ; B 30 -228 519 546 ; +C -1 ; WX 556 ; N ecircumflex ; B 23 -14 528 750 ; +C -1 ; WX 722 ; N Uring ; B 72 -19 651 962 ; +C -1 ; WX 722 ; N Udieresis ; B 72 -19 651 915 ; +C -1 ; WX 556 ; N aogonek ; B 29 -224 545 546 ; +C -1 ; WX 722 ; N Uacute ; B 72 -19 651 936 ; +C -1 ; WX 611 ; N uogonek ; B 66 -228 545 532 ; +C -1 ; WX 667 ; N Edieresis ; B 76 0 621 915 ; +C -1 ; WX 722 ; N Dcroat ; B -5 0 685 718 ; +C -1 ; WX 250 ; N commaaccent ; B 64 -228 199 -50 ; +C -1 ; WX 737 ; N copyright ; B -11 -19 749 737 ; +C -1 ; WX 667 ; N Emacron ; B 76 0 621 864 ; +C -1 ; WX 556 ; N ccaron ; B 34 -14 524 750 ; +C -1 ; WX 556 ; N aring ; B 29 -14 527 776 ; +C -1 ; WX 722 ; N Ncommaaccent ; B 69 -228 654 718 ; +C -1 ; WX 278 ; N lacute ; B 69 0 329 936 ; +C -1 ; WX 556 ; N agrave ; B 29 -14 527 750 ; +C -1 ; WX 611 ; N Tcommaaccent ; B 14 -228 598 718 ; +C -1 ; WX 722 ; N Cacute ; B 44 -19 684 936 ; +C -1 ; WX 556 ; N atilde ; B 29 -14 527 737 ; +C -1 ; WX 667 ; N Edotaccent ; B 76 0 621 915 ; +C -1 ; WX 556 ; N scaron ; B 30 -14 519 750 ; +C -1 ; WX 556 ; N scedilla ; B 30 -228 519 546 ; +C -1 ; WX 278 ; N iacute ; B 69 0 329 750 ; +C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ; +C -1 ; WX 722 ; N Rcaron ; B 76 0 677 936 ; +C -1 ; WX 778 ; N Gcommaaccent ; B 44 -228 713 737 ; +C -1 ; WX 611 ; N ucircumflex ; B 66 -14 545 750 ; +C -1 ; WX 556 ; N acircumflex ; B 29 -14 527 750 ; +C -1 ; WX 722 ; N Amacron ; B 20 0 702 864 ; +C -1 ; WX 389 ; N rcaron ; B 18 0 373 750 ; +C -1 ; WX 556 ; N ccedilla ; B 34 -228 524 546 ; +C -1 ; WX 611 ; N Zdotaccent ; B 25 0 586 915 ; +C -1 ; WX 667 ; N Thorn ; B 76 0 627 718 ; +C -1 ; WX 778 ; N Omacron ; B 44 -19 734 864 ; +C -1 ; WX 722 ; N Racute ; B 76 0 677 936 ; +C -1 ; WX 667 ; N Sacute ; B 39 -19 629 936 ; +C -1 ; WX 743 ; N dcaron ; B 34 -14 750 718 ; +C -1 ; WX 722 ; N Umacron ; B 72 -19 651 864 ; +C -1 ; WX 611 ; N uring ; B 66 -14 545 776 ; +C -1 ; WX 333 ; N threesuperior ; B 8 271 326 710 ; +C -1 ; WX 778 ; N Ograve ; B 44 -19 734 936 ; +C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ; +C -1 ; WX 722 ; N Abreve ; B 20 0 702 936 ; +C -1 ; WX 584 ; N multiply ; B 40 1 545 505 ; +C -1 ; WX 611 ; N uacute ; B 66 -14 545 750 ; +C -1 ; WX 611 ; N Tcaron ; B 14 0 598 936 ; +C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ; +C -1 ; WX 556 ; N ydieresis ; B 10 -214 539 729 ; +C -1 ; WX 722 ; N Nacute ; B 69 0 654 936 ; +C -1 ; WX 278 ; N icircumflex ; B -37 0 316 750 ; +C -1 ; WX 667 ; N Ecircumflex ; B 76 0 621 936 ; +C -1 ; WX 556 ; N adieresis ; B 29 -14 527 729 ; +C -1 ; WX 556 ; N edieresis ; B 23 -14 528 729 ; +C -1 ; WX 556 ; N cacute ; B 34 -14 524 750 ; +C -1 ; WX 611 ; N nacute ; B 65 0 546 750 ; +C -1 ; WX 611 ; N umacron ; B 66 -14 545 678 ; +C -1 ; WX 722 ; N Ncaron ; B 69 0 654 936 ; +C -1 ; WX 278 ; N Iacute ; B 64 0 329 936 ; +C -1 ; WX 584 ; N plusminus ; B 40 0 544 506 ; +C -1 ; WX 280 ; N brokenbar ; B 84 -150 196 700 ; +C -1 ; WX 737 ; N registered ; B -11 -19 748 737 ; +C -1 ; WX 778 ; N Gbreve ; B 44 -19 713 936 ; +C -1 ; WX 278 ; N Idotaccent ; B 64 0 214 915 ; +C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ; +C -1 ; WX 667 ; N Egrave ; B 76 0 621 936 ; +C -1 ; WX 389 ; N racute ; B 64 0 384 750 ; +C -1 ; WX 611 ; N omacron ; B 34 -14 578 678 ; +C -1 ; WX 611 ; N Zacute ; B 25 0 586 936 ; +C -1 ; WX 611 ; N Zcaron ; B 25 0 586 936 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ; +C -1 ; WX 722 ; N Eth ; B -5 0 685 718 ; +C -1 ; WX 722 ; N Ccedilla ; B 44 -228 684 737 ; +C -1 ; WX 278 ; N lcommaaccent ; B 69 -228 213 718 ; +C -1 ; WX 389 ; N tcaron ; B 10 -6 421 878 ; +C -1 ; WX 556 ; N eogonek ; B 23 -228 528 546 ; +C -1 ; WX 722 ; N Uogonek ; B 72 -228 651 718 ; +C -1 ; WX 722 ; N Aacute ; B 20 0 702 936 ; +C -1 ; WX 722 ; N Adieresis ; B 20 0 702 915 ; +C -1 ; WX 556 ; N egrave ; B 23 -14 528 750 ; +C -1 ; WX 500 ; N zacute ; B 20 0 480 750 ; +C -1 ; WX 278 ; N iogonek ; B 16 -224 249 725 ; +C -1 ; WX 778 ; N Oacute ; B 44 -19 734 936 ; +C -1 ; WX 611 ; N oacute ; B 34 -14 578 750 ; +C -1 ; WX 556 ; N amacron ; B 29 -14 527 678 ; +C -1 ; WX 556 ; N sacute ; B 30 -14 519 750 ; +C -1 ; WX 278 ; N idieresis ; B -21 0 300 729 ; +C -1 ; WX 778 ; N Ocircumflex ; B 44 -19 734 936 ; +C -1 ; WX 722 ; N Ugrave ; B 72 -19 651 936 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 611 ; N thorn ; B 62 -208 578 718 ; +C -1 ; WX 333 ; N twosuperior ; B 9 283 324 710 ; +C -1 ; WX 778 ; N Odieresis ; B 44 -19 734 915 ; +C -1 ; WX 611 ; N mu ; B 66 -207 545 532 ; +C -1 ; WX 278 ; N igrave ; B -50 0 209 750 ; +C -1 ; WX 611 ; N ohungarumlaut ; B 34 -14 625 750 ; +C -1 ; WX 667 ; N Eogonek ; B 76 -224 639 718 ; +C -1 ; WX 611 ; N dcroat ; B 34 -14 650 718 ; +C -1 ; WX 834 ; N threequarters ; B 16 -19 799 710 ; +C -1 ; WX 667 ; N Scedilla ; B 39 -228 629 737 ; +C -1 ; WX 400 ; N lcaron ; B 69 0 408 718 ; +C -1 ; WX 722 ; N Kcommaaccent ; B 87 -228 722 718 ; +C -1 ; WX 611 ; N Lacute ; B 76 0 583 936 ; +C -1 ; WX 1000 ; N trademark ; B 44 306 956 718 ; +C -1 ; WX 556 ; N edotaccent ; B 23 -14 528 729 ; +C -1 ; WX 278 ; N Igrave ; B -50 0 214 936 ; +C -1 ; WX 278 ; N Imacron ; B -33 0 312 864 ; +C -1 ; WX 611 ; N Lcaron ; B 76 0 583 718 ; +C -1 ; WX 834 ; N onehalf ; B 26 -19 794 710 ; +C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ; +C -1 ; WX 611 ; N ocircumflex ; B 34 -14 578 750 ; +C -1 ; WX 611 ; N ntilde ; B 65 0 546 737 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 72 -19 681 936 ; +C -1 ; WX 667 ; N Eacute ; B 76 0 621 936 ; +C -1 ; WX 556 ; N emacron ; B 23 -14 528 678 ; +C -1 ; WX 611 ; N gbreve ; B 40 -217 553 750 ; +C -1 ; WX 834 ; N onequarter ; B 26 -19 766 710 ; +C -1 ; WX 667 ; N Scaron ; B 39 -19 629 936 ; +C -1 ; WX 667 ; N Scommaaccent ; B 39 -228 629 737 ; +C -1 ; WX 778 ; N Ohungarumlaut ; B 44 -19 734 936 ; +C -1 ; WX 400 ; N degree ; B 57 426 343 712 ; +C -1 ; WX 611 ; N ograve ; B 34 -14 578 750 ; +C -1 ; WX 722 ; N Ccaron ; B 44 -19 684 936 ; +C -1 ; WX 611 ; N ugrave ; B 66 -14 545 750 ; +C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ; +C -1 ; WX 722 ; N Dcaron ; B 76 0 685 936 ; +C -1 ; WX 389 ; N rcommaaccent ; B 64 -228 373 546 ; +C -1 ; WX 722 ; N Ntilde ; B 69 0 654 923 ; +C -1 ; WX 611 ; N otilde ; B 34 -14 578 737 ; +C -1 ; WX 722 ; N Rcommaaccent ; B 76 -228 677 718 ; +C -1 ; WX 611 ; N Lcommaaccent ; B 76 -228 583 718 ; +C -1 ; WX 722 ; N Atilde ; B 20 0 702 923 ; +C -1 ; WX 722 ; N Aogonek ; B 20 -224 742 718 ; +C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ; +C -1 ; WX 778 ; N Otilde ; B 44 -19 734 923 ; +C -1 ; WX 500 ; N zdotaccent ; B 20 0 480 729 ; +C -1 ; WX 667 ; N Ecaron ; B 76 0 621 936 ; +C -1 ; WX 278 ; N Iogonek ; B -11 -228 222 718 ; +C -1 ; WX 556 ; N kcommaaccent ; B 69 -228 562 718 ; +C -1 ; WX 584 ; N minus ; B 40 197 544 309 ; +C -1 ; WX 278 ; N Icircumflex ; B -37 0 316 936 ; +C -1 ; WX 611 ; N ncaron ; B 65 0 546 750 ; +C -1 ; WX 333 ; N tcommaaccent ; B 10 -228 309 676 ; +C -1 ; WX 584 ; N logicalnot ; B 40 108 544 419 ; +C -1 ; WX 611 ; N odieresis ; B 34 -14 578 729 ; +C -1 ; WX 611 ; N udieresis ; B 66 -14 545 729 ; +C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ; +C -1 ; WX 611 ; N gcommaaccent ; B 40 -217 553 850 ; +C -1 ; WX 611 ; N eth ; B 34 -14 578 737 ; +C -1 ; WX 500 ; N zcaron ; B 20 0 480 750 ; +C -1 ; WX 611 ; N ncommaaccent ; B 65 -228 546 546 ; +C -1 ; WX 333 ; N onesuperior ; B 26 283 237 710 ; +C -1 ; WX 278 ; N imacron ; B -8 0 285 678 ; +C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2481 +KPX A C -40 +KPX A Cacute -40 +KPX A Ccaron -40 +KPX A Ccedilla -40 +KPX A G -50 +KPX A Gbreve -50 +KPX A Gcommaaccent -50 +KPX A O -40 +KPX A Oacute -40 +KPX A Ocircumflex -40 +KPX A Odieresis -40 +KPX A Ograve -40 +KPX A Ohungarumlaut -40 +KPX A Omacron -40 +KPX A Oslash -40 +KPX A Otilde -40 +KPX A Q -40 +KPX A T -90 +KPX A Tcaron -90 +KPX A Tcommaaccent -90 +KPX A U -50 +KPX A Uacute -50 +KPX A Ucircumflex -50 +KPX A Udieresis -50 +KPX A Ugrave -50 +KPX A Uhungarumlaut -50 +KPX A Umacron -50 +KPX A Uogonek -50 +KPX A Uring -50 +KPX A V -80 +KPX A W -60 +KPX A Y -110 +KPX A Yacute -110 +KPX A Ydieresis -110 +KPX A u -30 +KPX A uacute -30 +KPX A ucircumflex -30 +KPX A udieresis -30 +KPX A ugrave -30 +KPX A uhungarumlaut -30 +KPX A umacron -30 +KPX A uogonek -30 +KPX A uring -30 +KPX A v -40 +KPX A w -30 +KPX A y -30 +KPX A yacute -30 +KPX A ydieresis -30 +KPX Aacute C -40 +KPX Aacute Cacute -40 +KPX Aacute Ccaron -40 +KPX Aacute Ccedilla -40 +KPX Aacute G -50 +KPX Aacute Gbreve -50 +KPX Aacute Gcommaaccent -50 +KPX Aacute O -40 +KPX Aacute Oacute -40 +KPX Aacute Ocircumflex -40 +KPX Aacute Odieresis -40 +KPX Aacute Ograve -40 +KPX Aacute Ohungarumlaut -40 +KPX Aacute Omacron -40 +KPX Aacute Oslash -40 +KPX Aacute Otilde -40 +KPX Aacute Q -40 +KPX Aacute T -90 +KPX Aacute Tcaron -90 +KPX Aacute Tcommaaccent -90 +KPX Aacute U -50 +KPX Aacute Uacute -50 +KPX Aacute Ucircumflex -50 +KPX Aacute Udieresis -50 +KPX Aacute Ugrave -50 +KPX Aacute Uhungarumlaut -50 +KPX Aacute Umacron -50 +KPX Aacute Uogonek -50 +KPX Aacute Uring -50 +KPX Aacute V -80 +KPX Aacute W -60 +KPX Aacute Y -110 +KPX Aacute Yacute -110 +KPX Aacute Ydieresis -110 +KPX Aacute u -30 +KPX Aacute uacute -30 +KPX Aacute ucircumflex -30 +KPX Aacute udieresis -30 +KPX Aacute ugrave -30 +KPX Aacute uhungarumlaut -30 +KPX Aacute umacron -30 +KPX Aacute uogonek -30 +KPX Aacute uring -30 +KPX Aacute v -40 +KPX Aacute w -30 +KPX Aacute y -30 +KPX Aacute yacute -30 +KPX Aacute ydieresis -30 +KPX Abreve C -40 +KPX Abreve Cacute -40 +KPX Abreve Ccaron -40 +KPX Abreve Ccedilla -40 +KPX Abreve G -50 +KPX Abreve Gbreve -50 +KPX Abreve Gcommaaccent -50 +KPX Abreve O -40 +KPX Abreve Oacute -40 +KPX Abreve Ocircumflex -40 +KPX Abreve Odieresis -40 +KPX Abreve Ograve -40 +KPX Abreve Ohungarumlaut -40 +KPX Abreve Omacron -40 +KPX Abreve Oslash -40 +KPX Abreve Otilde -40 +KPX Abreve Q -40 +KPX Abreve T -90 +KPX Abreve Tcaron -90 +KPX Abreve Tcommaaccent -90 +KPX Abreve U -50 +KPX Abreve Uacute -50 +KPX Abreve Ucircumflex -50 +KPX Abreve Udieresis -50 +KPX Abreve Ugrave -50 +KPX Abreve Uhungarumlaut -50 +KPX Abreve Umacron -50 +KPX Abreve Uogonek -50 +KPX Abreve Uring -50 +KPX Abreve V -80 +KPX Abreve W -60 +KPX Abreve Y -110 +KPX Abreve Yacute -110 +KPX Abreve Ydieresis -110 +KPX Abreve u -30 +KPX Abreve uacute -30 +KPX Abreve ucircumflex -30 +KPX Abreve udieresis -30 +KPX Abreve ugrave -30 +KPX Abreve uhungarumlaut -30 +KPX Abreve umacron -30 +KPX Abreve uogonek -30 +KPX Abreve uring -30 +KPX Abreve v -40 +KPX Abreve w -30 +KPX Abreve y -30 +KPX Abreve yacute -30 +KPX Abreve ydieresis -30 +KPX Acircumflex C -40 +KPX Acircumflex Cacute -40 +KPX Acircumflex Ccaron -40 +KPX Acircumflex Ccedilla -40 +KPX Acircumflex G -50 +KPX Acircumflex Gbreve -50 +KPX Acircumflex Gcommaaccent -50 +KPX Acircumflex O -40 +KPX Acircumflex Oacute -40 +KPX Acircumflex Ocircumflex -40 +KPX Acircumflex Odieresis -40 +KPX Acircumflex Ograve -40 +KPX Acircumflex Ohungarumlaut -40 +KPX Acircumflex Omacron -40 +KPX Acircumflex Oslash -40 +KPX Acircumflex Otilde -40 +KPX Acircumflex Q -40 +KPX Acircumflex T -90 +KPX Acircumflex Tcaron -90 +KPX Acircumflex Tcommaaccent -90 +KPX Acircumflex U -50 +KPX Acircumflex Uacute -50 +KPX Acircumflex Ucircumflex -50 +KPX Acircumflex Udieresis -50 +KPX Acircumflex Ugrave -50 +KPX Acircumflex Uhungarumlaut -50 +KPX Acircumflex Umacron -50 +KPX Acircumflex Uogonek -50 +KPX Acircumflex Uring -50 +KPX Acircumflex V -80 +KPX Acircumflex W -60 +KPX Acircumflex Y -110 +KPX Acircumflex Yacute -110 +KPX Acircumflex Ydieresis -110 +KPX Acircumflex u -30 +KPX Acircumflex uacute -30 +KPX Acircumflex ucircumflex -30 +KPX Acircumflex udieresis -30 +KPX Acircumflex ugrave -30 +KPX Acircumflex uhungarumlaut -30 +KPX Acircumflex umacron -30 +KPX Acircumflex uogonek -30 +KPX Acircumflex uring -30 +KPX Acircumflex v -40 +KPX Acircumflex w -30 +KPX Acircumflex y -30 +KPX Acircumflex yacute -30 +KPX Acircumflex ydieresis -30 +KPX Adieresis C -40 +KPX Adieresis Cacute -40 +KPX Adieresis Ccaron -40 +KPX Adieresis Ccedilla -40 +KPX Adieresis G -50 +KPX Adieresis Gbreve -50 +KPX Adieresis Gcommaaccent -50 +KPX Adieresis O -40 +KPX Adieresis Oacute -40 +KPX Adieresis Ocircumflex -40 +KPX Adieresis Odieresis -40 +KPX Adieresis Ograve -40 +KPX Adieresis Ohungarumlaut -40 +KPX Adieresis Omacron -40 +KPX Adieresis Oslash -40 +KPX Adieresis Otilde -40 +KPX Adieresis Q -40 +KPX Adieresis T -90 +KPX Adieresis Tcaron -90 +KPX Adieresis Tcommaaccent -90 +KPX Adieresis U -50 +KPX Adieresis Uacute -50 +KPX Adieresis Ucircumflex -50 +KPX Adieresis Udieresis -50 +KPX Adieresis Ugrave -50 +KPX Adieresis Uhungarumlaut -50 +KPX Adieresis Umacron -50 +KPX Adieresis Uogonek -50 +KPX Adieresis Uring -50 +KPX Adieresis V -80 +KPX Adieresis W -60 +KPX Adieresis Y -110 +KPX Adieresis Yacute -110 +KPX Adieresis Ydieresis -110 +KPX Adieresis u -30 +KPX Adieresis uacute -30 +KPX Adieresis ucircumflex -30 +KPX Adieresis udieresis -30 +KPX Adieresis ugrave -30 +KPX Adieresis uhungarumlaut -30 +KPX Adieresis umacron -30 +KPX Adieresis uogonek -30 +KPX Adieresis uring -30 +KPX Adieresis v -40 +KPX Adieresis w -30 +KPX Adieresis y -30 +KPX Adieresis yacute -30 +KPX Adieresis ydieresis -30 +KPX Agrave C -40 +KPX Agrave Cacute -40 +KPX Agrave Ccaron -40 +KPX Agrave Ccedilla -40 +KPX Agrave G -50 +KPX Agrave Gbreve -50 +KPX Agrave Gcommaaccent -50 +KPX Agrave O -40 +KPX Agrave Oacute -40 +KPX Agrave Ocircumflex -40 +KPX Agrave Odieresis -40 +KPX Agrave Ograve -40 +KPX Agrave Ohungarumlaut -40 +KPX Agrave Omacron -40 +KPX Agrave Oslash -40 +KPX Agrave Otilde -40 +KPX Agrave Q -40 +KPX Agrave T -90 +KPX Agrave Tcaron -90 +KPX Agrave Tcommaaccent -90 +KPX Agrave U -50 +KPX Agrave Uacute -50 +KPX Agrave Ucircumflex -50 +KPX Agrave Udieresis -50 +KPX Agrave Ugrave -50 +KPX Agrave Uhungarumlaut -50 +KPX Agrave Umacron -50 +KPX Agrave Uogonek -50 +KPX Agrave Uring -50 +KPX Agrave V -80 +KPX Agrave W -60 +KPX Agrave Y -110 +KPX Agrave Yacute -110 +KPX Agrave Ydieresis -110 +KPX Agrave u -30 +KPX Agrave uacute -30 +KPX Agrave ucircumflex -30 +KPX Agrave udieresis -30 +KPX Agrave ugrave -30 +KPX Agrave uhungarumlaut -30 +KPX Agrave umacron -30 +KPX Agrave uogonek -30 +KPX Agrave uring -30 +KPX Agrave v -40 +KPX Agrave w -30 +KPX Agrave y -30 +KPX Agrave yacute -30 +KPX Agrave ydieresis -30 +KPX Amacron C -40 +KPX Amacron Cacute -40 +KPX Amacron Ccaron -40 +KPX Amacron Ccedilla -40 +KPX Amacron G -50 +KPX Amacron Gbreve -50 +KPX Amacron Gcommaaccent -50 +KPX Amacron O -40 +KPX Amacron Oacute -40 +KPX Amacron Ocircumflex -40 +KPX Amacron Odieresis -40 +KPX Amacron Ograve -40 +KPX Amacron Ohungarumlaut -40 +KPX Amacron Omacron -40 +KPX Amacron Oslash -40 +KPX Amacron Otilde -40 +KPX Amacron Q -40 +KPX Amacron T -90 +KPX Amacron Tcaron -90 +KPX Amacron Tcommaaccent -90 +KPX Amacron U -50 +KPX Amacron Uacute -50 +KPX Amacron Ucircumflex -50 +KPX Amacron Udieresis -50 +KPX Amacron Ugrave -50 +KPX Amacron Uhungarumlaut -50 +KPX Amacron Umacron -50 +KPX Amacron Uogonek -50 +KPX Amacron Uring -50 +KPX Amacron V -80 +KPX Amacron W -60 +KPX Amacron Y -110 +KPX Amacron Yacute -110 +KPX Amacron Ydieresis -110 +KPX Amacron u -30 +KPX Amacron uacute -30 +KPX Amacron ucircumflex -30 +KPX Amacron udieresis -30 +KPX Amacron ugrave -30 +KPX Amacron uhungarumlaut -30 +KPX Amacron umacron -30 +KPX Amacron uogonek -30 +KPX Amacron uring -30 +KPX Amacron v -40 +KPX Amacron w -30 +KPX Amacron y -30 +KPX Amacron yacute -30 +KPX Amacron ydieresis -30 +KPX Aogonek C -40 +KPX Aogonek Cacute -40 +KPX Aogonek Ccaron -40 +KPX Aogonek Ccedilla -40 +KPX Aogonek G -50 +KPX Aogonek Gbreve -50 +KPX Aogonek Gcommaaccent -50 +KPX Aogonek O -40 +KPX Aogonek Oacute -40 +KPX Aogonek Ocircumflex -40 +KPX Aogonek Odieresis -40 +KPX Aogonek Ograve -40 +KPX Aogonek Ohungarumlaut -40 +KPX Aogonek Omacron -40 +KPX Aogonek Oslash -40 +KPX Aogonek Otilde -40 +KPX Aogonek Q -40 +KPX Aogonek T -90 +KPX Aogonek Tcaron -90 +KPX Aogonek Tcommaaccent -90 +KPX Aogonek U -50 +KPX Aogonek Uacute -50 +KPX Aogonek Ucircumflex -50 +KPX Aogonek Udieresis -50 +KPX Aogonek Ugrave -50 +KPX Aogonek Uhungarumlaut -50 +KPX Aogonek Umacron -50 +KPX Aogonek Uogonek -50 +KPX Aogonek Uring -50 +KPX Aogonek V -80 +KPX Aogonek W -60 +KPX Aogonek Y -110 +KPX Aogonek Yacute -110 +KPX Aogonek Ydieresis -110 +KPX Aogonek u -30 +KPX Aogonek uacute -30 +KPX Aogonek ucircumflex -30 +KPX Aogonek udieresis -30 +KPX Aogonek ugrave -30 +KPX Aogonek uhungarumlaut -30 +KPX Aogonek umacron -30 +KPX Aogonek uogonek -30 +KPX Aogonek uring -30 +KPX Aogonek v -40 +KPX Aogonek w -30 +KPX Aogonek y -30 +KPX Aogonek yacute -30 +KPX Aogonek ydieresis -30 +KPX Aring C -40 +KPX Aring Cacute -40 +KPX Aring Ccaron -40 +KPX Aring Ccedilla -40 +KPX Aring G -50 +KPX Aring Gbreve -50 +KPX Aring Gcommaaccent -50 +KPX Aring O -40 +KPX Aring Oacute -40 +KPX Aring Ocircumflex -40 +KPX Aring Odieresis -40 +KPX Aring Ograve -40 +KPX Aring Ohungarumlaut -40 +KPX Aring Omacron -40 +KPX Aring Oslash -40 +KPX Aring Otilde -40 +KPX Aring Q -40 +KPX Aring T -90 +KPX Aring Tcaron -90 +KPX Aring Tcommaaccent -90 +KPX Aring U -50 +KPX Aring Uacute -50 +KPX Aring Ucircumflex -50 +KPX Aring Udieresis -50 +KPX Aring Ugrave -50 +KPX Aring Uhungarumlaut -50 +KPX Aring Umacron -50 +KPX Aring Uogonek -50 +KPX Aring Uring -50 +KPX Aring V -80 +KPX Aring W -60 +KPX Aring Y -110 +KPX Aring Yacute -110 +KPX Aring Ydieresis -110 +KPX Aring u -30 +KPX Aring uacute -30 +KPX Aring ucircumflex -30 +KPX Aring udieresis -30 +KPX Aring ugrave -30 +KPX Aring uhungarumlaut -30 +KPX Aring umacron -30 +KPX Aring uogonek -30 +KPX Aring uring -30 +KPX Aring v -40 +KPX Aring w -30 +KPX Aring y -30 +KPX Aring yacute -30 +KPX Aring ydieresis -30 +KPX Atilde C -40 +KPX Atilde Cacute -40 +KPX Atilde Ccaron -40 +KPX Atilde Ccedilla -40 +KPX Atilde G -50 +KPX Atilde Gbreve -50 +KPX Atilde Gcommaaccent -50 +KPX Atilde O -40 +KPX Atilde Oacute -40 +KPX Atilde Ocircumflex -40 +KPX Atilde Odieresis -40 +KPX Atilde Ograve -40 +KPX Atilde Ohungarumlaut -40 +KPX Atilde Omacron -40 +KPX Atilde Oslash -40 +KPX Atilde Otilde -40 +KPX Atilde Q -40 +KPX Atilde T -90 +KPX Atilde Tcaron -90 +KPX Atilde Tcommaaccent -90 +KPX Atilde U -50 +KPX Atilde Uacute -50 +KPX Atilde Ucircumflex -50 +KPX Atilde Udieresis -50 +KPX Atilde Ugrave -50 +KPX Atilde Uhungarumlaut -50 +KPX Atilde Umacron -50 +KPX Atilde Uogonek -50 +KPX Atilde Uring -50 +KPX Atilde V -80 +KPX Atilde W -60 +KPX Atilde Y -110 +KPX Atilde Yacute -110 +KPX Atilde Ydieresis -110 +KPX Atilde u -30 +KPX Atilde uacute -30 +KPX Atilde ucircumflex -30 +KPX Atilde udieresis -30 +KPX Atilde ugrave -30 +KPX Atilde uhungarumlaut -30 +KPX Atilde umacron -30 +KPX Atilde uogonek -30 +KPX Atilde uring -30 +KPX Atilde v -40 +KPX Atilde w -30 +KPX Atilde y -30 +KPX Atilde yacute -30 +KPX Atilde ydieresis -30 +KPX B A -30 +KPX B Aacute -30 +KPX B Abreve -30 +KPX B Acircumflex -30 +KPX B Adieresis -30 +KPX B Agrave -30 +KPX B Amacron -30 +KPX B Aogonek -30 +KPX B Aring -30 +KPX B Atilde -30 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX D A -40 +KPX D Aacute -40 +KPX D Abreve -40 +KPX D Acircumflex -40 +KPX D Adieresis -40 +KPX D Agrave -40 +KPX D Amacron -40 +KPX D Aogonek -40 +KPX D Aring -40 +KPX D Atilde -40 +KPX D V -40 +KPX D W -40 +KPX D Y -70 +KPX D Yacute -70 +KPX D Ydieresis -70 +KPX D comma -30 +KPX D period -30 +KPX Dcaron A -40 +KPX Dcaron Aacute -40 +KPX Dcaron Abreve -40 +KPX Dcaron Acircumflex -40 +KPX Dcaron Adieresis -40 +KPX Dcaron Agrave -40 +KPX Dcaron Amacron -40 +KPX Dcaron Aogonek -40 +KPX Dcaron Aring -40 +KPX Dcaron Atilde -40 +KPX Dcaron V -40 +KPX Dcaron W -40 +KPX Dcaron Y -70 +KPX Dcaron Yacute -70 +KPX Dcaron Ydieresis -70 +KPX Dcaron comma -30 +KPX Dcaron period -30 +KPX Dcroat A -40 +KPX Dcroat Aacute -40 +KPX Dcroat Abreve -40 +KPX Dcroat Acircumflex -40 +KPX Dcroat Adieresis -40 +KPX Dcroat Agrave -40 +KPX Dcroat Amacron -40 +KPX Dcroat Aogonek -40 +KPX Dcroat Aring -40 +KPX Dcroat Atilde -40 +KPX Dcroat V -40 +KPX Dcroat W -40 +KPX Dcroat Y -70 +KPX Dcroat Yacute -70 +KPX Dcroat Ydieresis -70 +KPX Dcroat comma -30 +KPX Dcroat period -30 +KPX F A -80 +KPX F Aacute -80 +KPX F Abreve -80 +KPX F Acircumflex -80 +KPX F Adieresis -80 +KPX F Agrave -80 +KPX F Amacron -80 +KPX F Aogonek -80 +KPX F Aring -80 +KPX F Atilde -80 +KPX F a -20 +KPX F aacute -20 +KPX F abreve -20 +KPX F acircumflex -20 +KPX F adieresis -20 +KPX F agrave -20 +KPX F amacron -20 +KPX F aogonek -20 +KPX F aring -20 +KPX F atilde -20 +KPX F comma -100 +KPX F period -100 +KPX J A -20 +KPX J Aacute -20 +KPX J Abreve -20 +KPX J Acircumflex -20 +KPX J Adieresis -20 +KPX J Agrave -20 +KPX J Amacron -20 +KPX J Aogonek -20 +KPX J Aring -20 +KPX J Atilde -20 +KPX J comma -20 +KPX J period -20 +KPX J u -20 +KPX J uacute -20 +KPX J ucircumflex -20 +KPX J udieresis -20 +KPX J ugrave -20 +KPX J uhungarumlaut -20 +KPX J umacron -20 +KPX J uogonek -20 +KPX J uring -20 +KPX K O -30 +KPX K Oacute -30 +KPX K Ocircumflex -30 +KPX K Odieresis -30 +KPX K Ograve -30 +KPX K Ohungarumlaut -30 +KPX K Omacron -30 +KPX K Oslash -30 +KPX K Otilde -30 +KPX K e -15 +KPX K eacute -15 +KPX K ecaron -15 +KPX K ecircumflex -15 +KPX K edieresis -15 +KPX K edotaccent -15 +KPX K egrave -15 +KPX K emacron -15 +KPX K eogonek -15 +KPX K o -35 +KPX K oacute -35 +KPX K ocircumflex -35 +KPX K odieresis -35 +KPX K ograve -35 +KPX K ohungarumlaut -35 +KPX K omacron -35 +KPX K oslash -35 +KPX K otilde -35 +KPX K u -30 +KPX K uacute -30 +KPX K ucircumflex -30 +KPX K udieresis -30 +KPX K ugrave -30 +KPX K uhungarumlaut -30 +KPX K umacron -30 +KPX K uogonek -30 +KPX K uring -30 +KPX K y -40 +KPX K yacute -40 +KPX K ydieresis -40 +KPX Kcommaaccent O -30 +KPX Kcommaaccent Oacute -30 +KPX Kcommaaccent Ocircumflex -30 +KPX Kcommaaccent Odieresis -30 +KPX Kcommaaccent Ograve -30 +KPX Kcommaaccent Ohungarumlaut -30 +KPX Kcommaaccent Omacron -30 +KPX Kcommaaccent Oslash -30 +KPX Kcommaaccent Otilde -30 +KPX Kcommaaccent e -15 +KPX Kcommaaccent eacute -15 +KPX Kcommaaccent ecaron -15 +KPX Kcommaaccent ecircumflex -15 +KPX Kcommaaccent edieresis -15 +KPX Kcommaaccent edotaccent -15 +KPX Kcommaaccent egrave -15 +KPX Kcommaaccent emacron -15 +KPX Kcommaaccent eogonek -15 +KPX Kcommaaccent o -35 +KPX Kcommaaccent oacute -35 +KPX Kcommaaccent ocircumflex -35 +KPX Kcommaaccent odieresis -35 +KPX Kcommaaccent ograve -35 +KPX Kcommaaccent ohungarumlaut -35 +KPX Kcommaaccent omacron -35 +KPX Kcommaaccent oslash -35 +KPX Kcommaaccent otilde -35 +KPX Kcommaaccent u -30 +KPX Kcommaaccent uacute -30 +KPX Kcommaaccent ucircumflex -30 +KPX Kcommaaccent udieresis -30 +KPX Kcommaaccent ugrave -30 +KPX Kcommaaccent uhungarumlaut -30 +KPX Kcommaaccent umacron -30 +KPX Kcommaaccent uogonek -30 +KPX Kcommaaccent uring -30 +KPX Kcommaaccent y -40 +KPX Kcommaaccent yacute -40 +KPX Kcommaaccent ydieresis -40 +KPX L T -90 +KPX L Tcaron -90 +KPX L Tcommaaccent -90 +KPX L V -110 +KPX L W -80 +KPX L Y -120 +KPX L Yacute -120 +KPX L Ydieresis -120 +KPX L quotedblright -140 +KPX L quoteright -140 +KPX L y -30 +KPX L yacute -30 +KPX L ydieresis -30 +KPX Lacute T -90 +KPX Lacute Tcaron -90 +KPX Lacute Tcommaaccent -90 +KPX Lacute V -110 +KPX Lacute W -80 +KPX Lacute Y -120 +KPX Lacute Yacute -120 +KPX Lacute Ydieresis -120 +KPX Lacute quotedblright -140 +KPX Lacute quoteright -140 +KPX Lacute y -30 +KPX Lacute yacute -30 +KPX Lacute ydieresis -30 +KPX Lcommaaccent T -90 +KPX Lcommaaccent Tcaron -90 +KPX Lcommaaccent Tcommaaccent -90 +KPX Lcommaaccent V -110 +KPX Lcommaaccent W -80 +KPX Lcommaaccent Y -120 +KPX Lcommaaccent Yacute -120 +KPX Lcommaaccent Ydieresis -120 +KPX Lcommaaccent quotedblright -140 +KPX Lcommaaccent quoteright -140 +KPX Lcommaaccent y -30 +KPX Lcommaaccent yacute -30 +KPX Lcommaaccent ydieresis -30 +KPX Lslash T -90 +KPX Lslash Tcaron -90 +KPX Lslash Tcommaaccent -90 +KPX Lslash V -110 +KPX Lslash W -80 +KPX Lslash Y -120 +KPX Lslash Yacute -120 +KPX Lslash Ydieresis -120 +KPX Lslash quotedblright -140 +KPX Lslash quoteright -140 +KPX Lslash y -30 +KPX Lslash yacute -30 +KPX Lslash ydieresis -30 +KPX O A -50 +KPX O Aacute -50 +KPX O Abreve -50 +KPX O Acircumflex -50 +KPX O Adieresis -50 +KPX O Agrave -50 +KPX O Amacron -50 +KPX O Aogonek -50 +KPX O Aring -50 +KPX O Atilde -50 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -50 +KPX O X -50 +KPX O Y -70 +KPX O Yacute -70 +KPX O Ydieresis -70 +KPX O comma -40 +KPX O period -40 +KPX Oacute A -50 +KPX Oacute Aacute -50 +KPX Oacute Abreve -50 +KPX Oacute Acircumflex -50 +KPX Oacute Adieresis -50 +KPX Oacute Agrave -50 +KPX Oacute Amacron -50 +KPX Oacute Aogonek -50 +KPX Oacute Aring -50 +KPX Oacute Atilde -50 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -50 +KPX Oacute X -50 +KPX Oacute Y -70 +KPX Oacute Yacute -70 +KPX Oacute Ydieresis -70 +KPX Oacute comma -40 +KPX Oacute period -40 +KPX Ocircumflex A -50 +KPX Ocircumflex Aacute -50 +KPX Ocircumflex Abreve -50 +KPX Ocircumflex Acircumflex -50 +KPX Ocircumflex Adieresis -50 +KPX Ocircumflex Agrave -50 +KPX Ocircumflex Amacron -50 +KPX Ocircumflex Aogonek -50 +KPX Ocircumflex Aring -50 +KPX Ocircumflex Atilde -50 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -50 +KPX Ocircumflex X -50 +KPX Ocircumflex Y -70 +KPX Ocircumflex Yacute -70 +KPX Ocircumflex Ydieresis -70 +KPX Ocircumflex comma -40 +KPX Ocircumflex period -40 +KPX Odieresis A -50 +KPX Odieresis Aacute -50 +KPX Odieresis Abreve -50 +KPX Odieresis Acircumflex -50 +KPX Odieresis Adieresis -50 +KPX Odieresis Agrave -50 +KPX Odieresis Amacron -50 +KPX Odieresis Aogonek -50 +KPX Odieresis Aring -50 +KPX Odieresis Atilde -50 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -50 +KPX Odieresis X -50 +KPX Odieresis Y -70 +KPX Odieresis Yacute -70 +KPX Odieresis Ydieresis -70 +KPX Odieresis comma -40 +KPX Odieresis period -40 +KPX Ograve A -50 +KPX Ograve Aacute -50 +KPX Ograve Abreve -50 +KPX Ograve Acircumflex -50 +KPX Ograve Adieresis -50 +KPX Ograve Agrave -50 +KPX Ograve Amacron -50 +KPX Ograve Aogonek -50 +KPX Ograve Aring -50 +KPX Ograve Atilde -50 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -50 +KPX Ograve X -50 +KPX Ograve Y -70 +KPX Ograve Yacute -70 +KPX Ograve Ydieresis -70 +KPX Ograve comma -40 +KPX Ograve period -40 +KPX Ohungarumlaut A -50 +KPX Ohungarumlaut Aacute -50 +KPX Ohungarumlaut Abreve -50 +KPX Ohungarumlaut Acircumflex -50 +KPX Ohungarumlaut Adieresis -50 +KPX Ohungarumlaut Agrave -50 +KPX Ohungarumlaut Amacron -50 +KPX Ohungarumlaut Aogonek -50 +KPX Ohungarumlaut Aring -50 +KPX Ohungarumlaut Atilde -50 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -50 +KPX Ohungarumlaut X -50 +KPX Ohungarumlaut Y -70 +KPX Ohungarumlaut Yacute -70 +KPX Ohungarumlaut Ydieresis -70 +KPX Ohungarumlaut comma -40 +KPX Ohungarumlaut period -40 +KPX Omacron A -50 +KPX Omacron Aacute -50 +KPX Omacron Abreve -50 +KPX Omacron Acircumflex -50 +KPX Omacron Adieresis -50 +KPX Omacron Agrave -50 +KPX Omacron Amacron -50 +KPX Omacron Aogonek -50 +KPX Omacron Aring -50 +KPX Omacron Atilde -50 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -50 +KPX Omacron X -50 +KPX Omacron Y -70 +KPX Omacron Yacute -70 +KPX Omacron Ydieresis -70 +KPX Omacron comma -40 +KPX Omacron period -40 +KPX Oslash A -50 +KPX Oslash Aacute -50 +KPX Oslash Abreve -50 +KPX Oslash Acircumflex -50 +KPX Oslash Adieresis -50 +KPX Oslash Agrave -50 +KPX Oslash Amacron -50 +KPX Oslash Aogonek -50 +KPX Oslash Aring -50 +KPX Oslash Atilde -50 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -50 +KPX Oslash X -50 +KPX Oslash Y -70 +KPX Oslash Yacute -70 +KPX Oslash Ydieresis -70 +KPX Oslash comma -40 +KPX Oslash period -40 +KPX Otilde A -50 +KPX Otilde Aacute -50 +KPX Otilde Abreve -50 +KPX Otilde Acircumflex -50 +KPX Otilde Adieresis -50 +KPX Otilde Agrave -50 +KPX Otilde Amacron -50 +KPX Otilde Aogonek -50 +KPX Otilde Aring -50 +KPX Otilde Atilde -50 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -50 +KPX Otilde X -50 +KPX Otilde Y -70 +KPX Otilde Yacute -70 +KPX Otilde Ydieresis -70 +KPX Otilde comma -40 +KPX Otilde period -40 +KPX P A -100 +KPX P Aacute -100 +KPX P Abreve -100 +KPX P Acircumflex -100 +KPX P Adieresis -100 +KPX P Agrave -100 +KPX P Amacron -100 +KPX P Aogonek -100 +KPX P Aring -100 +KPX P Atilde -100 +KPX P a -30 +KPX P aacute -30 +KPX P abreve -30 +KPX P acircumflex -30 +KPX P adieresis -30 +KPX P agrave -30 +KPX P amacron -30 +KPX P aogonek -30 +KPX P aring -30 +KPX P atilde -30 +KPX P comma -120 +KPX P e -30 +KPX P eacute -30 +KPX P ecaron -30 +KPX P ecircumflex -30 +KPX P edieresis -30 +KPX P edotaccent -30 +KPX P egrave -30 +KPX P emacron -30 +KPX P eogonek -30 +KPX P o -40 +KPX P oacute -40 +KPX P ocircumflex -40 +KPX P odieresis -40 +KPX P ograve -40 +KPX P ohungarumlaut -40 +KPX P omacron -40 +KPX P oslash -40 +KPX P otilde -40 +KPX P period -120 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX Q comma 20 +KPX Q period 20 +KPX R O -20 +KPX R Oacute -20 +KPX R Ocircumflex -20 +KPX R Odieresis -20 +KPX R Ograve -20 +KPX R Ohungarumlaut -20 +KPX R Omacron -20 +KPX R Oslash -20 +KPX R Otilde -20 +KPX R T -20 +KPX R Tcaron -20 +KPX R Tcommaaccent -20 +KPX R U -20 +KPX R Uacute -20 +KPX R Ucircumflex -20 +KPX R Udieresis -20 +KPX R Ugrave -20 +KPX R Uhungarumlaut -20 +KPX R Umacron -20 +KPX R Uogonek -20 +KPX R Uring -20 +KPX R V -50 +KPX R W -40 +KPX R Y -50 +KPX R Yacute -50 +KPX R Ydieresis -50 +KPX Racute O -20 +KPX Racute Oacute -20 +KPX Racute Ocircumflex -20 +KPX Racute Odieresis -20 +KPX Racute Ograve -20 +KPX Racute Ohungarumlaut -20 +KPX Racute Omacron -20 +KPX Racute Oslash -20 +KPX Racute Otilde -20 +KPX Racute T -20 +KPX Racute Tcaron -20 +KPX Racute Tcommaaccent -20 +KPX Racute U -20 +KPX Racute Uacute -20 +KPX Racute Ucircumflex -20 +KPX Racute Udieresis -20 +KPX Racute Ugrave -20 +KPX Racute Uhungarumlaut -20 +KPX Racute Umacron -20 +KPX Racute Uogonek -20 +KPX Racute Uring -20 +KPX Racute V -50 +KPX Racute W -40 +KPX Racute Y -50 +KPX Racute Yacute -50 +KPX Racute Ydieresis -50 +KPX Rcaron O -20 +KPX Rcaron Oacute -20 +KPX Rcaron Ocircumflex -20 +KPX Rcaron Odieresis -20 +KPX Rcaron Ograve -20 +KPX Rcaron Ohungarumlaut -20 +KPX Rcaron Omacron -20 +KPX Rcaron Oslash -20 +KPX Rcaron Otilde -20 +KPX Rcaron T -20 +KPX Rcaron Tcaron -20 +KPX Rcaron Tcommaaccent -20 +KPX Rcaron U -20 +KPX Rcaron Uacute -20 +KPX Rcaron Ucircumflex -20 +KPX Rcaron Udieresis -20 +KPX Rcaron Ugrave -20 +KPX Rcaron Uhungarumlaut -20 +KPX Rcaron Umacron -20 +KPX Rcaron Uogonek -20 +KPX Rcaron Uring -20 +KPX Rcaron V -50 +KPX Rcaron W -40 +KPX Rcaron Y -50 +KPX Rcaron Yacute -50 +KPX Rcaron Ydieresis -50 +KPX Rcommaaccent O -20 +KPX Rcommaaccent Oacute -20 +KPX Rcommaaccent Ocircumflex -20 +KPX Rcommaaccent Odieresis -20 +KPX Rcommaaccent Ograve -20 +KPX Rcommaaccent Ohungarumlaut -20 +KPX Rcommaaccent Omacron -20 +KPX Rcommaaccent Oslash -20 +KPX Rcommaaccent Otilde -20 +KPX Rcommaaccent T -20 +KPX Rcommaaccent Tcaron -20 +KPX Rcommaaccent Tcommaaccent -20 +KPX Rcommaaccent U -20 +KPX Rcommaaccent Uacute -20 +KPX Rcommaaccent Ucircumflex -20 +KPX Rcommaaccent Udieresis -20 +KPX Rcommaaccent Ugrave -20 +KPX Rcommaaccent Uhungarumlaut -20 +KPX Rcommaaccent Umacron -20 +KPX Rcommaaccent Uogonek -20 +KPX Rcommaaccent Uring -20 +KPX Rcommaaccent V -50 +KPX Rcommaaccent W -40 +KPX Rcommaaccent Y -50 +KPX Rcommaaccent Yacute -50 +KPX Rcommaaccent Ydieresis -50 +KPX T A -90 +KPX T Aacute -90 +KPX T Abreve -90 +KPX T Acircumflex -90 +KPX T Adieresis -90 +KPX T Agrave -90 +KPX T Amacron -90 +KPX T Aogonek -90 +KPX T Aring -90 +KPX T Atilde -90 +KPX T O -40 +KPX T Oacute -40 +KPX T Ocircumflex -40 +KPX T Odieresis -40 +KPX T Ograve -40 +KPX T Ohungarumlaut -40 +KPX T Omacron -40 +KPX T Oslash -40 +KPX T Otilde -40 +KPX T a -80 +KPX T aacute -80 +KPX T abreve -80 +KPX T acircumflex -80 +KPX T adieresis -80 +KPX T agrave -80 +KPX T amacron -80 +KPX T aogonek -80 +KPX T aring -80 +KPX T atilde -80 +KPX T colon -40 +KPX T comma -80 +KPX T e -60 +KPX T eacute -60 +KPX T ecaron -60 +KPX T ecircumflex -60 +KPX T edieresis -60 +KPX T edotaccent -60 +KPX T egrave -60 +KPX T emacron -60 +KPX T eogonek -60 +KPX T hyphen -120 +KPX T o -80 +KPX T oacute -80 +KPX T ocircumflex -80 +KPX T odieresis -80 +KPX T ograve -80 +KPX T ohungarumlaut -80 +KPX T omacron -80 +KPX T oslash -80 +KPX T otilde -80 +KPX T period -80 +KPX T r -80 +KPX T racute -80 +KPX T rcommaaccent -80 +KPX T semicolon -40 +KPX T u -90 +KPX T uacute -90 +KPX T ucircumflex -90 +KPX T udieresis -90 +KPX T ugrave -90 +KPX T uhungarumlaut -90 +KPX T umacron -90 +KPX T uogonek -90 +KPX T uring -90 +KPX T w -60 +KPX T y -60 +KPX T yacute -60 +KPX T ydieresis -60 +KPX Tcaron A -90 +KPX Tcaron Aacute -90 +KPX Tcaron Abreve -90 +KPX Tcaron Acircumflex -90 +KPX Tcaron Adieresis -90 +KPX Tcaron Agrave -90 +KPX Tcaron Amacron -90 +KPX Tcaron Aogonek -90 +KPX Tcaron Aring -90 +KPX Tcaron Atilde -90 +KPX Tcaron O -40 +KPX Tcaron Oacute -40 +KPX Tcaron Ocircumflex -40 +KPX Tcaron Odieresis -40 +KPX Tcaron Ograve -40 +KPX Tcaron Ohungarumlaut -40 +KPX Tcaron Omacron -40 +KPX Tcaron Oslash -40 +KPX Tcaron Otilde -40 +KPX Tcaron a -80 +KPX Tcaron aacute -80 +KPX Tcaron abreve -80 +KPX Tcaron acircumflex -80 +KPX Tcaron adieresis -80 +KPX Tcaron agrave -80 +KPX Tcaron amacron -80 +KPX Tcaron aogonek -80 +KPX Tcaron aring -80 +KPX Tcaron atilde -80 +KPX Tcaron colon -40 +KPX Tcaron comma -80 +KPX Tcaron e -60 +KPX Tcaron eacute -60 +KPX Tcaron ecaron -60 +KPX Tcaron ecircumflex -60 +KPX Tcaron edieresis -60 +KPX Tcaron edotaccent -60 +KPX Tcaron egrave -60 +KPX Tcaron emacron -60 +KPX Tcaron eogonek -60 +KPX Tcaron hyphen -120 +KPX Tcaron o -80 +KPX Tcaron oacute -80 +KPX Tcaron ocircumflex -80 +KPX Tcaron odieresis -80 +KPX Tcaron ograve -80 +KPX Tcaron ohungarumlaut -80 +KPX Tcaron omacron -80 +KPX Tcaron oslash -80 +KPX Tcaron otilde -80 +KPX Tcaron period -80 +KPX Tcaron r -80 +KPX Tcaron racute -80 +KPX Tcaron rcommaaccent -80 +KPX Tcaron semicolon -40 +KPX Tcaron u -90 +KPX Tcaron uacute -90 +KPX Tcaron ucircumflex -90 +KPX Tcaron udieresis -90 +KPX Tcaron ugrave -90 +KPX Tcaron uhungarumlaut -90 +KPX Tcaron umacron -90 +KPX Tcaron uogonek -90 +KPX Tcaron uring -90 +KPX Tcaron w -60 +KPX Tcaron y -60 +KPX Tcaron yacute -60 +KPX Tcaron ydieresis -60 +KPX Tcommaaccent A -90 +KPX Tcommaaccent Aacute -90 +KPX Tcommaaccent Abreve -90 +KPX Tcommaaccent Acircumflex -90 +KPX Tcommaaccent Adieresis -90 +KPX Tcommaaccent Agrave -90 +KPX Tcommaaccent Amacron -90 +KPX Tcommaaccent Aogonek -90 +KPX Tcommaaccent Aring -90 +KPX Tcommaaccent Atilde -90 +KPX Tcommaaccent O -40 +KPX Tcommaaccent Oacute -40 +KPX Tcommaaccent Ocircumflex -40 +KPX Tcommaaccent Odieresis -40 +KPX Tcommaaccent Ograve -40 +KPX Tcommaaccent Ohungarumlaut -40 +KPX Tcommaaccent Omacron -40 +KPX Tcommaaccent Oslash -40 +KPX Tcommaaccent Otilde -40 +KPX Tcommaaccent a -80 +KPX Tcommaaccent aacute -80 +KPX Tcommaaccent abreve -80 +KPX Tcommaaccent acircumflex -80 +KPX Tcommaaccent adieresis -80 +KPX Tcommaaccent agrave -80 +KPX Tcommaaccent amacron -80 +KPX Tcommaaccent aogonek -80 +KPX Tcommaaccent aring -80 +KPX Tcommaaccent atilde -80 +KPX Tcommaaccent colon -40 +KPX Tcommaaccent comma -80 +KPX Tcommaaccent e -60 +KPX Tcommaaccent eacute -60 +KPX Tcommaaccent ecaron -60 +KPX Tcommaaccent ecircumflex -60 +KPX Tcommaaccent edieresis -60 +KPX Tcommaaccent edotaccent -60 +KPX Tcommaaccent egrave -60 +KPX Tcommaaccent emacron -60 +KPX Tcommaaccent eogonek -60 +KPX Tcommaaccent hyphen -120 +KPX Tcommaaccent o -80 +KPX Tcommaaccent oacute -80 +KPX Tcommaaccent ocircumflex -80 +KPX Tcommaaccent odieresis -80 +KPX Tcommaaccent ograve -80 +KPX Tcommaaccent ohungarumlaut -80 +KPX Tcommaaccent omacron -80 +KPX Tcommaaccent oslash -80 +KPX Tcommaaccent otilde -80 +KPX Tcommaaccent period -80 +KPX Tcommaaccent r -80 +KPX Tcommaaccent racute -80 +KPX Tcommaaccent rcommaaccent -80 +KPX Tcommaaccent semicolon -40 +KPX Tcommaaccent u -90 +KPX Tcommaaccent uacute -90 +KPX Tcommaaccent ucircumflex -90 +KPX Tcommaaccent udieresis -90 +KPX Tcommaaccent ugrave -90 +KPX Tcommaaccent uhungarumlaut -90 +KPX Tcommaaccent umacron -90 +KPX Tcommaaccent uogonek -90 +KPX Tcommaaccent uring -90 +KPX Tcommaaccent w -60 +KPX Tcommaaccent y -60 +KPX Tcommaaccent yacute -60 +KPX Tcommaaccent ydieresis -60 +KPX U A -50 +KPX U Aacute -50 +KPX U Abreve -50 +KPX U Acircumflex -50 +KPX U Adieresis -50 +KPX U Agrave -50 +KPX U Amacron -50 +KPX U Aogonek -50 +KPX U Aring -50 +KPX U Atilde -50 +KPX U comma -30 +KPX U period -30 +KPX Uacute A -50 +KPX Uacute Aacute -50 +KPX Uacute Abreve -50 +KPX Uacute Acircumflex -50 +KPX Uacute Adieresis -50 +KPX Uacute Agrave -50 +KPX Uacute Amacron -50 +KPX Uacute Aogonek -50 +KPX Uacute Aring -50 +KPX Uacute Atilde -50 +KPX Uacute comma -30 +KPX Uacute period -30 +KPX Ucircumflex A -50 +KPX Ucircumflex Aacute -50 +KPX Ucircumflex Abreve -50 +KPX Ucircumflex Acircumflex -50 +KPX Ucircumflex Adieresis -50 +KPX Ucircumflex Agrave -50 +KPX Ucircumflex Amacron -50 +KPX Ucircumflex Aogonek -50 +KPX Ucircumflex Aring -50 +KPX Ucircumflex Atilde -50 +KPX Ucircumflex comma -30 +KPX Ucircumflex period -30 +KPX Udieresis A -50 +KPX Udieresis Aacute -50 +KPX Udieresis Abreve -50 +KPX Udieresis Acircumflex -50 +KPX Udieresis Adieresis -50 +KPX Udieresis Agrave -50 +KPX Udieresis Amacron -50 +KPX Udieresis Aogonek -50 +KPX Udieresis Aring -50 +KPX Udieresis Atilde -50 +KPX Udieresis comma -30 +KPX Udieresis period -30 +KPX Ugrave A -50 +KPX Ugrave Aacute -50 +KPX Ugrave Abreve -50 +KPX Ugrave Acircumflex -50 +KPX Ugrave Adieresis -50 +KPX Ugrave Agrave -50 +KPX Ugrave Amacron -50 +KPX Ugrave Aogonek -50 +KPX Ugrave Aring -50 +KPX Ugrave Atilde -50 +KPX Ugrave comma -30 +KPX Ugrave period -30 +KPX Uhungarumlaut A -50 +KPX Uhungarumlaut Aacute -50 +KPX Uhungarumlaut Abreve -50 +KPX Uhungarumlaut Acircumflex -50 +KPX Uhungarumlaut Adieresis -50 +KPX Uhungarumlaut Agrave -50 +KPX Uhungarumlaut Amacron -50 +KPX Uhungarumlaut Aogonek -50 +KPX Uhungarumlaut Aring -50 +KPX Uhungarumlaut Atilde -50 +KPX Uhungarumlaut comma -30 +KPX Uhungarumlaut period -30 +KPX Umacron A -50 +KPX Umacron Aacute -50 +KPX Umacron Abreve -50 +KPX Umacron Acircumflex -50 +KPX Umacron Adieresis -50 +KPX Umacron Agrave -50 +KPX Umacron Amacron -50 +KPX Umacron Aogonek -50 +KPX Umacron Aring -50 +KPX Umacron Atilde -50 +KPX Umacron comma -30 +KPX Umacron period -30 +KPX Uogonek A -50 +KPX Uogonek Aacute -50 +KPX Uogonek Abreve -50 +KPX Uogonek Acircumflex -50 +KPX Uogonek Adieresis -50 +KPX Uogonek Agrave -50 +KPX Uogonek Amacron -50 +KPX Uogonek Aogonek -50 +KPX Uogonek Aring -50 +KPX Uogonek Atilde -50 +KPX Uogonek comma -30 +KPX Uogonek period -30 +KPX Uring A -50 +KPX Uring Aacute -50 +KPX Uring Abreve -50 +KPX Uring Acircumflex -50 +KPX Uring Adieresis -50 +KPX Uring Agrave -50 +KPX Uring Amacron -50 +KPX Uring Aogonek -50 +KPX Uring Aring -50 +KPX Uring Atilde -50 +KPX Uring comma -30 +KPX Uring period -30 +KPX V A -80 +KPX V Aacute -80 +KPX V Abreve -80 +KPX V Acircumflex -80 +KPX V Adieresis -80 +KPX V Agrave -80 +KPX V Amacron -80 +KPX V Aogonek -80 +KPX V Aring -80 +KPX V Atilde -80 +KPX V G -50 +KPX V Gbreve -50 +KPX V Gcommaaccent -50 +KPX V O -50 +KPX V Oacute -50 +KPX V Ocircumflex -50 +KPX V Odieresis -50 +KPX V Ograve -50 +KPX V Ohungarumlaut -50 +KPX V Omacron -50 +KPX V Oslash -50 +KPX V Otilde -50 +KPX V a -60 +KPX V aacute -60 +KPX V abreve -60 +KPX V acircumflex -60 +KPX V adieresis -60 +KPX V agrave -60 +KPX V amacron -60 +KPX V aogonek -60 +KPX V aring -60 +KPX V atilde -60 +KPX V colon -40 +KPX V comma -120 +KPX V e -50 +KPX V eacute -50 +KPX V ecaron -50 +KPX V ecircumflex -50 +KPX V edieresis -50 +KPX V edotaccent -50 +KPX V egrave -50 +KPX V emacron -50 +KPX V eogonek -50 +KPX V hyphen -80 +KPX V o -90 +KPX V oacute -90 +KPX V ocircumflex -90 +KPX V odieresis -90 +KPX V ograve -90 +KPX V ohungarumlaut -90 +KPX V omacron -90 +KPX V oslash -90 +KPX V otilde -90 +KPX V period -120 +KPX V semicolon -40 +KPX V u -60 +KPX V uacute -60 +KPX V ucircumflex -60 +KPX V udieresis -60 +KPX V ugrave -60 +KPX V uhungarumlaut -60 +KPX V umacron -60 +KPX V uogonek -60 +KPX V uring -60 +KPX W A -60 +KPX W Aacute -60 +KPX W Abreve -60 +KPX W Acircumflex -60 +KPX W Adieresis -60 +KPX W Agrave -60 +KPX W Amacron -60 +KPX W Aogonek -60 +KPX W Aring -60 +KPX W Atilde -60 +KPX W O -20 +KPX W Oacute -20 +KPX W Ocircumflex -20 +KPX W Odieresis -20 +KPX W Ograve -20 +KPX W Ohungarumlaut -20 +KPX W Omacron -20 +KPX W Oslash -20 +KPX W Otilde -20 +KPX W a -40 +KPX W aacute -40 +KPX W abreve -40 +KPX W acircumflex -40 +KPX W adieresis -40 +KPX W agrave -40 +KPX W amacron -40 +KPX W aogonek -40 +KPX W aring -40 +KPX W atilde -40 +KPX W colon -10 +KPX W comma -80 +KPX W e -35 +KPX W eacute -35 +KPX W ecaron -35 +KPX W ecircumflex -35 +KPX W edieresis -35 +KPX W edotaccent -35 +KPX W egrave -35 +KPX W emacron -35 +KPX W eogonek -35 +KPX W hyphen -40 +KPX W o -60 +KPX W oacute -60 +KPX W ocircumflex -60 +KPX W odieresis -60 +KPX W ograve -60 +KPX W ohungarumlaut -60 +KPX W omacron -60 +KPX W oslash -60 +KPX W otilde -60 +KPX W period -80 +KPX W semicolon -10 +KPX W u -45 +KPX W uacute -45 +KPX W ucircumflex -45 +KPX W udieresis -45 +KPX W ugrave -45 +KPX W uhungarumlaut -45 +KPX W umacron -45 +KPX W uogonek -45 +KPX W uring -45 +KPX W y -20 +KPX W yacute -20 +KPX W ydieresis -20 +KPX Y A -110 +KPX Y Aacute -110 +KPX Y Abreve -110 +KPX Y Acircumflex -110 +KPX Y Adieresis -110 +KPX Y Agrave -110 +KPX Y Amacron -110 +KPX Y Aogonek -110 +KPX Y Aring -110 +KPX Y Atilde -110 +KPX Y O -70 +KPX Y Oacute -70 +KPX Y Ocircumflex -70 +KPX Y Odieresis -70 +KPX Y Ograve -70 +KPX Y Ohungarumlaut -70 +KPX Y Omacron -70 +KPX Y Oslash -70 +KPX Y Otilde -70 +KPX Y a -90 +KPX Y aacute -90 +KPX Y abreve -90 +KPX Y acircumflex -90 +KPX Y adieresis -90 +KPX Y agrave -90 +KPX Y amacron -90 +KPX Y aogonek -90 +KPX Y aring -90 +KPX Y atilde -90 +KPX Y colon -50 +KPX Y comma -100 +KPX Y e -80 +KPX Y eacute -80 +KPX Y ecaron -80 +KPX Y ecircumflex -80 +KPX Y edieresis -80 +KPX Y edotaccent -80 +KPX Y egrave -80 +KPX Y emacron -80 +KPX Y eogonek -80 +KPX Y o -100 +KPX Y oacute -100 +KPX Y ocircumflex -100 +KPX Y odieresis -100 +KPX Y ograve -100 +KPX Y ohungarumlaut -100 +KPX Y omacron -100 +KPX Y oslash -100 +KPX Y otilde -100 +KPX Y period -100 +KPX Y semicolon -50 +KPX Y u -100 +KPX Y uacute -100 +KPX Y ucircumflex -100 +KPX Y udieresis -100 +KPX Y ugrave -100 +KPX Y uhungarumlaut -100 +KPX Y umacron -100 +KPX Y uogonek -100 +KPX Y uring -100 +KPX Yacute A -110 +KPX Yacute Aacute -110 +KPX Yacute Abreve -110 +KPX Yacute Acircumflex -110 +KPX Yacute Adieresis -110 +KPX Yacute Agrave -110 +KPX Yacute Amacron -110 +KPX Yacute Aogonek -110 +KPX Yacute Aring -110 +KPX Yacute Atilde -110 +KPX Yacute O -70 +KPX Yacute Oacute -70 +KPX Yacute Ocircumflex -70 +KPX Yacute Odieresis -70 +KPX Yacute Ograve -70 +KPX Yacute Ohungarumlaut -70 +KPX Yacute Omacron -70 +KPX Yacute Oslash -70 +KPX Yacute Otilde -70 +KPX Yacute a -90 +KPX Yacute aacute -90 +KPX Yacute abreve -90 +KPX Yacute acircumflex -90 +KPX Yacute adieresis -90 +KPX Yacute agrave -90 +KPX Yacute amacron -90 +KPX Yacute aogonek -90 +KPX Yacute aring -90 +KPX Yacute atilde -90 +KPX Yacute colon -50 +KPX Yacute comma -100 +KPX Yacute e -80 +KPX Yacute eacute -80 +KPX Yacute ecaron -80 +KPX Yacute ecircumflex -80 +KPX Yacute edieresis -80 +KPX Yacute edotaccent -80 +KPX Yacute egrave -80 +KPX Yacute emacron -80 +KPX Yacute eogonek -80 +KPX Yacute o -100 +KPX Yacute oacute -100 +KPX Yacute ocircumflex -100 +KPX Yacute odieresis -100 +KPX Yacute ograve -100 +KPX Yacute ohungarumlaut -100 +KPX Yacute omacron -100 +KPX Yacute oslash -100 +KPX Yacute otilde -100 +KPX Yacute period -100 +KPX Yacute semicolon -50 +KPX Yacute u -100 +KPX Yacute uacute -100 +KPX Yacute ucircumflex -100 +KPX Yacute udieresis -100 +KPX Yacute ugrave -100 +KPX Yacute uhungarumlaut -100 +KPX Yacute umacron -100 +KPX Yacute uogonek -100 +KPX Yacute uring -100 +KPX Ydieresis A -110 +KPX Ydieresis Aacute -110 +KPX Ydieresis Abreve -110 +KPX Ydieresis Acircumflex -110 +KPX Ydieresis Adieresis -110 +KPX Ydieresis Agrave -110 +KPX Ydieresis Amacron -110 +KPX Ydieresis Aogonek -110 +KPX Ydieresis Aring -110 +KPX Ydieresis Atilde -110 +KPX Ydieresis O -70 +KPX Ydieresis Oacute -70 +KPX Ydieresis Ocircumflex -70 +KPX Ydieresis Odieresis -70 +KPX Ydieresis Ograve -70 +KPX Ydieresis Ohungarumlaut -70 +KPX Ydieresis Omacron -70 +KPX Ydieresis Oslash -70 +KPX Ydieresis Otilde -70 +KPX Ydieresis a -90 +KPX Ydieresis aacute -90 +KPX Ydieresis abreve -90 +KPX Ydieresis acircumflex -90 +KPX Ydieresis adieresis -90 +KPX Ydieresis agrave -90 +KPX Ydieresis amacron -90 +KPX Ydieresis aogonek -90 +KPX Ydieresis aring -90 +KPX Ydieresis atilde -90 +KPX Ydieresis colon -50 +KPX Ydieresis comma -100 +KPX Ydieresis e -80 +KPX Ydieresis eacute -80 +KPX Ydieresis ecaron -80 +KPX Ydieresis ecircumflex -80 +KPX Ydieresis edieresis -80 +KPX Ydieresis edotaccent -80 +KPX Ydieresis egrave -80 +KPX Ydieresis emacron -80 +KPX Ydieresis eogonek -80 +KPX Ydieresis o -100 +KPX Ydieresis oacute -100 +KPX Ydieresis ocircumflex -100 +KPX Ydieresis odieresis -100 +KPX Ydieresis ograve -100 +KPX Ydieresis ohungarumlaut -100 +KPX Ydieresis omacron -100 +KPX Ydieresis oslash -100 +KPX Ydieresis otilde -100 +KPX Ydieresis period -100 +KPX Ydieresis semicolon -50 +KPX Ydieresis u -100 +KPX Ydieresis uacute -100 +KPX Ydieresis ucircumflex -100 +KPX Ydieresis udieresis -100 +KPX Ydieresis ugrave -100 +KPX Ydieresis uhungarumlaut -100 +KPX Ydieresis umacron -100 +KPX Ydieresis uogonek -100 +KPX Ydieresis uring -100 +KPX a g -10 +KPX a gbreve -10 +KPX a gcommaaccent -10 +KPX a v -15 +KPX a w -15 +KPX a y -20 +KPX a yacute -20 +KPX a ydieresis -20 +KPX aacute g -10 +KPX aacute gbreve -10 +KPX aacute gcommaaccent -10 +KPX aacute v -15 +KPX aacute w -15 +KPX aacute y -20 +KPX aacute yacute -20 +KPX aacute ydieresis -20 +KPX abreve g -10 +KPX abreve gbreve -10 +KPX abreve gcommaaccent -10 +KPX abreve v -15 +KPX abreve w -15 +KPX abreve y -20 +KPX abreve yacute -20 +KPX abreve ydieresis -20 +KPX acircumflex g -10 +KPX acircumflex gbreve -10 +KPX acircumflex gcommaaccent -10 +KPX acircumflex v -15 +KPX acircumflex w -15 +KPX acircumflex y -20 +KPX acircumflex yacute -20 +KPX acircumflex ydieresis -20 +KPX adieresis g -10 +KPX adieresis gbreve -10 +KPX adieresis gcommaaccent -10 +KPX adieresis v -15 +KPX adieresis w -15 +KPX adieresis y -20 +KPX adieresis yacute -20 +KPX adieresis ydieresis -20 +KPX agrave g -10 +KPX agrave gbreve -10 +KPX agrave gcommaaccent -10 +KPX agrave v -15 +KPX agrave w -15 +KPX agrave y -20 +KPX agrave yacute -20 +KPX agrave ydieresis -20 +KPX amacron g -10 +KPX amacron gbreve -10 +KPX amacron gcommaaccent -10 +KPX amacron v -15 +KPX amacron w -15 +KPX amacron y -20 +KPX amacron yacute -20 +KPX amacron ydieresis -20 +KPX aogonek g -10 +KPX aogonek gbreve -10 +KPX aogonek gcommaaccent -10 +KPX aogonek v -15 +KPX aogonek w -15 +KPX aogonek y -20 +KPX aogonek yacute -20 +KPX aogonek ydieresis -20 +KPX aring g -10 +KPX aring gbreve -10 +KPX aring gcommaaccent -10 +KPX aring v -15 +KPX aring w -15 +KPX aring y -20 +KPX aring yacute -20 +KPX aring ydieresis -20 +KPX atilde g -10 +KPX atilde gbreve -10 +KPX atilde gcommaaccent -10 +KPX atilde v -15 +KPX atilde w -15 +KPX atilde y -20 +KPX atilde yacute -20 +KPX atilde ydieresis -20 +KPX b l -10 +KPX b lacute -10 +KPX b lcommaaccent -10 +KPX b lslash -10 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX b v -20 +KPX b y -20 +KPX b yacute -20 +KPX b ydieresis -20 +KPX c h -10 +KPX c k -20 +KPX c kcommaaccent -20 +KPX c l -20 +KPX c lacute -20 +KPX c lcommaaccent -20 +KPX c lslash -20 +KPX c y -10 +KPX c yacute -10 +KPX c ydieresis -10 +KPX cacute h -10 +KPX cacute k -20 +KPX cacute kcommaaccent -20 +KPX cacute l -20 +KPX cacute lacute -20 +KPX cacute lcommaaccent -20 +KPX cacute lslash -20 +KPX cacute y -10 +KPX cacute yacute -10 +KPX cacute ydieresis -10 +KPX ccaron h -10 +KPX ccaron k -20 +KPX ccaron kcommaaccent -20 +KPX ccaron l -20 +KPX ccaron lacute -20 +KPX ccaron lcommaaccent -20 +KPX ccaron lslash -20 +KPX ccaron y -10 +KPX ccaron yacute -10 +KPX ccaron ydieresis -10 +KPX ccedilla h -10 +KPX ccedilla k -20 +KPX ccedilla kcommaaccent -20 +KPX ccedilla l -20 +KPX ccedilla lacute -20 +KPX ccedilla lcommaaccent -20 +KPX ccedilla lslash -20 +KPX ccedilla y -10 +KPX ccedilla yacute -10 +KPX ccedilla ydieresis -10 +KPX colon space -40 +KPX comma quotedblright -120 +KPX comma quoteright -120 +KPX comma space -40 +KPX d d -10 +KPX d dcroat -10 +KPX d v -15 +KPX d w -15 +KPX d y -15 +KPX d yacute -15 +KPX d ydieresis -15 +KPX dcroat d -10 +KPX dcroat dcroat -10 +KPX dcroat v -15 +KPX dcroat w -15 +KPX dcroat y -15 +KPX dcroat yacute -15 +KPX dcroat ydieresis -15 +KPX e comma 10 +KPX e period 20 +KPX e v -15 +KPX e w -15 +KPX e x -15 +KPX e y -15 +KPX e yacute -15 +KPX e ydieresis -15 +KPX eacute comma 10 +KPX eacute period 20 +KPX eacute v -15 +KPX eacute w -15 +KPX eacute x -15 +KPX eacute y -15 +KPX eacute yacute -15 +KPX eacute ydieresis -15 +KPX ecaron comma 10 +KPX ecaron period 20 +KPX ecaron v -15 +KPX ecaron w -15 +KPX ecaron x -15 +KPX ecaron y -15 +KPX ecaron yacute -15 +KPX ecaron ydieresis -15 +KPX ecircumflex comma 10 +KPX ecircumflex period 20 +KPX ecircumflex v -15 +KPX ecircumflex w -15 +KPX ecircumflex x -15 +KPX ecircumflex y -15 +KPX ecircumflex yacute -15 +KPX ecircumflex ydieresis -15 +KPX edieresis comma 10 +KPX edieresis period 20 +KPX edieresis v -15 +KPX edieresis w -15 +KPX edieresis x -15 +KPX edieresis y -15 +KPX edieresis yacute -15 +KPX edieresis ydieresis -15 +KPX edotaccent comma 10 +KPX edotaccent period 20 +KPX edotaccent v -15 +KPX edotaccent w -15 +KPX edotaccent x -15 +KPX edotaccent y -15 +KPX edotaccent yacute -15 +KPX edotaccent ydieresis -15 +KPX egrave comma 10 +KPX egrave period 20 +KPX egrave v -15 +KPX egrave w -15 +KPX egrave x -15 +KPX egrave y -15 +KPX egrave yacute -15 +KPX egrave ydieresis -15 +KPX emacron comma 10 +KPX emacron period 20 +KPX emacron v -15 +KPX emacron w -15 +KPX emacron x -15 +KPX emacron y -15 +KPX emacron yacute -15 +KPX emacron ydieresis -15 +KPX eogonek comma 10 +KPX eogonek period 20 +KPX eogonek v -15 +KPX eogonek w -15 +KPX eogonek x -15 +KPX eogonek y -15 +KPX eogonek yacute -15 +KPX eogonek ydieresis -15 +KPX f comma -10 +KPX f e -10 +KPX f eacute -10 +KPX f ecaron -10 +KPX f ecircumflex -10 +KPX f edieresis -10 +KPX f edotaccent -10 +KPX f egrave -10 +KPX f emacron -10 +KPX f eogonek -10 +KPX f o -20 +KPX f oacute -20 +KPX f ocircumflex -20 +KPX f odieresis -20 +KPX f ograve -20 +KPX f ohungarumlaut -20 +KPX f omacron -20 +KPX f oslash -20 +KPX f otilde -20 +KPX f period -10 +KPX f quotedblright 30 +KPX f quoteright 30 +KPX g e 10 +KPX g eacute 10 +KPX g ecaron 10 +KPX g ecircumflex 10 +KPX g edieresis 10 +KPX g edotaccent 10 +KPX g egrave 10 +KPX g emacron 10 +KPX g eogonek 10 +KPX g g -10 +KPX g gbreve -10 +KPX g gcommaaccent -10 +KPX gbreve e 10 +KPX gbreve eacute 10 +KPX gbreve ecaron 10 +KPX gbreve ecircumflex 10 +KPX gbreve edieresis 10 +KPX gbreve edotaccent 10 +KPX gbreve egrave 10 +KPX gbreve emacron 10 +KPX gbreve eogonek 10 +KPX gbreve g -10 +KPX gbreve gbreve -10 +KPX gbreve gcommaaccent -10 +KPX gcommaaccent e 10 +KPX gcommaaccent eacute 10 +KPX gcommaaccent ecaron 10 +KPX gcommaaccent ecircumflex 10 +KPX gcommaaccent edieresis 10 +KPX gcommaaccent edotaccent 10 +KPX gcommaaccent egrave 10 +KPX gcommaaccent emacron 10 +KPX gcommaaccent eogonek 10 +KPX gcommaaccent g -10 +KPX gcommaaccent gbreve -10 +KPX gcommaaccent gcommaaccent -10 +KPX h y -20 +KPX h yacute -20 +KPX h ydieresis -20 +KPX k o -15 +KPX k oacute -15 +KPX k ocircumflex -15 +KPX k odieresis -15 +KPX k ograve -15 +KPX k ohungarumlaut -15 +KPX k omacron -15 +KPX k oslash -15 +KPX k otilde -15 +KPX kcommaaccent o -15 +KPX kcommaaccent oacute -15 +KPX kcommaaccent ocircumflex -15 +KPX kcommaaccent odieresis -15 +KPX kcommaaccent ograve -15 +KPX kcommaaccent ohungarumlaut -15 +KPX kcommaaccent omacron -15 +KPX kcommaaccent oslash -15 +KPX kcommaaccent otilde -15 +KPX l w -15 +KPX l y -15 +KPX l yacute -15 +KPX l ydieresis -15 +KPX lacute w -15 +KPX lacute y -15 +KPX lacute yacute -15 +KPX lacute ydieresis -15 +KPX lcommaaccent w -15 +KPX lcommaaccent y -15 +KPX lcommaaccent yacute -15 +KPX lcommaaccent ydieresis -15 +KPX lslash w -15 +KPX lslash y -15 +KPX lslash yacute -15 +KPX lslash ydieresis -15 +KPX m u -20 +KPX m uacute -20 +KPX m ucircumflex -20 +KPX m udieresis -20 +KPX m ugrave -20 +KPX m uhungarumlaut -20 +KPX m umacron -20 +KPX m uogonek -20 +KPX m uring -20 +KPX m y -30 +KPX m yacute -30 +KPX m ydieresis -30 +KPX n u -10 +KPX n uacute -10 +KPX n ucircumflex -10 +KPX n udieresis -10 +KPX n ugrave -10 +KPX n uhungarumlaut -10 +KPX n umacron -10 +KPX n uogonek -10 +KPX n uring -10 +KPX n v -40 +KPX n y -20 +KPX n yacute -20 +KPX n ydieresis -20 +KPX nacute u -10 +KPX nacute uacute -10 +KPX nacute ucircumflex -10 +KPX nacute udieresis -10 +KPX nacute ugrave -10 +KPX nacute uhungarumlaut -10 +KPX nacute umacron -10 +KPX nacute uogonek -10 +KPX nacute uring -10 +KPX nacute v -40 +KPX nacute y -20 +KPX nacute yacute -20 +KPX nacute ydieresis -20 +KPX ncaron u -10 +KPX ncaron uacute -10 +KPX ncaron ucircumflex -10 +KPX ncaron udieresis -10 +KPX ncaron ugrave -10 +KPX ncaron uhungarumlaut -10 +KPX ncaron umacron -10 +KPX ncaron uogonek -10 +KPX ncaron uring -10 +KPX ncaron v -40 +KPX ncaron y -20 +KPX ncaron yacute -20 +KPX ncaron ydieresis -20 +KPX ncommaaccent u -10 +KPX ncommaaccent uacute -10 +KPX ncommaaccent ucircumflex -10 +KPX ncommaaccent udieresis -10 +KPX ncommaaccent ugrave -10 +KPX ncommaaccent uhungarumlaut -10 +KPX ncommaaccent umacron -10 +KPX ncommaaccent uogonek -10 +KPX ncommaaccent uring -10 +KPX ncommaaccent v -40 +KPX ncommaaccent y -20 +KPX ncommaaccent yacute -20 +KPX ncommaaccent ydieresis -20 +KPX ntilde u -10 +KPX ntilde uacute -10 +KPX ntilde ucircumflex -10 +KPX ntilde udieresis -10 +KPX ntilde ugrave -10 +KPX ntilde uhungarumlaut -10 +KPX ntilde umacron -10 +KPX ntilde uogonek -10 +KPX ntilde uring -10 +KPX ntilde v -40 +KPX ntilde y -20 +KPX ntilde yacute -20 +KPX ntilde ydieresis -20 +KPX o v -20 +KPX o w -15 +KPX o x -30 +KPX o y -20 +KPX o yacute -20 +KPX o ydieresis -20 +KPX oacute v -20 +KPX oacute w -15 +KPX oacute x -30 +KPX oacute y -20 +KPX oacute yacute -20 +KPX oacute ydieresis -20 +KPX ocircumflex v -20 +KPX ocircumflex w -15 +KPX ocircumflex x -30 +KPX ocircumflex y -20 +KPX ocircumflex yacute -20 +KPX ocircumflex ydieresis -20 +KPX odieresis v -20 +KPX odieresis w -15 +KPX odieresis x -30 +KPX odieresis y -20 +KPX odieresis yacute -20 +KPX odieresis ydieresis -20 +KPX ograve v -20 +KPX ograve w -15 +KPX ograve x -30 +KPX ograve y -20 +KPX ograve yacute -20 +KPX ograve ydieresis -20 +KPX ohungarumlaut v -20 +KPX ohungarumlaut w -15 +KPX ohungarumlaut x -30 +KPX ohungarumlaut y -20 +KPX ohungarumlaut yacute -20 +KPX ohungarumlaut ydieresis -20 +KPX omacron v -20 +KPX omacron w -15 +KPX omacron x -30 +KPX omacron y -20 +KPX omacron yacute -20 +KPX omacron ydieresis -20 +KPX oslash v -20 +KPX oslash w -15 +KPX oslash x -30 +KPX oslash y -20 +KPX oslash yacute -20 +KPX oslash ydieresis -20 +KPX otilde v -20 +KPX otilde w -15 +KPX otilde x -30 +KPX otilde y -20 +KPX otilde yacute -20 +KPX otilde ydieresis -20 +KPX p y -15 +KPX p yacute -15 +KPX p ydieresis -15 +KPX period quotedblright -120 +KPX period quoteright -120 +KPX period space -40 +KPX quotedblright space -80 +KPX quoteleft quoteleft -46 +KPX quoteright d -80 +KPX quoteright dcroat -80 +KPX quoteright l -20 +KPX quoteright lacute -20 +KPX quoteright lcommaaccent -20 +KPX quoteright lslash -20 +KPX quoteright quoteright -46 +KPX quoteright r -40 +KPX quoteright racute -40 +KPX quoteright rcaron -40 +KPX quoteright rcommaaccent -40 +KPX quoteright s -60 +KPX quoteright sacute -60 +KPX quoteright scaron -60 +KPX quoteright scedilla -60 +KPX quoteright scommaaccent -60 +KPX quoteright space -80 +KPX quoteright v -20 +KPX r c -20 +KPX r cacute -20 +KPX r ccaron -20 +KPX r ccedilla -20 +KPX r comma -60 +KPX r d -20 +KPX r dcroat -20 +KPX r g -15 +KPX r gbreve -15 +KPX r gcommaaccent -15 +KPX r hyphen -20 +KPX r o -20 +KPX r oacute -20 +KPX r ocircumflex -20 +KPX r odieresis -20 +KPX r ograve -20 +KPX r ohungarumlaut -20 +KPX r omacron -20 +KPX r oslash -20 +KPX r otilde -20 +KPX r period -60 +KPX r q -20 +KPX r s -15 +KPX r sacute -15 +KPX r scaron -15 +KPX r scedilla -15 +KPX r scommaaccent -15 +KPX r t 20 +KPX r tcommaaccent 20 +KPX r v 10 +KPX r y 10 +KPX r yacute 10 +KPX r ydieresis 10 +KPX racute c -20 +KPX racute cacute -20 +KPX racute ccaron -20 +KPX racute ccedilla -20 +KPX racute comma -60 +KPX racute d -20 +KPX racute dcroat -20 +KPX racute g -15 +KPX racute gbreve -15 +KPX racute gcommaaccent -15 +KPX racute hyphen -20 +KPX racute o -20 +KPX racute oacute -20 +KPX racute ocircumflex -20 +KPX racute odieresis -20 +KPX racute ograve -20 +KPX racute ohungarumlaut -20 +KPX racute omacron -20 +KPX racute oslash -20 +KPX racute otilde -20 +KPX racute period -60 +KPX racute q -20 +KPX racute s -15 +KPX racute sacute -15 +KPX racute scaron -15 +KPX racute scedilla -15 +KPX racute scommaaccent -15 +KPX racute t 20 +KPX racute tcommaaccent 20 +KPX racute v 10 +KPX racute y 10 +KPX racute yacute 10 +KPX racute ydieresis 10 +KPX rcaron c -20 +KPX rcaron cacute -20 +KPX rcaron ccaron -20 +KPX rcaron ccedilla -20 +KPX rcaron comma -60 +KPX rcaron d -20 +KPX rcaron dcroat -20 +KPX rcaron g -15 +KPX rcaron gbreve -15 +KPX rcaron gcommaaccent -15 +KPX rcaron hyphen -20 +KPX rcaron o -20 +KPX rcaron oacute -20 +KPX rcaron ocircumflex -20 +KPX rcaron odieresis -20 +KPX rcaron ograve -20 +KPX rcaron ohungarumlaut -20 +KPX rcaron omacron -20 +KPX rcaron oslash -20 +KPX rcaron otilde -20 +KPX rcaron period -60 +KPX rcaron q -20 +KPX rcaron s -15 +KPX rcaron sacute -15 +KPX rcaron scaron -15 +KPX rcaron scedilla -15 +KPX rcaron scommaaccent -15 +KPX rcaron t 20 +KPX rcaron tcommaaccent 20 +KPX rcaron v 10 +KPX rcaron y 10 +KPX rcaron yacute 10 +KPX rcaron ydieresis 10 +KPX rcommaaccent c -20 +KPX rcommaaccent cacute -20 +KPX rcommaaccent ccaron -20 +KPX rcommaaccent ccedilla -20 +KPX rcommaaccent comma -60 +KPX rcommaaccent d -20 +KPX rcommaaccent dcroat -20 +KPX rcommaaccent g -15 +KPX rcommaaccent gbreve -15 +KPX rcommaaccent gcommaaccent -15 +KPX rcommaaccent hyphen -20 +KPX rcommaaccent o -20 +KPX rcommaaccent oacute -20 +KPX rcommaaccent ocircumflex -20 +KPX rcommaaccent odieresis -20 +KPX rcommaaccent ograve -20 +KPX rcommaaccent ohungarumlaut -20 +KPX rcommaaccent omacron -20 +KPX rcommaaccent oslash -20 +KPX rcommaaccent otilde -20 +KPX rcommaaccent period -60 +KPX rcommaaccent q -20 +KPX rcommaaccent s -15 +KPX rcommaaccent sacute -15 +KPX rcommaaccent scaron -15 +KPX rcommaaccent scedilla -15 +KPX rcommaaccent scommaaccent -15 +KPX rcommaaccent t 20 +KPX rcommaaccent tcommaaccent 20 +KPX rcommaaccent v 10 +KPX rcommaaccent y 10 +KPX rcommaaccent yacute 10 +KPX rcommaaccent ydieresis 10 +KPX s w -15 +KPX sacute w -15 +KPX scaron w -15 +KPX scedilla w -15 +KPX scommaaccent w -15 +KPX semicolon space -40 +KPX space T -100 +KPX space Tcaron -100 +KPX space Tcommaaccent -100 +KPX space V -80 +KPX space W -80 +KPX space Y -120 +KPX space Yacute -120 +KPX space Ydieresis -120 +KPX space quotedblleft -80 +KPX space quoteleft -60 +KPX v a -20 +KPX v aacute -20 +KPX v abreve -20 +KPX v acircumflex -20 +KPX v adieresis -20 +KPX v agrave -20 +KPX v amacron -20 +KPX v aogonek -20 +KPX v aring -20 +KPX v atilde -20 +KPX v comma -80 +KPX v o -30 +KPX v oacute -30 +KPX v ocircumflex -30 +KPX v odieresis -30 +KPX v ograve -30 +KPX v ohungarumlaut -30 +KPX v omacron -30 +KPX v oslash -30 +KPX v otilde -30 +KPX v period -80 +KPX w comma -40 +KPX w o -20 +KPX w oacute -20 +KPX w ocircumflex -20 +KPX w odieresis -20 +KPX w ograve -20 +KPX w ohungarumlaut -20 +KPX w omacron -20 +KPX w oslash -20 +KPX w otilde -20 +KPX w period -40 +KPX x e -10 +KPX x eacute -10 +KPX x ecaron -10 +KPX x ecircumflex -10 +KPX x edieresis -10 +KPX x edotaccent -10 +KPX x egrave -10 +KPX x emacron -10 +KPX x eogonek -10 +KPX y a -30 +KPX y aacute -30 +KPX y abreve -30 +KPX y acircumflex -30 +KPX y adieresis -30 +KPX y agrave -30 +KPX y amacron -30 +KPX y aogonek -30 +KPX y aring -30 +KPX y atilde -30 +KPX y comma -80 +KPX y e -10 +KPX y eacute -10 +KPX y ecaron -10 +KPX y ecircumflex -10 +KPX y edieresis -10 +KPX y edotaccent -10 +KPX y egrave -10 +KPX y emacron -10 +KPX y eogonek -10 +KPX y o -25 +KPX y oacute -25 +KPX y ocircumflex -25 +KPX y odieresis -25 +KPX y ograve -25 +KPX y ohungarumlaut -25 +KPX y omacron -25 +KPX y oslash -25 +KPX y otilde -25 +KPX y period -80 +KPX yacute a -30 +KPX yacute aacute -30 +KPX yacute abreve -30 +KPX yacute acircumflex -30 +KPX yacute adieresis -30 +KPX yacute agrave -30 +KPX yacute amacron -30 +KPX yacute aogonek -30 +KPX yacute aring -30 +KPX yacute atilde -30 +KPX yacute comma -80 +KPX yacute e -10 +KPX yacute eacute -10 +KPX yacute ecaron -10 +KPX yacute ecircumflex -10 +KPX yacute edieresis -10 +KPX yacute edotaccent -10 +KPX yacute egrave -10 +KPX yacute emacron -10 +KPX yacute eogonek -10 +KPX yacute o -25 +KPX yacute oacute -25 +KPX yacute ocircumflex -25 +KPX yacute odieresis -25 +KPX yacute ograve -25 +KPX yacute ohungarumlaut -25 +KPX yacute omacron -25 +KPX yacute oslash -25 +KPX yacute otilde -25 +KPX yacute period -80 +KPX ydieresis a -30 +KPX ydieresis aacute -30 +KPX ydieresis abreve -30 +KPX ydieresis acircumflex -30 +KPX ydieresis adieresis -30 +KPX ydieresis agrave -30 +KPX ydieresis amacron -30 +KPX ydieresis aogonek -30 +KPX ydieresis aring -30 +KPX ydieresis atilde -30 +KPX ydieresis comma -80 +KPX ydieresis e -10 +KPX ydieresis eacute -10 +KPX ydieresis ecaron -10 +KPX ydieresis ecircumflex -10 +KPX ydieresis edieresis -10 +KPX ydieresis edotaccent -10 +KPX ydieresis egrave -10 +KPX ydieresis emacron -10 +KPX ydieresis eogonek -10 +KPX ydieresis o -25 +KPX ydieresis oacute -25 +KPX ydieresis ocircumflex -25 +KPX ydieresis odieresis -25 +KPX ydieresis ograve -25 +KPX ydieresis ohungarumlaut -25 +KPX ydieresis omacron -25 +KPX ydieresis oslash -25 +KPX ydieresis otilde -25 +KPX ydieresis period -80 +KPX z e 10 +KPX z eacute 10 +KPX z ecaron 10 +KPX z ecircumflex 10 +KPX z edieresis 10 +KPX z edotaccent 10 +KPX z egrave 10 +KPX z emacron 10 +KPX z eogonek 10 +KPX zacute e 10 +KPX zacute eacute 10 +KPX zacute ecaron 10 +KPX zacute ecircumflex 10 +KPX zacute edieresis 10 +KPX zacute edotaccent 10 +KPX zacute egrave 10 +KPX zacute emacron 10 +KPX zacute eogonek 10 +KPX zcaron e 10 +KPX zcaron eacute 10 +KPX zcaron ecaron 10 +KPX zcaron ecircumflex 10 +KPX zcaron edieresis 10 +KPX zcaron edotaccent 10 +KPX zcaron egrave 10 +KPX zcaron emacron 10 +KPX zcaron eogonek 10 +KPX zdotaccent e 10 +KPX zdotaccent eacute 10 +KPX zdotaccent ecaron 10 +KPX zdotaccent ecircumflex 10 +KPX zdotaccent edieresis 10 +KPX zdotaccent edotaccent 10 +KPX zdotaccent egrave 10 +KPX zdotaccent emacron 10 +KPX zdotaccent eogonek 10 +EndKernPairs +EndKernData +EndFontMetrics addfile ./Core14_AFMs/Helvetica-BoldOblique.afm hunk ./Core14_AFMs/Helvetica-BoldOblique.afm 1 +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 12:45:12 1997 +Comment UniqueID 43053 +Comment VMusage 14482 68586 +FontName Helvetica-BoldOblique +FullName Helvetica Bold Oblique +FamilyName Helvetica +Weight Bold +ItalicAngle -12 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -174 -228 1114 962 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 532 +Ascender 718 +Descender -207 +StdHW 118 +StdVW 140 +StartCharMetrics 315 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 94 0 397 718 ; +C 34 ; WX 474 ; N quotedbl ; B 193 447 529 718 ; +C 35 ; WX 556 ; N numbersign ; B 60 0 644 698 ; +C 36 ; WX 556 ; N dollar ; B 67 -115 622 775 ; +C 37 ; WX 889 ; N percent ; B 136 -19 901 710 ; +C 38 ; WX 722 ; N ampersand ; B 89 -19 732 718 ; +C 39 ; WX 278 ; N quoteright ; B 167 445 362 718 ; +C 40 ; WX 333 ; N parenleft ; B 76 -208 470 734 ; +C 41 ; WX 333 ; N parenright ; B -25 -208 369 734 ; +C 42 ; WX 389 ; N asterisk ; B 146 387 481 718 ; +C 43 ; WX 584 ; N plus ; B 82 0 610 506 ; +C 44 ; WX 278 ; N comma ; B 28 -168 245 146 ; +C 45 ; WX 333 ; N hyphen ; B 73 215 379 345 ; +C 46 ; WX 278 ; N period ; B 64 0 245 146 ; +C 47 ; WX 278 ; N slash ; B -37 -19 468 737 ; +C 48 ; WX 556 ; N zero ; B 86 -19 617 710 ; +C 49 ; WX 556 ; N one ; B 173 0 529 710 ; +C 50 ; WX 556 ; N two ; B 26 0 619 710 ; +C 51 ; WX 556 ; N three ; B 65 -19 608 710 ; +C 52 ; WX 556 ; N four ; B 60 0 598 710 ; +C 53 ; WX 556 ; N five ; B 64 -19 636 698 ; +C 54 ; WX 556 ; N six ; B 85 -19 619 710 ; +C 55 ; WX 556 ; N seven ; B 125 0 676 698 ; +C 56 ; WX 556 ; N eight ; B 69 -19 616 710 ; +C 57 ; WX 556 ; N nine ; B 78 -19 615 710 ; +C 58 ; WX 333 ; N colon ; B 92 0 351 512 ; +C 59 ; WX 333 ; N semicolon ; B 56 -168 351 512 ; +C 60 ; WX 584 ; N less ; B 82 -8 655 514 ; +C 61 ; WX 584 ; N equal ; B 58 87 633 419 ; +C 62 ; WX 584 ; N greater ; B 36 -8 609 514 ; +C 63 ; WX 611 ; N question ; B 165 0 671 727 ; +C 64 ; WX 975 ; N at ; B 186 -19 954 737 ; +C 65 ; WX 722 ; N A ; B 20 0 702 718 ; +C 66 ; WX 722 ; N B ; B 76 0 764 718 ; +C 67 ; WX 722 ; N C ; B 107 -19 789 737 ; +C 68 ; WX 722 ; N D ; B 76 0 777 718 ; +C 69 ; WX 667 ; N E ; B 76 0 757 718 ; +C 70 ; WX 611 ; N F ; B 76 0 740 718 ; +C 71 ; WX 778 ; N G ; B 108 -19 817 737 ; +C 72 ; WX 722 ; N H ; B 71 0 804 718 ; +C 73 ; WX 278 ; N I ; B 64 0 367 718 ; +C 74 ; WX 556 ; N J ; B 60 -18 637 718 ; +C 75 ; WX 722 ; N K ; B 87 0 858 718 ; +C 76 ; WX 611 ; N L ; B 76 0 611 718 ; +C 77 ; WX 833 ; N M ; B 69 0 918 718 ; +C 78 ; WX 722 ; N N ; B 69 0 807 718 ; +C 79 ; WX 778 ; N O ; B 107 -19 823 737 ; +C 80 ; WX 667 ; N P ; B 76 0 738 718 ; +C 81 ; WX 778 ; N Q ; B 107 -52 823 737 ; +C 82 ; WX 722 ; N R ; B 76 0 778 718 ; +C 83 ; WX 667 ; N S ; B 81 -19 718 737 ; +C 84 ; WX 611 ; N T ; B 140 0 751 718 ; +C 85 ; WX 722 ; N U ; B 116 -19 804 718 ; +C 86 ; WX 667 ; N V ; B 172 0 801 718 ; +C 87 ; WX 944 ; N W ; B 169 0 1082 718 ; +C 88 ; WX 667 ; N X ; B 14 0 791 718 ; +C 89 ; WX 667 ; N Y ; B 168 0 806 718 ; +C 90 ; WX 611 ; N Z ; B 25 0 737 718 ; +C 91 ; WX 333 ; N bracketleft ; B 21 -196 462 722 ; +C 92 ; WX 278 ; N backslash ; B 124 -19 307 737 ; +C 93 ; WX 333 ; N bracketright ; B -18 -196 423 722 ; +C 94 ; WX 584 ; N asciicircum ; B 131 323 591 698 ; +C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ; +C 96 ; WX 278 ; N quoteleft ; B 165 454 361 727 ; +C 97 ; WX 556 ; N a ; B 55 -14 583 546 ; +C 98 ; WX 611 ; N b ; B 61 -14 645 718 ; +C 99 ; WX 556 ; N c ; B 79 -14 599 546 ; +C 100 ; WX 611 ; N d ; B 82 -14 704 718 ; +C 101 ; WX 556 ; N e ; B 70 -14 593 546 ; +C 102 ; WX 333 ; N f ; B 87 0 469 727 ; L i fi ; L l fl ; +C 103 ; WX 611 ; N g ; B 38 -217 666 546 ; +C 104 ; WX 611 ; N h ; B 65 0 629 718 ; +C 105 ; WX 278 ; N i ; B 69 0 363 725 ; +C 106 ; WX 278 ; N j ; B -42 -214 363 725 ; +C 107 ; WX 556 ; N k ; B 69 0 670 718 ; +C 108 ; WX 278 ; N l ; B 69 0 362 718 ; +C 109 ; WX 889 ; N m ; B 64 0 909 546 ; +C 110 ; WX 611 ; N n ; B 65 0 629 546 ; +C 111 ; WX 611 ; N o ; B 82 -14 643 546 ; +C 112 ; WX 611 ; N p ; B 18 -207 645 546 ; +C 113 ; WX 611 ; N q ; B 80 -207 665 546 ; +C 114 ; WX 389 ; N r ; B 64 0 489 546 ; +C 115 ; WX 556 ; N s ; B 63 -14 584 546 ; +C 116 ; WX 333 ; N t ; B 100 -6 422 676 ; +C 117 ; WX 611 ; N u ; B 98 -14 658 532 ; +C 118 ; WX 556 ; N v ; B 126 0 656 532 ; +C 119 ; WX 778 ; N w ; B 123 0 882 532 ; +C 120 ; WX 556 ; N x ; B 15 0 648 532 ; +C 121 ; WX 556 ; N y ; B 42 -214 652 532 ; +C 122 ; WX 500 ; N z ; B 20 0 583 532 ; +C 123 ; WX 389 ; N braceleft ; B 94 -196 518 722 ; +C 124 ; WX 280 ; N bar ; B 36 -225 361 775 ; +C 125 ; WX 389 ; N braceright ; B -18 -196 407 722 ; +C 126 ; WX 584 ; N asciitilde ; B 115 163 577 343 ; +C 161 ; WX 333 ; N exclamdown ; B 50 -186 353 532 ; +C 162 ; WX 556 ; N cent ; B 79 -118 599 628 ; +C 163 ; WX 556 ; N sterling ; B 50 -16 635 718 ; +C 164 ; WX 167 ; N fraction ; B -174 -19 487 710 ; +C 165 ; WX 556 ; N yen ; B 60 0 713 698 ; +C 166 ; WX 556 ; N florin ; B -50 -210 669 737 ; +C 167 ; WX 556 ; N section ; B 61 -184 598 727 ; +C 168 ; WX 556 ; N currency ; B 27 76 680 636 ; +C 169 ; WX 238 ; N quotesingle ; B 165 447 321 718 ; +C 170 ; WX 500 ; N quotedblleft ; B 160 454 588 727 ; +C 171 ; WX 556 ; N guillemotleft ; B 135 76 571 484 ; +C 172 ; WX 333 ; N guilsinglleft ; B 130 76 353 484 ; +C 173 ; WX 333 ; N guilsinglright ; B 99 76 322 484 ; +C 174 ; WX 611 ; N fi ; B 87 0 696 727 ; +C 175 ; WX 611 ; N fl ; B 87 0 695 727 ; +C 177 ; WX 556 ; N endash ; B 48 227 627 333 ; +C 178 ; WX 556 ; N dagger ; B 118 -171 626 718 ; +C 179 ; WX 556 ; N daggerdbl ; B 46 -171 628 718 ; +C 180 ; WX 278 ; N periodcentered ; B 110 172 276 334 ; +C 182 ; WX 556 ; N paragraph ; B 98 -191 688 700 ; +C 183 ; WX 350 ; N bullet ; B 83 194 420 524 ; +C 184 ; WX 278 ; N quotesinglbase ; B 41 -146 236 127 ; +C 185 ; WX 500 ; N quotedblbase ; B 36 -146 463 127 ; +C 186 ; WX 500 ; N quotedblright ; B 162 445 589 718 ; +C 187 ; WX 556 ; N guillemotright ; B 104 76 540 484 ; +C 188 ; WX 1000 ; N ellipsis ; B 92 0 939 146 ; +C 189 ; WX 1000 ; N perthousand ; B 76 -19 1038 710 ; +C 191 ; WX 611 ; N questiondown ; B 53 -195 559 532 ; +C 193 ; WX 333 ; N grave ; B 136 604 353 750 ; +C 194 ; WX 333 ; N acute ; B 236 604 515 750 ; +C 195 ; WX 333 ; N circumflex ; B 118 604 471 750 ; +C 196 ; WX 333 ; N tilde ; B 113 610 507 737 ; +C 197 ; WX 333 ; N macron ; B 122 604 483 678 ; +C 198 ; WX 333 ; N breve ; B 156 604 494 750 ; +C 199 ; WX 333 ; N dotaccent ; B 235 614 385 729 ; +C 200 ; WX 333 ; N dieresis ; B 137 614 482 729 ; +C 202 ; WX 333 ; N ring ; B 200 568 420 776 ; +C 203 ; WX 333 ; N cedilla ; B -37 -228 220 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 137 604 645 750 ; +C 206 ; WX 333 ; N ogonek ; B 41 -228 264 0 ; +C 207 ; WX 333 ; N caron ; B 149 604 502 750 ; +C 208 ; WX 1000 ; N emdash ; B 48 227 1071 333 ; +C 225 ; WX 1000 ; N AE ; B 5 0 1100 718 ; +C 227 ; WX 370 ; N ordfeminine ; B 125 401 465 737 ; +C 232 ; WX 611 ; N Lslash ; B 34 0 611 718 ; +C 233 ; WX 778 ; N Oslash ; B 35 -27 894 745 ; +C 234 ; WX 1000 ; N OE ; B 99 -19 1114 737 ; +C 235 ; WX 365 ; N ordmasculine ; B 123 401 485 737 ; +C 241 ; WX 889 ; N ae ; B 56 -14 923 546 ; +C 245 ; WX 278 ; N dotlessi ; B 69 0 322 532 ; +C 248 ; WX 278 ; N lslash ; B 40 0 407 718 ; +C 249 ; WX 611 ; N oslash ; B 22 -29 701 560 ; +C 250 ; WX 944 ; N oe ; B 82 -14 977 546 ; +C 251 ; WX 611 ; N germandbls ; B 69 -14 657 731 ; +C -1 ; WX 278 ; N Idieresis ; B 64 0 494 915 ; +C -1 ; WX 556 ; N eacute ; B 70 -14 627 750 ; +C -1 ; WX 556 ; N abreve ; B 55 -14 606 750 ; +C -1 ; WX 611 ; N uhungarumlaut ; B 98 -14 784 750 ; +C -1 ; WX 556 ; N ecaron ; B 70 -14 614 750 ; +C -1 ; WX 667 ; N Ydieresis ; B 168 0 806 915 ; +C -1 ; WX 584 ; N divide ; B 82 -42 610 548 ; +C -1 ; WX 667 ; N Yacute ; B 168 0 806 936 ; +C -1 ; WX 722 ; N Acircumflex ; B 20 0 706 936 ; +C -1 ; WX 556 ; N aacute ; B 55 -14 627 750 ; +C -1 ; WX 722 ; N Ucircumflex ; B 116 -19 804 936 ; +C -1 ; WX 556 ; N yacute ; B 42 -214 652 750 ; +C -1 ; WX 556 ; N scommaaccent ; B 63 -228 584 546 ; +C -1 ; WX 556 ; N ecircumflex ; B 70 -14 593 750 ; +C -1 ; WX 722 ; N Uring ; B 116 -19 804 962 ; +C -1 ; WX 722 ; N Udieresis ; B 116 -19 804 915 ; +C -1 ; WX 556 ; N aogonek ; B 55 -224 583 546 ; +C -1 ; WX 722 ; N Uacute ; B 116 -19 804 936 ; +C -1 ; WX 611 ; N uogonek ; B 98 -228 658 532 ; +C -1 ; WX 667 ; N Edieresis ; B 76 0 757 915 ; +C -1 ; WX 722 ; N Dcroat ; B 62 0 777 718 ; +C -1 ; WX 250 ; N commaaccent ; B 16 -228 188 -50 ; +C -1 ; WX 737 ; N copyright ; B 56 -19 835 737 ; +C -1 ; WX 667 ; N Emacron ; B 76 0 757 864 ; +C -1 ; WX 556 ; N ccaron ; B 79 -14 614 750 ; +C -1 ; WX 556 ; N aring ; B 55 -14 583 776 ; +C -1 ; WX 722 ; N Ncommaaccent ; B 69 -228 807 718 ; +C -1 ; WX 278 ; N lacute ; B 69 0 528 936 ; +C -1 ; WX 556 ; N agrave ; B 55 -14 583 750 ; +C -1 ; WX 611 ; N Tcommaaccent ; B 140 -228 751 718 ; +C -1 ; WX 722 ; N Cacute ; B 107 -19 789 936 ; +C -1 ; WX 556 ; N atilde ; B 55 -14 619 737 ; +C -1 ; WX 667 ; N Edotaccent ; B 76 0 757 915 ; +C -1 ; WX 556 ; N scaron ; B 63 -14 614 750 ; +C -1 ; WX 556 ; N scedilla ; B 63 -228 584 546 ; +C -1 ; WX 278 ; N iacute ; B 69 0 488 750 ; +C -1 ; WX 494 ; N lozenge ; B 90 0 564 745 ; +C -1 ; WX 722 ; N Rcaron ; B 76 0 778 936 ; +C -1 ; WX 778 ; N Gcommaaccent ; B 108 -228 817 737 ; +C -1 ; WX 611 ; N ucircumflex ; B 98 -14 658 750 ; +C -1 ; WX 556 ; N acircumflex ; B 55 -14 583 750 ; +C -1 ; WX 722 ; N Amacron ; B 20 0 718 864 ; +C -1 ; WX 389 ; N rcaron ; B 64 0 530 750 ; +C -1 ; WX 556 ; N ccedilla ; B 79 -228 599 546 ; +C -1 ; WX 611 ; N Zdotaccent ; B 25 0 737 915 ; +C -1 ; WX 667 ; N Thorn ; B 76 0 716 718 ; +C -1 ; WX 778 ; N Omacron ; B 107 -19 823 864 ; +C -1 ; WX 722 ; N Racute ; B 76 0 778 936 ; +C -1 ; WX 667 ; N Sacute ; B 81 -19 722 936 ; +C -1 ; WX 743 ; N dcaron ; B 82 -14 903 718 ; +C -1 ; WX 722 ; N Umacron ; B 116 -19 804 864 ; +C -1 ; WX 611 ; N uring ; B 98 -14 658 776 ; +C -1 ; WX 333 ; N threesuperior ; B 91 271 441 710 ; +C -1 ; WX 778 ; N Ograve ; B 107 -19 823 936 ; +C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ; +C -1 ; WX 722 ; N Abreve ; B 20 0 729 936 ; +C -1 ; WX 584 ; N multiply ; B 57 1 635 505 ; +C -1 ; WX 611 ; N uacute ; B 98 -14 658 750 ; +C -1 ; WX 611 ; N Tcaron ; B 140 0 751 936 ; +C -1 ; WX 494 ; N partialdiff ; B 43 -21 585 750 ; +C -1 ; WX 556 ; N ydieresis ; B 42 -214 652 729 ; +C -1 ; WX 722 ; N Nacute ; B 69 0 807 936 ; +C -1 ; WX 278 ; N icircumflex ; B 69 0 444 750 ; +C -1 ; WX 667 ; N Ecircumflex ; B 76 0 757 936 ; +C -1 ; WX 556 ; N adieresis ; B 55 -14 594 729 ; +C -1 ; WX 556 ; N edieresis ; B 70 -14 594 729 ; +C -1 ; WX 556 ; N cacute ; B 79 -14 627 750 ; +C -1 ; WX 611 ; N nacute ; B 65 0 654 750 ; +C -1 ; WX 611 ; N umacron ; B 98 -14 658 678 ; +C -1 ; WX 722 ; N Ncaron ; B 69 0 807 936 ; +C -1 ; WX 278 ; N Iacute ; B 64 0 528 936 ; +C -1 ; WX 584 ; N plusminus ; B 40 0 625 506 ; +C -1 ; WX 280 ; N brokenbar ; B 52 -150 345 700 ; +C -1 ; WX 737 ; N registered ; B 55 -19 834 737 ; +C -1 ; WX 778 ; N Gbreve ; B 108 -19 817 936 ; +C -1 ; WX 278 ; N Idotaccent ; B 64 0 397 915 ; +C -1 ; WX 600 ; N summation ; B 14 -10 670 706 ; +C -1 ; WX 667 ; N Egrave ; B 76 0 757 936 ; +C -1 ; WX 389 ; N racute ; B 64 0 543 750 ; +C -1 ; WX 611 ; N omacron ; B 82 -14 643 678 ; +C -1 ; WX 611 ; N Zacute ; B 25 0 737 936 ; +C -1 ; WX 611 ; N Zcaron ; B 25 0 737 936 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 629 704 ; +C -1 ; WX 722 ; N Eth ; B 62 0 777 718 ; +C -1 ; WX 722 ; N Ccedilla ; B 107 -228 789 737 ; +C -1 ; WX 278 ; N lcommaaccent ; B 30 -228 362 718 ; +C -1 ; WX 389 ; N tcaron ; B 100 -6 608 878 ; +C -1 ; WX 556 ; N eogonek ; B 70 -228 593 546 ; +C -1 ; WX 722 ; N Uogonek ; B 116 -228 804 718 ; +C -1 ; WX 722 ; N Aacute ; B 20 0 750 936 ; +C -1 ; WX 722 ; N Adieresis ; B 20 0 716 915 ; +C -1 ; WX 556 ; N egrave ; B 70 -14 593 750 ; +C -1 ; WX 500 ; N zacute ; B 20 0 599 750 ; +C -1 ; WX 278 ; N iogonek ; B -14 -224 363 725 ; +C -1 ; WX 778 ; N Oacute ; B 107 -19 823 936 ; +C -1 ; WX 611 ; N oacute ; B 82 -14 654 750 ; +C -1 ; WX 556 ; N amacron ; B 55 -14 595 678 ; +C -1 ; WX 556 ; N sacute ; B 63 -14 627 750 ; +C -1 ; WX 278 ; N idieresis ; B 69 0 455 729 ; +C -1 ; WX 778 ; N Ocircumflex ; B 107 -19 823 936 ; +C -1 ; WX 722 ; N Ugrave ; B 116 -19 804 936 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 611 ; N thorn ; B 18 -208 645 718 ; +C -1 ; WX 333 ; N twosuperior ; B 69 283 449 710 ; +C -1 ; WX 778 ; N Odieresis ; B 107 -19 823 915 ; +C -1 ; WX 611 ; N mu ; B 22 -207 658 532 ; +C -1 ; WX 278 ; N igrave ; B 69 0 326 750 ; +C -1 ; WX 611 ; N ohungarumlaut ; B 82 -14 784 750 ; +C -1 ; WX 667 ; N Eogonek ; B 76 -224 757 718 ; +C -1 ; WX 611 ; N dcroat ; B 82 -14 789 718 ; +C -1 ; WX 834 ; N threequarters ; B 99 -19 839 710 ; +C -1 ; WX 667 ; N Scedilla ; B 81 -228 718 737 ; +C -1 ; WX 400 ; N lcaron ; B 69 0 561 718 ; +C -1 ; WX 722 ; N Kcommaaccent ; B 87 -228 858 718 ; +C -1 ; WX 611 ; N Lacute ; B 76 0 611 936 ; +C -1 ; WX 1000 ; N trademark ; B 179 306 1109 718 ; +C -1 ; WX 556 ; N edotaccent ; B 70 -14 593 729 ; +C -1 ; WX 278 ; N Igrave ; B 64 0 367 936 ; +C -1 ; WX 278 ; N Imacron ; B 64 0 496 864 ; +C -1 ; WX 611 ; N Lcaron ; B 76 0 643 718 ; +C -1 ; WX 834 ; N onehalf ; B 132 -19 858 710 ; +C -1 ; WX 549 ; N lessequal ; B 29 0 676 704 ; +C -1 ; WX 611 ; N ocircumflex ; B 82 -14 643 750 ; +C -1 ; WX 611 ; N ntilde ; B 65 0 646 737 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 116 -19 880 936 ; +C -1 ; WX 667 ; N Eacute ; B 76 0 757 936 ; +C -1 ; WX 556 ; N emacron ; B 70 -14 595 678 ; +C -1 ; WX 611 ; N gbreve ; B 38 -217 666 750 ; +C -1 ; WX 834 ; N onequarter ; B 132 -19 806 710 ; +C -1 ; WX 667 ; N Scaron ; B 81 -19 718 936 ; +C -1 ; WX 667 ; N Scommaaccent ; B 81 -228 718 737 ; +C -1 ; WX 778 ; N Ohungarumlaut ; B 107 -19 908 936 ; +C -1 ; WX 400 ; N degree ; B 175 426 467 712 ; +C -1 ; WX 611 ; N ograve ; B 82 -14 643 750 ; +C -1 ; WX 722 ; N Ccaron ; B 107 -19 789 936 ; +C -1 ; WX 611 ; N ugrave ; B 98 -14 658 750 ; +C -1 ; WX 549 ; N radical ; B 112 -46 689 850 ; +C -1 ; WX 722 ; N Dcaron ; B 76 0 777 936 ; +C -1 ; WX 389 ; N rcommaaccent ; B 26 -228 489 546 ; +C -1 ; WX 722 ; N Ntilde ; B 69 0 807 923 ; +C -1 ; WX 611 ; N otilde ; B 82 -14 646 737 ; +C -1 ; WX 722 ; N Rcommaaccent ; B 76 -228 778 718 ; +C -1 ; WX 611 ; N Lcommaaccent ; B 76 -228 611 718 ; +C -1 ; WX 722 ; N Atilde ; B 20 0 741 923 ; +C -1 ; WX 722 ; N Aogonek ; B 20 -224 702 718 ; +C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ; +C -1 ; WX 778 ; N Otilde ; B 107 -19 823 923 ; +C -1 ; WX 500 ; N zdotaccent ; B 20 0 583 729 ; +C -1 ; WX 667 ; N Ecaron ; B 76 0 757 936 ; +C -1 ; WX 278 ; N Iogonek ; B -41 -228 367 718 ; +C -1 ; WX 556 ; N kcommaaccent ; B 69 -228 670 718 ; +C -1 ; WX 584 ; N minus ; B 82 197 610 309 ; +C -1 ; WX 278 ; N Icircumflex ; B 64 0 484 936 ; +C -1 ; WX 611 ; N ncaron ; B 65 0 641 750 ; +C -1 ; WX 333 ; N tcommaaccent ; B 58 -228 422 676 ; +C -1 ; WX 584 ; N logicalnot ; B 105 108 633 419 ; +C -1 ; WX 611 ; N odieresis ; B 82 -14 643 729 ; +C -1 ; WX 611 ; N udieresis ; B 98 -14 658 729 ; +C -1 ; WX 549 ; N notequal ; B 32 -49 630 570 ; +C -1 ; WX 611 ; N gcommaaccent ; B 38 -217 666 850 ; +C -1 ; WX 611 ; N eth ; B 82 -14 670 737 ; +C -1 ; WX 500 ; N zcaron ; B 20 0 586 750 ; +C -1 ; WX 611 ; N ncommaaccent ; B 65 -228 629 546 ; +C -1 ; WX 333 ; N onesuperior ; B 148 283 388 710 ; +C -1 ; WX 278 ; N imacron ; B 69 0 429 678 ; +C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2481 +KPX A C -40 +KPX A Cacute -40 +KPX A Ccaron -40 +KPX A Ccedilla -40 +KPX A G -50 +KPX A Gbreve -50 +KPX A Gcommaaccent -50 +KPX A O -40 +KPX A Oacute -40 +KPX A Ocircumflex -40 +KPX A Odieresis -40 +KPX A Ograve -40 +KPX A Ohungarumlaut -40 +KPX A Omacron -40 +KPX A Oslash -40 +KPX A Otilde -40 +KPX A Q -40 +KPX A T -90 +KPX A Tcaron -90 +KPX A Tcommaaccent -90 +KPX A U -50 +KPX A Uacute -50 +KPX A Ucircumflex -50 +KPX A Udieresis -50 +KPX A Ugrave -50 +KPX A Uhungarumlaut -50 +KPX A Umacron -50 +KPX A Uogonek -50 +KPX A Uring -50 +KPX A V -80 +KPX A W -60 +KPX A Y -110 +KPX A Yacute -110 +KPX A Ydieresis -110 +KPX A u -30 +KPX A uacute -30 +KPX A ucircumflex -30 +KPX A udieresis -30 +KPX A ugrave -30 +KPX A uhungarumlaut -30 +KPX A umacron -30 +KPX A uogonek -30 +KPX A uring -30 +KPX A v -40 +KPX A w -30 +KPX A y -30 +KPX A yacute -30 +KPX A ydieresis -30 +KPX Aacute C -40 +KPX Aacute Cacute -40 +KPX Aacute Ccaron -40 +KPX Aacute Ccedilla -40 +KPX Aacute G -50 +KPX Aacute Gbreve -50 +KPX Aacute Gcommaaccent -50 +KPX Aacute O -40 +KPX Aacute Oacute -40 +KPX Aacute Ocircumflex -40 +KPX Aacute Odieresis -40 +KPX Aacute Ograve -40 +KPX Aacute Ohungarumlaut -40 +KPX Aacute Omacron -40 +KPX Aacute Oslash -40 +KPX Aacute Otilde -40 +KPX Aacute Q -40 +KPX Aacute T -90 +KPX Aacute Tcaron -90 +KPX Aacute Tcommaaccent -90 +KPX Aacute U -50 +KPX Aacute Uacute -50 +KPX Aacute Ucircumflex -50 +KPX Aacute Udieresis -50 +KPX Aacute Ugrave -50 +KPX Aacute Uhungarumlaut -50 +KPX Aacute Umacron -50 +KPX Aacute Uogonek -50 +KPX Aacute Uring -50 +KPX Aacute V -80 +KPX Aacute W -60 +KPX Aacute Y -110 +KPX Aacute Yacute -110 +KPX Aacute Ydieresis -110 +KPX Aacute u -30 +KPX Aacute uacute -30 +KPX Aacute ucircumflex -30 +KPX Aacute udieresis -30 +KPX Aacute ugrave -30 +KPX Aacute uhungarumlaut -30 +KPX Aacute umacron -30 +KPX Aacute uogonek -30 +KPX Aacute uring -30 +KPX Aacute v -40 +KPX Aacute w -30 +KPX Aacute y -30 +KPX Aacute yacute -30 +KPX Aacute ydieresis -30 +KPX Abreve C -40 +KPX Abreve Cacute -40 +KPX Abreve Ccaron -40 +KPX Abreve Ccedilla -40 +KPX Abreve G -50 +KPX Abreve Gbreve -50 +KPX Abreve Gcommaaccent -50 +KPX Abreve O -40 +KPX Abreve Oacute -40 +KPX Abreve Ocircumflex -40 +KPX Abreve Odieresis -40 +KPX Abreve Ograve -40 +KPX Abreve Ohungarumlaut -40 +KPX Abreve Omacron -40 +KPX Abreve Oslash -40 +KPX Abreve Otilde -40 +KPX Abreve Q -40 +KPX Abreve T -90 +KPX Abreve Tcaron -90 +KPX Abreve Tcommaaccent -90 +KPX Abreve U -50 +KPX Abreve Uacute -50 +KPX Abreve Ucircumflex -50 +KPX Abreve Udieresis -50 +KPX Abreve Ugrave -50 +KPX Abreve Uhungarumlaut -50 +KPX Abreve Umacron -50 +KPX Abreve Uogonek -50 +KPX Abreve Uring -50 +KPX Abreve V -80 +KPX Abreve W -60 +KPX Abreve Y -110 +KPX Abreve Yacute -110 +KPX Abreve Ydieresis -110 +KPX Abreve u -30 +KPX Abreve uacute -30 +KPX Abreve ucircumflex -30 +KPX Abreve udieresis -30 +KPX Abreve ugrave -30 +KPX Abreve uhungarumlaut -30 +KPX Abreve umacron -30 +KPX Abreve uogonek -30 +KPX Abreve uring -30 +KPX Abreve v -40 +KPX Abreve w -30 +KPX Abreve y -30 +KPX Abreve yacute -30 +KPX Abreve ydieresis -30 +KPX Acircumflex C -40 +KPX Acircumflex Cacute -40 +KPX Acircumflex Ccaron -40 +KPX Acircumflex Ccedilla -40 +KPX Acircumflex G -50 +KPX Acircumflex Gbreve -50 +KPX Acircumflex Gcommaaccent -50 +KPX Acircumflex O -40 +KPX Acircumflex Oacute -40 +KPX Acircumflex Ocircumflex -40 +KPX Acircumflex Odieresis -40 +KPX Acircumflex Ograve -40 +KPX Acircumflex Ohungarumlaut -40 +KPX Acircumflex Omacron -40 +KPX Acircumflex Oslash -40 +KPX Acircumflex Otilde -40 +KPX Acircumflex Q -40 +KPX Acircumflex T -90 +KPX Acircumflex Tcaron -90 +KPX Acircumflex Tcommaaccent -90 +KPX Acircumflex U -50 +KPX Acircumflex Uacute -50 +KPX Acircumflex Ucircumflex -50 +KPX Acircumflex Udieresis -50 +KPX Acircumflex Ugrave -50 +KPX Acircumflex Uhungarumlaut -50 +KPX Acircumflex Umacron -50 +KPX Acircumflex Uogonek -50 +KPX Acircumflex Uring -50 +KPX Acircumflex V -80 +KPX Acircumflex W -60 +KPX Acircumflex Y -110 +KPX Acircumflex Yacute -110 +KPX Acircumflex Ydieresis -110 +KPX Acircumflex u -30 +KPX Acircumflex uacute -30 +KPX Acircumflex ucircumflex -30 +KPX Acircumflex udieresis -30 +KPX Acircumflex ugrave -30 +KPX Acircumflex uhungarumlaut -30 +KPX Acircumflex umacron -30 +KPX Acircumflex uogonek -30 +KPX Acircumflex uring -30 +KPX Acircumflex v -40 +KPX Acircumflex w -30 +KPX Acircumflex y -30 +KPX Acircumflex yacute -30 +KPX Acircumflex ydieresis -30 +KPX Adieresis C -40 +KPX Adieresis Cacute -40 +KPX Adieresis Ccaron -40 +KPX Adieresis Ccedilla -40 +KPX Adieresis G -50 +KPX Adieresis Gbreve -50 +KPX Adieresis Gcommaaccent -50 +KPX Adieresis O -40 +KPX Adieresis Oacute -40 +KPX Adieresis Ocircumflex -40 +KPX Adieresis Odieresis -40 +KPX Adieresis Ograve -40 +KPX Adieresis Ohungarumlaut -40 +KPX Adieresis Omacron -40 +KPX Adieresis Oslash -40 +KPX Adieresis Otilde -40 +KPX Adieresis Q -40 +KPX Adieresis T -90 +KPX Adieresis Tcaron -90 +KPX Adieresis Tcommaaccent -90 +KPX Adieresis U -50 +KPX Adieresis Uacute -50 +KPX Adieresis Ucircumflex -50 +KPX Adieresis Udieresis -50 +KPX Adieresis Ugrave -50 +KPX Adieresis Uhungarumlaut -50 +KPX Adieresis Umacron -50 +KPX Adieresis Uogonek -50 +KPX Adieresis Uring -50 +KPX Adieresis V -80 +KPX Adieresis W -60 +KPX Adieresis Y -110 +KPX Adieresis Yacute -110 +KPX Adieresis Ydieresis -110 +KPX Adieresis u -30 +KPX Adieresis uacute -30 +KPX Adieresis ucircumflex -30 +KPX Adieresis udieresis -30 +KPX Adieresis ugrave -30 +KPX Adieresis uhungarumlaut -30 +KPX Adieresis umacron -30 +KPX Adieresis uogonek -30 +KPX Adieresis uring -30 +KPX Adieresis v -40 +KPX Adieresis w -30 +KPX Adieresis y -30 +KPX Adieresis yacute -30 +KPX Adieresis ydieresis -30 +KPX Agrave C -40 +KPX Agrave Cacute -40 +KPX Agrave Ccaron -40 +KPX Agrave Ccedilla -40 +KPX Agrave G -50 +KPX Agrave Gbreve -50 +KPX Agrave Gcommaaccent -50 +KPX Agrave O -40 +KPX Agrave Oacute -40 +KPX Agrave Ocircumflex -40 +KPX Agrave Odieresis -40 +KPX Agrave Ograve -40 +KPX Agrave Ohungarumlaut -40 +KPX Agrave Omacron -40 +KPX Agrave Oslash -40 +KPX Agrave Otilde -40 +KPX Agrave Q -40 +KPX Agrave T -90 +KPX Agrave Tcaron -90 +KPX Agrave Tcommaaccent -90 +KPX Agrave U -50 +KPX Agrave Uacute -50 +KPX Agrave Ucircumflex -50 +KPX Agrave Udieresis -50 +KPX Agrave Ugrave -50 +KPX Agrave Uhungarumlaut -50 +KPX Agrave Umacron -50 +KPX Agrave Uogonek -50 +KPX Agrave Uring -50 +KPX Agrave V -80 +KPX Agrave W -60 +KPX Agrave Y -110 +KPX Agrave Yacute -110 +KPX Agrave Ydieresis -110 +KPX Agrave u -30 +KPX Agrave uacute -30 +KPX Agrave ucircumflex -30 +KPX Agrave udieresis -30 +KPX Agrave ugrave -30 +KPX Agrave uhungarumlaut -30 +KPX Agrave umacron -30 +KPX Agrave uogonek -30 +KPX Agrave uring -30 +KPX Agrave v -40 +KPX Agrave w -30 +KPX Agrave y -30 +KPX Agrave yacute -30 +KPX Agrave ydieresis -30 +KPX Amacron C -40 +KPX Amacron Cacute -40 +KPX Amacron Ccaron -40 +KPX Amacron Ccedilla -40 +KPX Amacron G -50 +KPX Amacron Gbreve -50 +KPX Amacron Gcommaaccent -50 +KPX Amacron O -40 +KPX Amacron Oacute -40 +KPX Amacron Ocircumflex -40 +KPX Amacron Odieresis -40 +KPX Amacron Ograve -40 +KPX Amacron Ohungarumlaut -40 +KPX Amacron Omacron -40 +KPX Amacron Oslash -40 +KPX Amacron Otilde -40 +KPX Amacron Q -40 +KPX Amacron T -90 +KPX Amacron Tcaron -90 +KPX Amacron Tcommaaccent -90 +KPX Amacron U -50 +KPX Amacron Uacute -50 +KPX Amacron Ucircumflex -50 +KPX Amacron Udieresis -50 +KPX Amacron Ugrave -50 +KPX Amacron Uhungarumlaut -50 +KPX Amacron Umacron -50 +KPX Amacron Uogonek -50 +KPX Amacron Uring -50 +KPX Amacron V -80 +KPX Amacron W -60 +KPX Amacron Y -110 +KPX Amacron Yacute -110 +KPX Amacron Ydieresis -110 +KPX Amacron u -30 +KPX Amacron uacute -30 +KPX Amacron ucircumflex -30 +KPX Amacron udieresis -30 +KPX Amacron ugrave -30 +KPX Amacron uhungarumlaut -30 +KPX Amacron umacron -30 +KPX Amacron uogonek -30 +KPX Amacron uring -30 +KPX Amacron v -40 +KPX Amacron w -30 +KPX Amacron y -30 +KPX Amacron yacute -30 +KPX Amacron ydieresis -30 +KPX Aogonek C -40 +KPX Aogonek Cacute -40 +KPX Aogonek Ccaron -40 +KPX Aogonek Ccedilla -40 +KPX Aogonek G -50 +KPX Aogonek Gbreve -50 +KPX Aogonek Gcommaaccent -50 +KPX Aogonek O -40 +KPX Aogonek Oacute -40 +KPX Aogonek Ocircumflex -40 +KPX Aogonek Odieresis -40 +KPX Aogonek Ograve -40 +KPX Aogonek Ohungarumlaut -40 +KPX Aogonek Omacron -40 +KPX Aogonek Oslash -40 +KPX Aogonek Otilde -40 +KPX Aogonek Q -40 +KPX Aogonek T -90 +KPX Aogonek Tcaron -90 +KPX Aogonek Tcommaaccent -90 +KPX Aogonek U -50 +KPX Aogonek Uacute -50 +KPX Aogonek Ucircumflex -50 +KPX Aogonek Udieresis -50 +KPX Aogonek Ugrave -50 +KPX Aogonek Uhungarumlaut -50 +KPX Aogonek Umacron -50 +KPX Aogonek Uogonek -50 +KPX Aogonek Uring -50 +KPX Aogonek V -80 +KPX Aogonek W -60 +KPX Aogonek Y -110 +KPX Aogonek Yacute -110 +KPX Aogonek Ydieresis -110 +KPX Aogonek u -30 +KPX Aogonek uacute -30 +KPX Aogonek ucircumflex -30 +KPX Aogonek udieresis -30 +KPX Aogonek ugrave -30 +KPX Aogonek uhungarumlaut -30 +KPX Aogonek umacron -30 +KPX Aogonek uogonek -30 +KPX Aogonek uring -30 +KPX Aogonek v -40 +KPX Aogonek w -30 +KPX Aogonek y -30 +KPX Aogonek yacute -30 +KPX Aogonek ydieresis -30 +KPX Aring C -40 +KPX Aring Cacute -40 +KPX Aring Ccaron -40 +KPX Aring Ccedilla -40 +KPX Aring G -50 +KPX Aring Gbreve -50 +KPX Aring Gcommaaccent -50 +KPX Aring O -40 +KPX Aring Oacute -40 +KPX Aring Ocircumflex -40 +KPX Aring Odieresis -40 +KPX Aring Ograve -40 +KPX Aring Ohungarumlaut -40 +KPX Aring Omacron -40 +KPX Aring Oslash -40 +KPX Aring Otilde -40 +KPX Aring Q -40 +KPX Aring T -90 +KPX Aring Tcaron -90 +KPX Aring Tcommaaccent -90 +KPX Aring U -50 +KPX Aring Uacute -50 +KPX Aring Ucircumflex -50 +KPX Aring Udieresis -50 +KPX Aring Ugrave -50 +KPX Aring Uhungarumlaut -50 +KPX Aring Umacron -50 +KPX Aring Uogonek -50 +KPX Aring Uring -50 +KPX Aring V -80 +KPX Aring W -60 +KPX Aring Y -110 +KPX Aring Yacute -110 +KPX Aring Ydieresis -110 +KPX Aring u -30 +KPX Aring uacute -30 +KPX Aring ucircumflex -30 +KPX Aring udieresis -30 +KPX Aring ugrave -30 +KPX Aring uhungarumlaut -30 +KPX Aring umacron -30 +KPX Aring uogonek -30 +KPX Aring uring -30 +KPX Aring v -40 +KPX Aring w -30 +KPX Aring y -30 +KPX Aring yacute -30 +KPX Aring ydieresis -30 +KPX Atilde C -40 +KPX Atilde Cacute -40 +KPX Atilde Ccaron -40 +KPX Atilde Ccedilla -40 +KPX Atilde G -50 +KPX Atilde Gbreve -50 +KPX Atilde Gcommaaccent -50 +KPX Atilde O -40 +KPX Atilde Oacute -40 +KPX Atilde Ocircumflex -40 +KPX Atilde Odieresis -40 +KPX Atilde Ograve -40 +KPX Atilde Ohungarumlaut -40 +KPX Atilde Omacron -40 +KPX Atilde Oslash -40 +KPX Atilde Otilde -40 +KPX Atilde Q -40 +KPX Atilde T -90 +KPX Atilde Tcaron -90 +KPX Atilde Tcommaaccent -90 +KPX Atilde U -50 +KPX Atilde Uacute -50 +KPX Atilde Ucircumflex -50 +KPX Atilde Udieresis -50 +KPX Atilde Ugrave -50 +KPX Atilde Uhungarumlaut -50 +KPX Atilde Umacron -50 +KPX Atilde Uogonek -50 +KPX Atilde Uring -50 +KPX Atilde V -80 +KPX Atilde W -60 +KPX Atilde Y -110 +KPX Atilde Yacute -110 +KPX Atilde Ydieresis -110 +KPX Atilde u -30 +KPX Atilde uacute -30 +KPX Atilde ucircumflex -30 +KPX Atilde udieresis -30 +KPX Atilde ugrave -30 +KPX Atilde uhungarumlaut -30 +KPX Atilde umacron -30 +KPX Atilde uogonek -30 +KPX Atilde uring -30 +KPX Atilde v -40 +KPX Atilde w -30 +KPX Atilde y -30 +KPX Atilde yacute -30 +KPX Atilde ydieresis -30 +KPX B A -30 +KPX B Aacute -30 +KPX B Abreve -30 +KPX B Acircumflex -30 +KPX B Adieresis -30 +KPX B Agrave -30 +KPX B Amacron -30 +KPX B Aogonek -30 +KPX B Aring -30 +KPX B Atilde -30 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX D A -40 +KPX D Aacute -40 +KPX D Abreve -40 +KPX D Acircumflex -40 +KPX D Adieresis -40 +KPX D Agrave -40 +KPX D Amacron -40 +KPX D Aogonek -40 +KPX D Aring -40 +KPX D Atilde -40 +KPX D V -40 +KPX D W -40 +KPX D Y -70 +KPX D Yacute -70 +KPX D Ydieresis -70 +KPX D comma -30 +KPX D period -30 +KPX Dcaron A -40 +KPX Dcaron Aacute -40 +KPX Dcaron Abreve -40 +KPX Dcaron Acircumflex -40 +KPX Dcaron Adieresis -40 +KPX Dcaron Agrave -40 +KPX Dcaron Amacron -40 +KPX Dcaron Aogonek -40 +KPX Dcaron Aring -40 +KPX Dcaron Atilde -40 +KPX Dcaron V -40 +KPX Dcaron W -40 +KPX Dcaron Y -70 +KPX Dcaron Yacute -70 +KPX Dcaron Ydieresis -70 +KPX Dcaron comma -30 +KPX Dcaron period -30 +KPX Dcroat A -40 +KPX Dcroat Aacute -40 +KPX Dcroat Abreve -40 +KPX Dcroat Acircumflex -40 +KPX Dcroat Adieresis -40 +KPX Dcroat Agrave -40 +KPX Dcroat Amacron -40 +KPX Dcroat Aogonek -40 +KPX Dcroat Aring -40 +KPX Dcroat Atilde -40 +KPX Dcroat V -40 +KPX Dcroat W -40 +KPX Dcroat Y -70 +KPX Dcroat Yacute -70 +KPX Dcroat Ydieresis -70 +KPX Dcroat comma -30 +KPX Dcroat period -30 +KPX F A -80 +KPX F Aacute -80 +KPX F Abreve -80 +KPX F Acircumflex -80 +KPX F Adieresis -80 +KPX F Agrave -80 +KPX F Amacron -80 +KPX F Aogonek -80 +KPX F Aring -80 +KPX F Atilde -80 +KPX F a -20 +KPX F aacute -20 +KPX F abreve -20 +KPX F acircumflex -20 +KPX F adieresis -20 +KPX F agrave -20 +KPX F amacron -20 +KPX F aogonek -20 +KPX F aring -20 +KPX F atilde -20 +KPX F comma -100 +KPX F period -100 +KPX J A -20 +KPX J Aacute -20 +KPX J Abreve -20 +KPX J Acircumflex -20 +KPX J Adieresis -20 +KPX J Agrave -20 +KPX J Amacron -20 +KPX J Aogonek -20 +KPX J Aring -20 +KPX J Atilde -20 +KPX J comma -20 +KPX J period -20 +KPX J u -20 +KPX J uacute -20 +KPX J ucircumflex -20 +KPX J udieresis -20 +KPX J ugrave -20 +KPX J uhungarumlaut -20 +KPX J umacron -20 +KPX J uogonek -20 +KPX J uring -20 +KPX K O -30 +KPX K Oacute -30 +KPX K Ocircumflex -30 +KPX K Odieresis -30 +KPX K Ograve -30 +KPX K Ohungarumlaut -30 +KPX K Omacron -30 +KPX K Oslash -30 +KPX K Otilde -30 +KPX K e -15 +KPX K eacute -15 +KPX K ecaron -15 +KPX K ecircumflex -15 +KPX K edieresis -15 +KPX K edotaccent -15 +KPX K egrave -15 +KPX K emacron -15 +KPX K eogonek -15 +KPX K o -35 +KPX K oacute -35 +KPX K ocircumflex -35 +KPX K odieresis -35 +KPX K ograve -35 +KPX K ohungarumlaut -35 +KPX K omacron -35 +KPX K oslash -35 +KPX K otilde -35 +KPX K u -30 +KPX K uacute -30 +KPX K ucircumflex -30 +KPX K udieresis -30 +KPX K ugrave -30 +KPX K uhungarumlaut -30 +KPX K umacron -30 +KPX K uogonek -30 +KPX K uring -30 +KPX K y -40 +KPX K yacute -40 +KPX K ydieresis -40 +KPX Kcommaaccent O -30 +KPX Kcommaaccent Oacute -30 +KPX Kcommaaccent Ocircumflex -30 +KPX Kcommaaccent Odieresis -30 +KPX Kcommaaccent Ograve -30 +KPX Kcommaaccent Ohungarumlaut -30 +KPX Kcommaaccent Omacron -30 +KPX Kcommaaccent Oslash -30 +KPX Kcommaaccent Otilde -30 +KPX Kcommaaccent e -15 +KPX Kcommaaccent eacute -15 +KPX Kcommaaccent ecaron -15 +KPX Kcommaaccent ecircumflex -15 +KPX Kcommaaccent edieresis -15 +KPX Kcommaaccent edotaccent -15 +KPX Kcommaaccent egrave -15 +KPX Kcommaaccent emacron -15 +KPX Kcommaaccent eogonek -15 +KPX Kcommaaccent o -35 +KPX Kcommaaccent oacute -35 +KPX Kcommaaccent ocircumflex -35 +KPX Kcommaaccent odieresis -35 +KPX Kcommaaccent ograve -35 +KPX Kcommaaccent ohungarumlaut -35 +KPX Kcommaaccent omacron -35 +KPX Kcommaaccent oslash -35 +KPX Kcommaaccent otilde -35 +KPX Kcommaaccent u -30 +KPX Kcommaaccent uacute -30 +KPX Kcommaaccent ucircumflex -30 +KPX Kcommaaccent udieresis -30 +KPX Kcommaaccent ugrave -30 +KPX Kcommaaccent uhungarumlaut -30 +KPX Kcommaaccent umacron -30 +KPX Kcommaaccent uogonek -30 +KPX Kcommaaccent uring -30 +KPX Kcommaaccent y -40 +KPX Kcommaaccent yacute -40 +KPX Kcommaaccent ydieresis -40 +KPX L T -90 +KPX L Tcaron -90 +KPX L Tcommaaccent -90 +KPX L V -110 +KPX L W -80 +KPX L Y -120 +KPX L Yacute -120 +KPX L Ydieresis -120 +KPX L quotedblright -140 +KPX L quoteright -140 +KPX L y -30 +KPX L yacute -30 +KPX L ydieresis -30 +KPX Lacute T -90 +KPX Lacute Tcaron -90 +KPX Lacute Tcommaaccent -90 +KPX Lacute V -110 +KPX Lacute W -80 +KPX Lacute Y -120 +KPX Lacute Yacute -120 +KPX Lacute Ydieresis -120 +KPX Lacute quotedblright -140 +KPX Lacute quoteright -140 +KPX Lacute y -30 +KPX Lacute yacute -30 +KPX Lacute ydieresis -30 +KPX Lcommaaccent T -90 +KPX Lcommaaccent Tcaron -90 +KPX Lcommaaccent Tcommaaccent -90 +KPX Lcommaaccent V -110 +KPX Lcommaaccent W -80 +KPX Lcommaaccent Y -120 +KPX Lcommaaccent Yacute -120 +KPX Lcommaaccent Ydieresis -120 +KPX Lcommaaccent quotedblright -140 +KPX Lcommaaccent quoteright -140 +KPX Lcommaaccent y -30 +KPX Lcommaaccent yacute -30 +KPX Lcommaaccent ydieresis -30 +KPX Lslash T -90 +KPX Lslash Tcaron -90 +KPX Lslash Tcommaaccent -90 +KPX Lslash V -110 +KPX Lslash W -80 +KPX Lslash Y -120 +KPX Lslash Yacute -120 +KPX Lslash Ydieresis -120 +KPX Lslash quotedblright -140 +KPX Lslash quoteright -140 +KPX Lslash y -30 +KPX Lslash yacute -30 +KPX Lslash ydieresis -30 +KPX O A -50 +KPX O Aacute -50 +KPX O Abreve -50 +KPX O Acircumflex -50 +KPX O Adieresis -50 +KPX O Agrave -50 +KPX O Amacron -50 +KPX O Aogonek -50 +KPX O Aring -50 +KPX O Atilde -50 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -50 +KPX O X -50 +KPX O Y -70 +KPX O Yacute -70 +KPX O Ydieresis -70 +KPX O comma -40 +KPX O period -40 +KPX Oacute A -50 +KPX Oacute Aacute -50 +KPX Oacute Abreve -50 +KPX Oacute Acircumflex -50 +KPX Oacute Adieresis -50 +KPX Oacute Agrave -50 +KPX Oacute Amacron -50 +KPX Oacute Aogonek -50 +KPX Oacute Aring -50 +KPX Oacute Atilde -50 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -50 +KPX Oacute X -50 +KPX Oacute Y -70 +KPX Oacute Yacute -70 +KPX Oacute Ydieresis -70 +KPX Oacute comma -40 +KPX Oacute period -40 +KPX Ocircumflex A -50 +KPX Ocircumflex Aacute -50 +KPX Ocircumflex Abreve -50 +KPX Ocircumflex Acircumflex -50 +KPX Ocircumflex Adieresis -50 +KPX Ocircumflex Agrave -50 +KPX Ocircumflex Amacron -50 +KPX Ocircumflex Aogonek -50 +KPX Ocircumflex Aring -50 +KPX Ocircumflex Atilde -50 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -50 +KPX Ocircumflex X -50 +KPX Ocircumflex Y -70 +KPX Ocircumflex Yacute -70 +KPX Ocircumflex Ydieresis -70 +KPX Ocircumflex comma -40 +KPX Ocircumflex period -40 +KPX Odieresis A -50 +KPX Odieresis Aacute -50 +KPX Odieresis Abreve -50 +KPX Odieresis Acircumflex -50 +KPX Odieresis Adieresis -50 +KPX Odieresis Agrave -50 +KPX Odieresis Amacron -50 +KPX Odieresis Aogonek -50 +KPX Odieresis Aring -50 +KPX Odieresis Atilde -50 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -50 +KPX Odieresis X -50 +KPX Odieresis Y -70 +KPX Odieresis Yacute -70 +KPX Odieresis Ydieresis -70 +KPX Odieresis comma -40 +KPX Odieresis period -40 +KPX Ograve A -50 +KPX Ograve Aacute -50 +KPX Ograve Abreve -50 +KPX Ograve Acircumflex -50 +KPX Ograve Adieresis -50 +KPX Ograve Agrave -50 +KPX Ograve Amacron -50 +KPX Ograve Aogonek -50 +KPX Ograve Aring -50 +KPX Ograve Atilde -50 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -50 +KPX Ograve X -50 +KPX Ograve Y -70 +KPX Ograve Yacute -70 +KPX Ograve Ydieresis -70 +KPX Ograve comma -40 +KPX Ograve period -40 +KPX Ohungarumlaut A -50 +KPX Ohungarumlaut Aacute -50 +KPX Ohungarumlaut Abreve -50 +KPX Ohungarumlaut Acircumflex -50 +KPX Ohungarumlaut Adieresis -50 +KPX Ohungarumlaut Agrave -50 +KPX Ohungarumlaut Amacron -50 +KPX Ohungarumlaut Aogonek -50 +KPX Ohungarumlaut Aring -50 +KPX Ohungarumlaut Atilde -50 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -50 +KPX Ohungarumlaut X -50 +KPX Ohungarumlaut Y -70 +KPX Ohungarumlaut Yacute -70 +KPX Ohungarumlaut Ydieresis -70 +KPX Ohungarumlaut comma -40 +KPX Ohungarumlaut period -40 +KPX Omacron A -50 +KPX Omacron Aacute -50 +KPX Omacron Abreve -50 +KPX Omacron Acircumflex -50 +KPX Omacron Adieresis -50 +KPX Omacron Agrave -50 +KPX Omacron Amacron -50 +KPX Omacron Aogonek -50 +KPX Omacron Aring -50 +KPX Omacron Atilde -50 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -50 +KPX Omacron X -50 +KPX Omacron Y -70 +KPX Omacron Yacute -70 +KPX Omacron Ydieresis -70 +KPX Omacron comma -40 +KPX Omacron period -40 +KPX Oslash A -50 +KPX Oslash Aacute -50 +KPX Oslash Abreve -50 +KPX Oslash Acircumflex -50 +KPX Oslash Adieresis -50 +KPX Oslash Agrave -50 +KPX Oslash Amacron -50 +KPX Oslash Aogonek -50 +KPX Oslash Aring -50 +KPX Oslash Atilde -50 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -50 +KPX Oslash X -50 +KPX Oslash Y -70 +KPX Oslash Yacute -70 +KPX Oslash Ydieresis -70 +KPX Oslash comma -40 +KPX Oslash period -40 +KPX Otilde A -50 +KPX Otilde Aacute -50 +KPX Otilde Abreve -50 +KPX Otilde Acircumflex -50 +KPX Otilde Adieresis -50 +KPX Otilde Agrave -50 +KPX Otilde Amacron -50 +KPX Otilde Aogonek -50 +KPX Otilde Aring -50 +KPX Otilde Atilde -50 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -50 +KPX Otilde X -50 +KPX Otilde Y -70 +KPX Otilde Yacute -70 +KPX Otilde Ydieresis -70 +KPX Otilde comma -40 +KPX Otilde period -40 +KPX P A -100 +KPX P Aacute -100 +KPX P Abreve -100 +KPX P Acircumflex -100 +KPX P Adieresis -100 +KPX P Agrave -100 +KPX P Amacron -100 +KPX P Aogonek -100 +KPX P Aring -100 +KPX P Atilde -100 +KPX P a -30 +KPX P aacute -30 +KPX P abreve -30 +KPX P acircumflex -30 +KPX P adieresis -30 +KPX P agrave -30 +KPX P amacron -30 +KPX P aogonek -30 +KPX P aring -30 +KPX P atilde -30 +KPX P comma -120 +KPX P e -30 +KPX P eacute -30 +KPX P ecaron -30 +KPX P ecircumflex -30 +KPX P edieresis -30 +KPX P edotaccent -30 +KPX P egrave -30 +KPX P emacron -30 +KPX P eogonek -30 +KPX P o -40 +KPX P oacute -40 +KPX P ocircumflex -40 +KPX P odieresis -40 +KPX P ograve -40 +KPX P ohungarumlaut -40 +KPX P omacron -40 +KPX P oslash -40 +KPX P otilde -40 +KPX P period -120 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX Q comma 20 +KPX Q period 20 +KPX R O -20 +KPX R Oacute -20 +KPX R Ocircumflex -20 +KPX R Odieresis -20 +KPX R Ograve -20 +KPX R Ohungarumlaut -20 +KPX R Omacron -20 +KPX R Oslash -20 +KPX R Otilde -20 +KPX R T -20 +KPX R Tcaron -20 +KPX R Tcommaaccent -20 +KPX R U -20 +KPX R Uacute -20 +KPX R Ucircumflex -20 +KPX R Udieresis -20 +KPX R Ugrave -20 +KPX R Uhungarumlaut -20 +KPX R Umacron -20 +KPX R Uogonek -20 +KPX R Uring -20 +KPX R V -50 +KPX R W -40 +KPX R Y -50 +KPX R Yacute -50 +KPX R Ydieresis -50 +KPX Racute O -20 +KPX Racute Oacute -20 +KPX Racute Ocircumflex -20 +KPX Racute Odieresis -20 +KPX Racute Ograve -20 +KPX Racute Ohungarumlaut -20 +KPX Racute Omacron -20 +KPX Racute Oslash -20 +KPX Racute Otilde -20 +KPX Racute T -20 +KPX Racute Tcaron -20 +KPX Racute Tcommaaccent -20 +KPX Racute U -20 +KPX Racute Uacute -20 +KPX Racute Ucircumflex -20 +KPX Racute Udieresis -20 +KPX Racute Ugrave -20 +KPX Racute Uhungarumlaut -20 +KPX Racute Umacron -20 +KPX Racute Uogonek -20 +KPX Racute Uring -20 +KPX Racute V -50 +KPX Racute W -40 +KPX Racute Y -50 +KPX Racute Yacute -50 +KPX Racute Ydieresis -50 +KPX Rcaron O -20 +KPX Rcaron Oacute -20 +KPX Rcaron Ocircumflex -20 +KPX Rcaron Odieresis -20 +KPX Rcaron Ograve -20 +KPX Rcaron Ohungarumlaut -20 +KPX Rcaron Omacron -20 +KPX Rcaron Oslash -20 +KPX Rcaron Otilde -20 +KPX Rcaron T -20 +KPX Rcaron Tcaron -20 +KPX Rcaron Tcommaaccent -20 +KPX Rcaron U -20 +KPX Rcaron Uacute -20 +KPX Rcaron Ucircumflex -20 +KPX Rcaron Udieresis -20 +KPX Rcaron Ugrave -20 +KPX Rcaron Uhungarumlaut -20 +KPX Rcaron Umacron -20 +KPX Rcaron Uogonek -20 +KPX Rcaron Uring -20 +KPX Rcaron V -50 +KPX Rcaron W -40 +KPX Rcaron Y -50 +KPX Rcaron Yacute -50 +KPX Rcaron Ydieresis -50 +KPX Rcommaaccent O -20 +KPX Rcommaaccent Oacute -20 +KPX Rcommaaccent Ocircumflex -20 +KPX Rcommaaccent Odieresis -20 +KPX Rcommaaccent Ograve -20 +KPX Rcommaaccent Ohungarumlaut -20 +KPX Rcommaaccent Omacron -20 +KPX Rcommaaccent Oslash -20 +KPX Rcommaaccent Otilde -20 +KPX Rcommaaccent T -20 +KPX Rcommaaccent Tcaron -20 +KPX Rcommaaccent Tcommaaccent -20 +KPX Rcommaaccent U -20 +KPX Rcommaaccent Uacute -20 +KPX Rcommaaccent Ucircumflex -20 +KPX Rcommaaccent Udieresis -20 +KPX Rcommaaccent Ugrave -20 +KPX Rcommaaccent Uhungarumlaut -20 +KPX Rcommaaccent Umacron -20 +KPX Rcommaaccent Uogonek -20 +KPX Rcommaaccent Uring -20 +KPX Rcommaaccent V -50 +KPX Rcommaaccent W -40 +KPX Rcommaaccent Y -50 +KPX Rcommaaccent Yacute -50 +KPX Rcommaaccent Ydieresis -50 +KPX T A -90 +KPX T Aacute -90 +KPX T Abreve -90 +KPX T Acircumflex -90 +KPX T Adieresis -90 +KPX T Agrave -90 +KPX T Amacron -90 +KPX T Aogonek -90 +KPX T Aring -90 +KPX T Atilde -90 +KPX T O -40 +KPX T Oacute -40 +KPX T Ocircumflex -40 +KPX T Odieresis -40 +KPX T Ograve -40 +KPX T Ohungarumlaut -40 +KPX T Omacron -40 +KPX T Oslash -40 +KPX T Otilde -40 +KPX T a -80 +KPX T aacute -80 +KPX T abreve -80 +KPX T acircumflex -80 +KPX T adieresis -80 +KPX T agrave -80 +KPX T amacron -80 +KPX T aogonek -80 +KPX T aring -80 +KPX T atilde -80 +KPX T colon -40 +KPX T comma -80 +KPX T e -60 +KPX T eacute -60 +KPX T ecaron -60 +KPX T ecircumflex -60 +KPX T edieresis -60 +KPX T edotaccent -60 +KPX T egrave -60 +KPX T emacron -60 +KPX T eogonek -60 +KPX T hyphen -120 +KPX T o -80 +KPX T oacute -80 +KPX T ocircumflex -80 +KPX T odieresis -80 +KPX T ograve -80 +KPX T ohungarumlaut -80 +KPX T omacron -80 +KPX T oslash -80 +KPX T otilde -80 +KPX T period -80 +KPX T r -80 +KPX T racute -80 +KPX T rcommaaccent -80 +KPX T semicolon -40 +KPX T u -90 +KPX T uacute -90 +KPX T ucircumflex -90 +KPX T udieresis -90 +KPX T ugrave -90 +KPX T uhungarumlaut -90 +KPX T umacron -90 +KPX T uogonek -90 +KPX T uring -90 +KPX T w -60 +KPX T y -60 +KPX T yacute -60 +KPX T ydieresis -60 +KPX Tcaron A -90 +KPX Tcaron Aacute -90 +KPX Tcaron Abreve -90 +KPX Tcaron Acircumflex -90 +KPX Tcaron Adieresis -90 +KPX Tcaron Agrave -90 +KPX Tcaron Amacron -90 +KPX Tcaron Aogonek -90 +KPX Tcaron Aring -90 +KPX Tcaron Atilde -90 +KPX Tcaron O -40 +KPX Tcaron Oacute -40 +KPX Tcaron Ocircumflex -40 +KPX Tcaron Odieresis -40 +KPX Tcaron Ograve -40 +KPX Tcaron Ohungarumlaut -40 +KPX Tcaron Omacron -40 +KPX Tcaron Oslash -40 +KPX Tcaron Otilde -40 +KPX Tcaron a -80 +KPX Tcaron aacute -80 +KPX Tcaron abreve -80 +KPX Tcaron acircumflex -80 +KPX Tcaron adieresis -80 +KPX Tcaron agrave -80 +KPX Tcaron amacron -80 +KPX Tcaron aogonek -80 +KPX Tcaron aring -80 +KPX Tcaron atilde -80 +KPX Tcaron colon -40 +KPX Tcaron comma -80 +KPX Tcaron e -60 +KPX Tcaron eacute -60 +KPX Tcaron ecaron -60 +KPX Tcaron ecircumflex -60 +KPX Tcaron edieresis -60 +KPX Tcaron edotaccent -60 +KPX Tcaron egrave -60 +KPX Tcaron emacron -60 +KPX Tcaron eogonek -60 +KPX Tcaron hyphen -120 +KPX Tcaron o -80 +KPX Tcaron oacute -80 +KPX Tcaron ocircumflex -80 +KPX Tcaron odieresis -80 +KPX Tcaron ograve -80 +KPX Tcaron ohungarumlaut -80 +KPX Tcaron omacron -80 +KPX Tcaron oslash -80 +KPX Tcaron otilde -80 +KPX Tcaron period -80 +KPX Tcaron r -80 +KPX Tcaron racute -80 +KPX Tcaron rcommaaccent -80 +KPX Tcaron semicolon -40 +KPX Tcaron u -90 +KPX Tcaron uacute -90 +KPX Tcaron ucircumflex -90 +KPX Tcaron udieresis -90 +KPX Tcaron ugrave -90 +KPX Tcaron uhungarumlaut -90 +KPX Tcaron umacron -90 +KPX Tcaron uogonek -90 +KPX Tcaron uring -90 +KPX Tcaron w -60 +KPX Tcaron y -60 +KPX Tcaron yacute -60 +KPX Tcaron ydieresis -60 +KPX Tcommaaccent A -90 +KPX Tcommaaccent Aacute -90 +KPX Tcommaaccent Abreve -90 +KPX Tcommaaccent Acircumflex -90 +KPX Tcommaaccent Adieresis -90 +KPX Tcommaaccent Agrave -90 +KPX Tcommaaccent Amacron -90 +KPX Tcommaaccent Aogonek -90 +KPX Tcommaaccent Aring -90 +KPX Tcommaaccent Atilde -90 +KPX Tcommaaccent O -40 +KPX Tcommaaccent Oacute -40 +KPX Tcommaaccent Ocircumflex -40 +KPX Tcommaaccent Odieresis -40 +KPX Tcommaaccent Ograve -40 +KPX Tcommaaccent Ohungarumlaut -40 +KPX Tcommaaccent Omacron -40 +KPX Tcommaaccent Oslash -40 +KPX Tcommaaccent Otilde -40 +KPX Tcommaaccent a -80 +KPX Tcommaaccent aacute -80 +KPX Tcommaaccent abreve -80 +KPX Tcommaaccent acircumflex -80 +KPX Tcommaaccent adieresis -80 +KPX Tcommaaccent agrave -80 +KPX Tcommaaccent amacron -80 +KPX Tcommaaccent aogonek -80 +KPX Tcommaaccent aring -80 +KPX Tcommaaccent atilde -80 +KPX Tcommaaccent colon -40 +KPX Tcommaaccent comma -80 +KPX Tcommaaccent e -60 +KPX Tcommaaccent eacute -60 +KPX Tcommaaccent ecaron -60 +KPX Tcommaaccent ecircumflex -60 +KPX Tcommaaccent edieresis -60 +KPX Tcommaaccent edotaccent -60 +KPX Tcommaaccent egrave -60 +KPX Tcommaaccent emacron -60 +KPX Tcommaaccent eogonek -60 +KPX Tcommaaccent hyphen -120 +KPX Tcommaaccent o -80 +KPX Tcommaaccent oacute -80 +KPX Tcommaaccent ocircumflex -80 +KPX Tcommaaccent odieresis -80 +KPX Tcommaaccent ograve -80 +KPX Tcommaaccent ohungarumlaut -80 +KPX Tcommaaccent omacron -80 +KPX Tcommaaccent oslash -80 +KPX Tcommaaccent otilde -80 +KPX Tcommaaccent period -80 +KPX Tcommaaccent r -80 +KPX Tcommaaccent racute -80 +KPX Tcommaaccent rcommaaccent -80 +KPX Tcommaaccent semicolon -40 +KPX Tcommaaccent u -90 +KPX Tcommaaccent uacute -90 +KPX Tcommaaccent ucircumflex -90 +KPX Tcommaaccent udieresis -90 +KPX Tcommaaccent ugrave -90 +KPX Tcommaaccent uhungarumlaut -90 +KPX Tcommaaccent umacron -90 +KPX Tcommaaccent uogonek -90 +KPX Tcommaaccent uring -90 +KPX Tcommaaccent w -60 +KPX Tcommaaccent y -60 +KPX Tcommaaccent yacute -60 +KPX Tcommaaccent ydieresis -60 +KPX U A -50 +KPX U Aacute -50 +KPX U Abreve -50 +KPX U Acircumflex -50 +KPX U Adieresis -50 +KPX U Agrave -50 +KPX U Amacron -50 +KPX U Aogonek -50 +KPX U Aring -50 +KPX U Atilde -50 +KPX U comma -30 +KPX U period -30 +KPX Uacute A -50 +KPX Uacute Aacute -50 +KPX Uacute Abreve -50 +KPX Uacute Acircumflex -50 +KPX Uacute Adieresis -50 +KPX Uacute Agrave -50 +KPX Uacute Amacron -50 +KPX Uacute Aogonek -50 +KPX Uacute Aring -50 +KPX Uacute Atilde -50 +KPX Uacute comma -30 +KPX Uacute period -30 +KPX Ucircumflex A -50 +KPX Ucircumflex Aacute -50 +KPX Ucircumflex Abreve -50 +KPX Ucircumflex Acircumflex -50 +KPX Ucircumflex Adieresis -50 +KPX Ucircumflex Agrave -50 +KPX Ucircumflex Amacron -50 +KPX Ucircumflex Aogonek -50 +KPX Ucircumflex Aring -50 +KPX Ucircumflex Atilde -50 +KPX Ucircumflex comma -30 +KPX Ucircumflex period -30 +KPX Udieresis A -50 +KPX Udieresis Aacute -50 +KPX Udieresis Abreve -50 +KPX Udieresis Acircumflex -50 +KPX Udieresis Adieresis -50 +KPX Udieresis Agrave -50 +KPX Udieresis Amacron -50 +KPX Udieresis Aogonek -50 +KPX Udieresis Aring -50 +KPX Udieresis Atilde -50 +KPX Udieresis comma -30 +KPX Udieresis period -30 +KPX Ugrave A -50 +KPX Ugrave Aacute -50 +KPX Ugrave Abreve -50 +KPX Ugrave Acircumflex -50 +KPX Ugrave Adieresis -50 +KPX Ugrave Agrave -50 +KPX Ugrave Amacron -50 +KPX Ugrave Aogonek -50 +KPX Ugrave Aring -50 +KPX Ugrave Atilde -50 +KPX Ugrave comma -30 +KPX Ugrave period -30 +KPX Uhungarumlaut A -50 +KPX Uhungarumlaut Aacute -50 +KPX Uhungarumlaut Abreve -50 +KPX Uhungarumlaut Acircumflex -50 +KPX Uhungarumlaut Adieresis -50 +KPX Uhungarumlaut Agrave -50 +KPX Uhungarumlaut Amacron -50 +KPX Uhungarumlaut Aogonek -50 +KPX Uhungarumlaut Aring -50 +KPX Uhungarumlaut Atilde -50 +KPX Uhungarumlaut comma -30 +KPX Uhungarumlaut period -30 +KPX Umacron A -50 +KPX Umacron Aacute -50 +KPX Umacron Abreve -50 +KPX Umacron Acircumflex -50 +KPX Umacron Adieresis -50 +KPX Umacron Agrave -50 +KPX Umacron Amacron -50 +KPX Umacron Aogonek -50 +KPX Umacron Aring -50 +KPX Umacron Atilde -50 +KPX Umacron comma -30 +KPX Umacron period -30 +KPX Uogonek A -50 +KPX Uogonek Aacute -50 +KPX Uogonek Abreve -50 +KPX Uogonek Acircumflex -50 +KPX Uogonek Adieresis -50 +KPX Uogonek Agrave -50 +KPX Uogonek Amacron -50 +KPX Uogonek Aogonek -50 +KPX Uogonek Aring -50 +KPX Uogonek Atilde -50 +KPX Uogonek comma -30 +KPX Uogonek period -30 +KPX Uring A -50 +KPX Uring Aacute -50 +KPX Uring Abreve -50 +KPX Uring Acircumflex -50 +KPX Uring Adieresis -50 +KPX Uring Agrave -50 +KPX Uring Amacron -50 +KPX Uring Aogonek -50 +KPX Uring Aring -50 +KPX Uring Atilde -50 +KPX Uring comma -30 +KPX Uring period -30 +KPX V A -80 +KPX V Aacute -80 +KPX V Abreve -80 +KPX V Acircumflex -80 +KPX V Adieresis -80 +KPX V Agrave -80 +KPX V Amacron -80 +KPX V Aogonek -80 +KPX V Aring -80 +KPX V Atilde -80 +KPX V G -50 +KPX V Gbreve -50 +KPX V Gcommaaccent -50 +KPX V O -50 +KPX V Oacute -50 +KPX V Ocircumflex -50 +KPX V Odieresis -50 +KPX V Ograve -50 +KPX V Ohungarumlaut -50 +KPX V Omacron -50 +KPX V Oslash -50 +KPX V Otilde -50 +KPX V a -60 +KPX V aacute -60 +KPX V abreve -60 +KPX V acircumflex -60 +KPX V adieresis -60 +KPX V agrave -60 +KPX V amacron -60 +KPX V aogonek -60 +KPX V aring -60 +KPX V atilde -60 +KPX V colon -40 +KPX V comma -120 +KPX V e -50 +KPX V eacute -50 +KPX V ecaron -50 +KPX V ecircumflex -50 +KPX V edieresis -50 +KPX V edotaccent -50 +KPX V egrave -50 +KPX V emacron -50 +KPX V eogonek -50 +KPX V hyphen -80 +KPX V o -90 +KPX V oacute -90 +KPX V ocircumflex -90 +KPX V odieresis -90 +KPX V ograve -90 +KPX V ohungarumlaut -90 +KPX V omacron -90 +KPX V oslash -90 +KPX V otilde -90 +KPX V period -120 +KPX V semicolon -40 +KPX V u -60 +KPX V uacute -60 +KPX V ucircumflex -60 +KPX V udieresis -60 +KPX V ugrave -60 +KPX V uhungarumlaut -60 +KPX V umacron -60 +KPX V uogonek -60 +KPX V uring -60 +KPX W A -60 +KPX W Aacute -60 +KPX W Abreve -60 +KPX W Acircumflex -60 +KPX W Adieresis -60 +KPX W Agrave -60 +KPX W Amacron -60 +KPX W Aogonek -60 +KPX W Aring -60 +KPX W Atilde -60 +KPX W O -20 +KPX W Oacute -20 +KPX W Ocircumflex -20 +KPX W Odieresis -20 +KPX W Ograve -20 +KPX W Ohungarumlaut -20 +KPX W Omacron -20 +KPX W Oslash -20 +KPX W Otilde -20 +KPX W a -40 +KPX W aacute -40 +KPX W abreve -40 +KPX W acircumflex -40 +KPX W adieresis -40 +KPX W agrave -40 +KPX W amacron -40 +KPX W aogonek -40 +KPX W aring -40 +KPX W atilde -40 +KPX W colon -10 +KPX W comma -80 +KPX W e -35 +KPX W eacute -35 +KPX W ecaron -35 +KPX W ecircumflex -35 +KPX W edieresis -35 +KPX W edotaccent -35 +KPX W egrave -35 +KPX W emacron -35 +KPX W eogonek -35 +KPX W hyphen -40 +KPX W o -60 +KPX W oacute -60 +KPX W ocircumflex -60 +KPX W odieresis -60 +KPX W ograve -60 +KPX W ohungarumlaut -60 +KPX W omacron -60 +KPX W oslash -60 +KPX W otilde -60 +KPX W period -80 +KPX W semicolon -10 +KPX W u -45 +KPX W uacute -45 +KPX W ucircumflex -45 +KPX W udieresis -45 +KPX W ugrave -45 +KPX W uhungarumlaut -45 +KPX W umacron -45 +KPX W uogonek -45 +KPX W uring -45 +KPX W y -20 +KPX W yacute -20 +KPX W ydieresis -20 +KPX Y A -110 +KPX Y Aacute -110 +KPX Y Abreve -110 +KPX Y Acircumflex -110 +KPX Y Adieresis -110 +KPX Y Agrave -110 +KPX Y Amacron -110 +KPX Y Aogonek -110 +KPX Y Aring -110 +KPX Y Atilde -110 +KPX Y O -70 +KPX Y Oacute -70 +KPX Y Ocircumflex -70 +KPX Y Odieresis -70 +KPX Y Ograve -70 +KPX Y Ohungarumlaut -70 +KPX Y Omacron -70 +KPX Y Oslash -70 +KPX Y Otilde -70 +KPX Y a -90 +KPX Y aacute -90 +KPX Y abreve -90 +KPX Y acircumflex -90 +KPX Y adieresis -90 +KPX Y agrave -90 +KPX Y amacron -90 +KPX Y aogonek -90 +KPX Y aring -90 +KPX Y atilde -90 +KPX Y colon -50 +KPX Y comma -100 +KPX Y e -80 +KPX Y eacute -80 +KPX Y ecaron -80 +KPX Y ecircumflex -80 +KPX Y edieresis -80 +KPX Y edotaccent -80 +KPX Y egrave -80 +KPX Y emacron -80 +KPX Y eogonek -80 +KPX Y o -100 +KPX Y oacute -100 +KPX Y ocircumflex -100 +KPX Y odieresis -100 +KPX Y ograve -100 +KPX Y ohungarumlaut -100 +KPX Y omacron -100 +KPX Y oslash -100 +KPX Y otilde -100 +KPX Y period -100 +KPX Y semicolon -50 +KPX Y u -100 +KPX Y uacute -100 +KPX Y ucircumflex -100 +KPX Y udieresis -100 +KPX Y ugrave -100 +KPX Y uhungarumlaut -100 +KPX Y umacron -100 +KPX Y uogonek -100 +KPX Y uring -100 +KPX Yacute A -110 +KPX Yacute Aacute -110 +KPX Yacute Abreve -110 +KPX Yacute Acircumflex -110 +KPX Yacute Adieresis -110 +KPX Yacute Agrave -110 +KPX Yacute Amacron -110 +KPX Yacute Aogonek -110 +KPX Yacute Aring -110 +KPX Yacute Atilde -110 +KPX Yacute O -70 +KPX Yacute Oacute -70 +KPX Yacute Ocircumflex -70 +KPX Yacute Odieresis -70 +KPX Yacute Ograve -70 +KPX Yacute Ohungarumlaut -70 +KPX Yacute Omacron -70 +KPX Yacute Oslash -70 +KPX Yacute Otilde -70 +KPX Yacute a -90 +KPX Yacute aacute -90 +KPX Yacute abreve -90 +KPX Yacute acircumflex -90 +KPX Yacute adieresis -90 +KPX Yacute agrave -90 +KPX Yacute amacron -90 +KPX Yacute aogonek -90 +KPX Yacute aring -90 +KPX Yacute atilde -90 +KPX Yacute colon -50 +KPX Yacute comma -100 +KPX Yacute e -80 +KPX Yacute eacute -80 +KPX Yacute ecaron -80 +KPX Yacute ecircumflex -80 +KPX Yacute edieresis -80 +KPX Yacute edotaccent -80 +KPX Yacute egrave -80 +KPX Yacute emacron -80 +KPX Yacute eogonek -80 +KPX Yacute o -100 +KPX Yacute oacute -100 +KPX Yacute ocircumflex -100 +KPX Yacute odieresis -100 +KPX Yacute ograve -100 +KPX Yacute ohungarumlaut -100 +KPX Yacute omacron -100 +KPX Yacute oslash -100 +KPX Yacute otilde -100 +KPX Yacute period -100 +KPX Yacute semicolon -50 +KPX Yacute u -100 +KPX Yacute uacute -100 +KPX Yacute ucircumflex -100 +KPX Yacute udieresis -100 +KPX Yacute ugrave -100 +KPX Yacute uhungarumlaut -100 +KPX Yacute umacron -100 +KPX Yacute uogonek -100 +KPX Yacute uring -100 +KPX Ydieresis A -110 +KPX Ydieresis Aacute -110 +KPX Ydieresis Abreve -110 +KPX Ydieresis Acircumflex -110 +KPX Ydieresis Adieresis -110 +KPX Ydieresis Agrave -110 +KPX Ydieresis Amacron -110 +KPX Ydieresis Aogonek -110 +KPX Ydieresis Aring -110 +KPX Ydieresis Atilde -110 +KPX Ydieresis O -70 +KPX Ydieresis Oacute -70 +KPX Ydieresis Ocircumflex -70 +KPX Ydieresis Odieresis -70 +KPX Ydieresis Ograve -70 +KPX Ydieresis Ohungarumlaut -70 +KPX Ydieresis Omacron -70 +KPX Ydieresis Oslash -70 +KPX Ydieresis Otilde -70 +KPX Ydieresis a -90 +KPX Ydieresis aacute -90 +KPX Ydieresis abreve -90 +KPX Ydieresis acircumflex -90 +KPX Ydieresis adieresis -90 +KPX Ydieresis agrave -90 +KPX Ydieresis amacron -90 +KPX Ydieresis aogonek -90 +KPX Ydieresis aring -90 +KPX Ydieresis atilde -90 +KPX Ydieresis colon -50 +KPX Ydieresis comma -100 +KPX Ydieresis e -80 +KPX Ydieresis eacute -80 +KPX Ydieresis ecaron -80 +KPX Ydieresis ecircumflex -80 +KPX Ydieresis edieresis -80 +KPX Ydieresis edotaccent -80 +KPX Ydieresis egrave -80 +KPX Ydieresis emacron -80 +KPX Ydieresis eogonek -80 +KPX Ydieresis o -100 +KPX Ydieresis oacute -100 +KPX Ydieresis ocircumflex -100 +KPX Ydieresis odieresis -100 +KPX Ydieresis ograve -100 +KPX Ydieresis ohungarumlaut -100 +KPX Ydieresis omacron -100 +KPX Ydieresis oslash -100 +KPX Ydieresis otilde -100 +KPX Ydieresis period -100 +KPX Ydieresis semicolon -50 +KPX Ydieresis u -100 +KPX Ydieresis uacute -100 +KPX Ydieresis ucircumflex -100 +KPX Ydieresis udieresis -100 +KPX Ydieresis ugrave -100 +KPX Ydieresis uhungarumlaut -100 +KPX Ydieresis umacron -100 +KPX Ydieresis uogonek -100 +KPX Ydieresis uring -100 +KPX a g -10 +KPX a gbreve -10 +KPX a gcommaaccent -10 +KPX a v -15 +KPX a w -15 +KPX a y -20 +KPX a yacute -20 +KPX a ydieresis -20 +KPX aacute g -10 +KPX aacute gbreve -10 +KPX aacute gcommaaccent -10 +KPX aacute v -15 +KPX aacute w -15 +KPX aacute y -20 +KPX aacute yacute -20 +KPX aacute ydieresis -20 +KPX abreve g -10 +KPX abreve gbreve -10 +KPX abreve gcommaaccent -10 +KPX abreve v -15 +KPX abreve w -15 +KPX abreve y -20 +KPX abreve yacute -20 +KPX abreve ydieresis -20 +KPX acircumflex g -10 +KPX acircumflex gbreve -10 +KPX acircumflex gcommaaccent -10 +KPX acircumflex v -15 +KPX acircumflex w -15 +KPX acircumflex y -20 +KPX acircumflex yacute -20 +KPX acircumflex ydieresis -20 +KPX adieresis g -10 +KPX adieresis gbreve -10 +KPX adieresis gcommaaccent -10 +KPX adieresis v -15 +KPX adieresis w -15 +KPX adieresis y -20 +KPX adieresis yacute -20 +KPX adieresis ydieresis -20 +KPX agrave g -10 +KPX agrave gbreve -10 +KPX agrave gcommaaccent -10 +KPX agrave v -15 +KPX agrave w -15 +KPX agrave y -20 +KPX agrave yacute -20 +KPX agrave ydieresis -20 +KPX amacron g -10 +KPX amacron gbreve -10 +KPX amacron gcommaaccent -10 +KPX amacron v -15 +KPX amacron w -15 +KPX amacron y -20 +KPX amacron yacute -20 +KPX amacron ydieresis -20 +KPX aogonek g -10 +KPX aogonek gbreve -10 +KPX aogonek gcommaaccent -10 +KPX aogonek v -15 +KPX aogonek w -15 +KPX aogonek y -20 +KPX aogonek yacute -20 +KPX aogonek ydieresis -20 +KPX aring g -10 +KPX aring gbreve -10 +KPX aring gcommaaccent -10 +KPX aring v -15 +KPX aring w -15 +KPX aring y -20 +KPX aring yacute -20 +KPX aring ydieresis -20 +KPX atilde g -10 +KPX atilde gbreve -10 +KPX atilde gcommaaccent -10 +KPX atilde v -15 +KPX atilde w -15 +KPX atilde y -20 +KPX atilde yacute -20 +KPX atilde ydieresis -20 +KPX b l -10 +KPX b lacute -10 +KPX b lcommaaccent -10 +KPX b lslash -10 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX b v -20 +KPX b y -20 +KPX b yacute -20 +KPX b ydieresis -20 +KPX c h -10 +KPX c k -20 +KPX c kcommaaccent -20 +KPX c l -20 +KPX c lacute -20 +KPX c lcommaaccent -20 +KPX c lslash -20 +KPX c y -10 +KPX c yacute -10 +KPX c ydieresis -10 +KPX cacute h -10 +KPX cacute k -20 +KPX cacute kcommaaccent -20 +KPX cacute l -20 +KPX cacute lacute -20 +KPX cacute lcommaaccent -20 +KPX cacute lslash -20 +KPX cacute y -10 +KPX cacute yacute -10 +KPX cacute ydieresis -10 +KPX ccaron h -10 +KPX ccaron k -20 +KPX ccaron kcommaaccent -20 +KPX ccaron l -20 +KPX ccaron lacute -20 +KPX ccaron lcommaaccent -20 +KPX ccaron lslash -20 +KPX ccaron y -10 +KPX ccaron yacute -10 +KPX ccaron ydieresis -10 +KPX ccedilla h -10 +KPX ccedilla k -20 +KPX ccedilla kcommaaccent -20 +KPX ccedilla l -20 +KPX ccedilla lacute -20 +KPX ccedilla lcommaaccent -20 +KPX ccedilla lslash -20 +KPX ccedilla y -10 +KPX ccedilla yacute -10 +KPX ccedilla ydieresis -10 +KPX colon space -40 +KPX comma quotedblright -120 +KPX comma quoteright -120 +KPX comma space -40 +KPX d d -10 +KPX d dcroat -10 +KPX d v -15 +KPX d w -15 +KPX d y -15 +KPX d yacute -15 +KPX d ydieresis -15 +KPX dcroat d -10 +KPX dcroat dcroat -10 +KPX dcroat v -15 +KPX dcroat w -15 +KPX dcroat y -15 +KPX dcroat yacute -15 +KPX dcroat ydieresis -15 +KPX e comma 10 +KPX e period 20 +KPX e v -15 +KPX e w -15 +KPX e x -15 +KPX e y -15 +KPX e yacute -15 +KPX e ydieresis -15 +KPX eacute comma 10 +KPX eacute period 20 +KPX eacute v -15 +KPX eacute w -15 +KPX eacute x -15 +KPX eacute y -15 +KPX eacute yacute -15 +KPX eacute ydieresis -15 +KPX ecaron comma 10 +KPX ecaron period 20 +KPX ecaron v -15 +KPX ecaron w -15 +KPX ecaron x -15 +KPX ecaron y -15 +KPX ecaron yacute -15 +KPX ecaron ydieresis -15 +KPX ecircumflex comma 10 +KPX ecircumflex period 20 +KPX ecircumflex v -15 +KPX ecircumflex w -15 +KPX ecircumflex x -15 +KPX ecircumflex y -15 +KPX ecircumflex yacute -15 +KPX ecircumflex ydieresis -15 +KPX edieresis comma 10 +KPX edieresis period 20 +KPX edieresis v -15 +KPX edieresis w -15 +KPX edieresis x -15 +KPX edieresis y -15 +KPX edieresis yacute -15 +KPX edieresis ydieresis -15 +KPX edotaccent comma 10 +KPX edotaccent period 20 +KPX edotaccent v -15 +KPX edotaccent w -15 +KPX edotaccent x -15 +KPX edotaccent y -15 +KPX edotaccent yacute -15 +KPX edotaccent ydieresis -15 +KPX egrave comma 10 +KPX egrave period 20 +KPX egrave v -15 +KPX egrave w -15 +KPX egrave x -15 +KPX egrave y -15 +KPX egrave yacute -15 +KPX egrave ydieresis -15 +KPX emacron comma 10 +KPX emacron period 20 +KPX emacron v -15 +KPX emacron w -15 +KPX emacron x -15 +KPX emacron y -15 +KPX emacron yacute -15 +KPX emacron ydieresis -15 +KPX eogonek comma 10 +KPX eogonek period 20 +KPX eogonek v -15 +KPX eogonek w -15 +KPX eogonek x -15 +KPX eogonek y -15 +KPX eogonek yacute -15 +KPX eogonek ydieresis -15 +KPX f comma -10 +KPX f e -10 +KPX f eacute -10 +KPX f ecaron -10 +KPX f ecircumflex -10 +KPX f edieresis -10 +KPX f edotaccent -10 +KPX f egrave -10 +KPX f emacron -10 +KPX f eogonek -10 +KPX f o -20 +KPX f oacute -20 +KPX f ocircumflex -20 +KPX f odieresis -20 +KPX f ograve -20 +KPX f ohungarumlaut -20 +KPX f omacron -20 +KPX f oslash -20 +KPX f otilde -20 +KPX f period -10 +KPX f quotedblright 30 +KPX f quoteright 30 +KPX g e 10 +KPX g eacute 10 +KPX g ecaron 10 +KPX g ecircumflex 10 +KPX g edieresis 10 +KPX g edotaccent 10 +KPX g egrave 10 +KPX g emacron 10 +KPX g eogonek 10 +KPX g g -10 +KPX g gbreve -10 +KPX g gcommaaccent -10 +KPX gbreve e 10 +KPX gbreve eacute 10 +KPX gbreve ecaron 10 +KPX gbreve ecircumflex 10 +KPX gbreve edieresis 10 +KPX gbreve edotaccent 10 +KPX gbreve egrave 10 +KPX gbreve emacron 10 +KPX gbreve eogonek 10 +KPX gbreve g -10 +KPX gbreve gbreve -10 +KPX gbreve gcommaaccent -10 +KPX gcommaaccent e 10 +KPX gcommaaccent eacute 10 +KPX gcommaaccent ecaron 10 +KPX gcommaaccent ecircumflex 10 +KPX gcommaaccent edieresis 10 +KPX gcommaaccent edotaccent 10 +KPX gcommaaccent egrave 10 +KPX gcommaaccent emacron 10 +KPX gcommaaccent eogonek 10 +KPX gcommaaccent g -10 +KPX gcommaaccent gbreve -10 +KPX gcommaaccent gcommaaccent -10 +KPX h y -20 +KPX h yacute -20 +KPX h ydieresis -20 +KPX k o -15 +KPX k oacute -15 +KPX k ocircumflex -15 +KPX k odieresis -15 +KPX k ograve -15 +KPX k ohungarumlaut -15 +KPX k omacron -15 +KPX k oslash -15 +KPX k otilde -15 +KPX kcommaaccent o -15 +KPX kcommaaccent oacute -15 +KPX kcommaaccent ocircumflex -15 +KPX kcommaaccent odieresis -15 +KPX kcommaaccent ograve -15 +KPX kcommaaccent ohungarumlaut -15 +KPX kcommaaccent omacron -15 +KPX kcommaaccent oslash -15 +KPX kcommaaccent otilde -15 +KPX l w -15 +KPX l y -15 +KPX l yacute -15 +KPX l ydieresis -15 +KPX lacute w -15 +KPX lacute y -15 +KPX lacute yacute -15 +KPX lacute ydieresis -15 +KPX lcommaaccent w -15 +KPX lcommaaccent y -15 +KPX lcommaaccent yacute -15 +KPX lcommaaccent ydieresis -15 +KPX lslash w -15 +KPX lslash y -15 +KPX lslash yacute -15 +KPX lslash ydieresis -15 +KPX m u -20 +KPX m uacute -20 +KPX m ucircumflex -20 +KPX m udieresis -20 +KPX m ugrave -20 +KPX m uhungarumlaut -20 +KPX m umacron -20 +KPX m uogonek -20 +KPX m uring -20 +KPX m y -30 +KPX m yacute -30 +KPX m ydieresis -30 +KPX n u -10 +KPX n uacute -10 +KPX n ucircumflex -10 +KPX n udieresis -10 +KPX n ugrave -10 +KPX n uhungarumlaut -10 +KPX n umacron -10 +KPX n uogonek -10 +KPX n uring -10 +KPX n v -40 +KPX n y -20 +KPX n yacute -20 +KPX n ydieresis -20 +KPX nacute u -10 +KPX nacute uacute -10 +KPX nacute ucircumflex -10 +KPX nacute udieresis -10 +KPX nacute ugrave -10 +KPX nacute uhungarumlaut -10 +KPX nacute umacron -10 +KPX nacute uogonek -10 +KPX nacute uring -10 +KPX nacute v -40 +KPX nacute y -20 +KPX nacute yacute -20 +KPX nacute ydieresis -20 +KPX ncaron u -10 +KPX ncaron uacute -10 +KPX ncaron ucircumflex -10 +KPX ncaron udieresis -10 +KPX ncaron ugrave -10 +KPX ncaron uhungarumlaut -10 +KPX ncaron umacron -10 +KPX ncaron uogonek -10 +KPX ncaron uring -10 +KPX ncaron v -40 +KPX ncaron y -20 +KPX ncaron yacute -20 +KPX ncaron ydieresis -20 +KPX ncommaaccent u -10 +KPX ncommaaccent uacute -10 +KPX ncommaaccent ucircumflex -10 +KPX ncommaaccent udieresis -10 +KPX ncommaaccent ugrave -10 +KPX ncommaaccent uhungarumlaut -10 +KPX ncommaaccent umacron -10 +KPX ncommaaccent uogonek -10 +KPX ncommaaccent uring -10 +KPX ncommaaccent v -40 +KPX ncommaaccent y -20 +KPX ncommaaccent yacute -20 +KPX ncommaaccent ydieresis -20 +KPX ntilde u -10 +KPX ntilde uacute -10 +KPX ntilde ucircumflex -10 +KPX ntilde udieresis -10 +KPX ntilde ugrave -10 +KPX ntilde uhungarumlaut -10 +KPX ntilde umacron -10 +KPX ntilde uogonek -10 +KPX ntilde uring -10 +KPX ntilde v -40 +KPX ntilde y -20 +KPX ntilde yacute -20 +KPX ntilde ydieresis -20 +KPX o v -20 +KPX o w -15 +KPX o x -30 +KPX o y -20 +KPX o yacute -20 +KPX o ydieresis -20 +KPX oacute v -20 +KPX oacute w -15 +KPX oacute x -30 +KPX oacute y -20 +KPX oacute yacute -20 +KPX oacute ydieresis -20 +KPX ocircumflex v -20 +KPX ocircumflex w -15 +KPX ocircumflex x -30 +KPX ocircumflex y -20 +KPX ocircumflex yacute -20 +KPX ocircumflex ydieresis -20 +KPX odieresis v -20 +KPX odieresis w -15 +KPX odieresis x -30 +KPX odieresis y -20 +KPX odieresis yacute -20 +KPX odieresis ydieresis -20 +KPX ograve v -20 +KPX ograve w -15 +KPX ograve x -30 +KPX ograve y -20 +KPX ograve yacute -20 +KPX ograve ydieresis -20 +KPX ohungarumlaut v -20 +KPX ohungarumlaut w -15 +KPX ohungarumlaut x -30 +KPX ohungarumlaut y -20 +KPX ohungarumlaut yacute -20 +KPX ohungarumlaut ydieresis -20 +KPX omacron v -20 +KPX omacron w -15 +KPX omacron x -30 +KPX omacron y -20 +KPX omacron yacute -20 +KPX omacron ydieresis -20 +KPX oslash v -20 +KPX oslash w -15 +KPX oslash x -30 +KPX oslash y -20 +KPX oslash yacute -20 +KPX oslash ydieresis -20 +KPX otilde v -20 +KPX otilde w -15 +KPX otilde x -30 +KPX otilde y -20 +KPX otilde yacute -20 +KPX otilde ydieresis -20 +KPX p y -15 +KPX p yacute -15 +KPX p ydieresis -15 +KPX period quotedblright -120 +KPX period quoteright -120 +KPX period space -40 +KPX quotedblright space -80 +KPX quoteleft quoteleft -46 +KPX quoteright d -80 +KPX quoteright dcroat -80 +KPX quoteright l -20 +KPX quoteright lacute -20 +KPX quoteright lcommaaccent -20 +KPX quoteright lslash -20 +KPX quoteright quoteright -46 +KPX quoteright r -40 +KPX quoteright racute -40 +KPX quoteright rcaron -40 +KPX quoteright rcommaaccent -40 +KPX quoteright s -60 +KPX quoteright sacute -60 +KPX quoteright scaron -60 +KPX quoteright scedilla -60 +KPX quoteright scommaaccent -60 +KPX quoteright space -80 +KPX quoteright v -20 +KPX r c -20 +KPX r cacute -20 +KPX r ccaron -20 +KPX r ccedilla -20 +KPX r comma -60 +KPX r d -20 +KPX r dcroat -20 +KPX r g -15 +KPX r gbreve -15 +KPX r gcommaaccent -15 +KPX r hyphen -20 +KPX r o -20 +KPX r oacute -20 +KPX r ocircumflex -20 +KPX r odieresis -20 +KPX r ograve -20 +KPX r ohungarumlaut -20 +KPX r omacron -20 +KPX r oslash -20 +KPX r otilde -20 +KPX r period -60 +KPX r q -20 +KPX r s -15 +KPX r sacute -15 +KPX r scaron -15 +KPX r scedilla -15 +KPX r scommaaccent -15 +KPX r t 20 +KPX r tcommaaccent 20 +KPX r v 10 +KPX r y 10 +KPX r yacute 10 +KPX r ydieresis 10 +KPX racute c -20 +KPX racute cacute -20 +KPX racute ccaron -20 +KPX racute ccedilla -20 +KPX racute comma -60 +KPX racute d -20 +KPX racute dcroat -20 +KPX racute g -15 +KPX racute gbreve -15 +KPX racute gcommaaccent -15 +KPX racute hyphen -20 +KPX racute o -20 +KPX racute oacute -20 +KPX racute ocircumflex -20 +KPX racute odieresis -20 +KPX racute ograve -20 +KPX racute ohungarumlaut -20 +KPX racute omacron -20 +KPX racute oslash -20 +KPX racute otilde -20 +KPX racute period -60 +KPX racute q -20 +KPX racute s -15 +KPX racute sacute -15 +KPX racute scaron -15 +KPX racute scedilla -15 +KPX racute scommaaccent -15 +KPX racute t 20 +KPX racute tcommaaccent 20 +KPX racute v 10 +KPX racute y 10 +KPX racute yacute 10 +KPX racute ydieresis 10 +KPX rcaron c -20 +KPX rcaron cacute -20 +KPX rcaron ccaron -20 +KPX rcaron ccedilla -20 +KPX rcaron comma -60 +KPX rcaron d -20 +KPX rcaron dcroat -20 +KPX rcaron g -15 +KPX rcaron gbreve -15 +KPX rcaron gcommaaccent -15 +KPX rcaron hyphen -20 +KPX rcaron o -20 +KPX rcaron oacute -20 +KPX rcaron ocircumflex -20 +KPX rcaron odieresis -20 +KPX rcaron ograve -20 +KPX rcaron ohungarumlaut -20 +KPX rcaron omacron -20 +KPX rcaron oslash -20 +KPX rcaron otilde -20 +KPX rcaron period -60 +KPX rcaron q -20 +KPX rcaron s -15 +KPX rcaron sacute -15 +KPX rcaron scaron -15 +KPX rcaron scedilla -15 +KPX rcaron scommaaccent -15 +KPX rcaron t 20 +KPX rcaron tcommaaccent 20 +KPX rcaron v 10 +KPX rcaron y 10 +KPX rcaron yacute 10 +KPX rcaron ydieresis 10 +KPX rcommaaccent c -20 +KPX rcommaaccent cacute -20 +KPX rcommaaccent ccaron -20 +KPX rcommaaccent ccedilla -20 +KPX rcommaaccent comma -60 +KPX rcommaaccent d -20 +KPX rcommaaccent dcroat -20 +KPX rcommaaccent g -15 +KPX rcommaaccent gbreve -15 +KPX rcommaaccent gcommaaccent -15 +KPX rcommaaccent hyphen -20 +KPX rcommaaccent o -20 +KPX rcommaaccent oacute -20 +KPX rcommaaccent ocircumflex -20 +KPX rcommaaccent odieresis -20 +KPX rcommaaccent ograve -20 +KPX rcommaaccent ohungarumlaut -20 +KPX rcommaaccent omacron -20 +KPX rcommaaccent oslash -20 +KPX rcommaaccent otilde -20 +KPX rcommaaccent period -60 +KPX rcommaaccent q -20 +KPX rcommaaccent s -15 +KPX rcommaaccent sacute -15 +KPX rcommaaccent scaron -15 +KPX rcommaaccent scedilla -15 +KPX rcommaaccent scommaaccent -15 +KPX rcommaaccent t 20 +KPX rcommaaccent tcommaaccent 20 +KPX rcommaaccent v 10 +KPX rcommaaccent y 10 +KPX rcommaaccent yacute 10 +KPX rcommaaccent ydieresis 10 +KPX s w -15 +KPX sacute w -15 +KPX scaron w -15 +KPX scedilla w -15 +KPX scommaaccent w -15 +KPX semicolon space -40 +KPX space T -100 +KPX space Tcaron -100 +KPX space Tcommaaccent -100 +KPX space V -80 +KPX space W -80 +KPX space Y -120 +KPX space Yacute -120 +KPX space Ydieresis -120 +KPX space quotedblleft -80 +KPX space quoteleft -60 +KPX v a -20 +KPX v aacute -20 +KPX v abreve -20 +KPX v acircumflex -20 +KPX v adieresis -20 +KPX v agrave -20 +KPX v amacron -20 +KPX v aogonek -20 +KPX v aring -20 +KPX v atilde -20 +KPX v comma -80 +KPX v o -30 +KPX v oacute -30 +KPX v ocircumflex -30 +KPX v odieresis -30 +KPX v ograve -30 +KPX v ohungarumlaut -30 +KPX v omacron -30 +KPX v oslash -30 +KPX v otilde -30 +KPX v period -80 +KPX w comma -40 +KPX w o -20 +KPX w oacute -20 +KPX w ocircumflex -20 +KPX w odieresis -20 +KPX w ograve -20 +KPX w ohungarumlaut -20 +KPX w omacron -20 +KPX w oslash -20 +KPX w otilde -20 +KPX w period -40 +KPX x e -10 +KPX x eacute -10 +KPX x ecaron -10 +KPX x ecircumflex -10 +KPX x edieresis -10 +KPX x edotaccent -10 +KPX x egrave -10 +KPX x emacron -10 +KPX x eogonek -10 +KPX y a -30 +KPX y aacute -30 +KPX y abreve -30 +KPX y acircumflex -30 +KPX y adieresis -30 +KPX y agrave -30 +KPX y amacron -30 +KPX y aogonek -30 +KPX y aring -30 +KPX y atilde -30 +KPX y comma -80 +KPX y e -10 +KPX y eacute -10 +KPX y ecaron -10 +KPX y ecircumflex -10 +KPX y edieresis -10 +KPX y edotaccent -10 +KPX y egrave -10 +KPX y emacron -10 +KPX y eogonek -10 +KPX y o -25 +KPX y oacute -25 +KPX y ocircumflex -25 +KPX y odieresis -25 +KPX y ograve -25 +KPX y ohungarumlaut -25 +KPX y omacron -25 +KPX y oslash -25 +KPX y otilde -25 +KPX y period -80 +KPX yacute a -30 +KPX yacute aacute -30 +KPX yacute abreve -30 +KPX yacute acircumflex -30 +KPX yacute adieresis -30 +KPX yacute agrave -30 +KPX yacute amacron -30 +KPX yacute aogonek -30 +KPX yacute aring -30 +KPX yacute atilde -30 +KPX yacute comma -80 +KPX yacute e -10 +KPX yacute eacute -10 +KPX yacute ecaron -10 +KPX yacute ecircumflex -10 +KPX yacute edieresis -10 +KPX yacute edotaccent -10 +KPX yacute egrave -10 +KPX yacute emacron -10 +KPX yacute eogonek -10 +KPX yacute o -25 +KPX yacute oacute -25 +KPX yacute ocircumflex -25 +KPX yacute odieresis -25 +KPX yacute ograve -25 +KPX yacute ohungarumlaut -25 +KPX yacute omacron -25 +KPX yacute oslash -25 +KPX yacute otilde -25 +KPX yacute period -80 +KPX ydieresis a -30 +KPX ydieresis aacute -30 +KPX ydieresis abreve -30 +KPX ydieresis acircumflex -30 +KPX ydieresis adieresis -30 +KPX ydieresis agrave -30 +KPX ydieresis amacron -30 +KPX ydieresis aogonek -30 +KPX ydieresis aring -30 +KPX ydieresis atilde -30 +KPX ydieresis comma -80 +KPX ydieresis e -10 +KPX ydieresis eacute -10 +KPX ydieresis ecaron -10 +KPX ydieresis ecircumflex -10 +KPX ydieresis edieresis -10 +KPX ydieresis edotaccent -10 +KPX ydieresis egrave -10 +KPX ydieresis emacron -10 +KPX ydieresis eogonek -10 +KPX ydieresis o -25 +KPX ydieresis oacute -25 +KPX ydieresis ocircumflex -25 +KPX ydieresis odieresis -25 +KPX ydieresis ograve -25 +KPX ydieresis ohungarumlaut -25 +KPX ydieresis omacron -25 +KPX ydieresis oslash -25 +KPX ydieresis otilde -25 +KPX ydieresis period -80 +KPX z e 10 +KPX z eacute 10 +KPX z ecaron 10 +KPX z ecircumflex 10 +KPX z edieresis 10 +KPX z edotaccent 10 +KPX z egrave 10 +KPX z emacron 10 +KPX z eogonek 10 +KPX zacute e 10 +KPX zacute eacute 10 +KPX zacute ecaron 10 +KPX zacute ecircumflex 10 +KPX zacute edieresis 10 +KPX zacute edotaccent 10 +KPX zacute egrave 10 +KPX zacute emacron 10 +KPX zacute eogonek 10 +KPX zcaron e 10 +KPX zcaron eacute 10 +KPX zcaron ecaron 10 +KPX zcaron ecircumflex 10 +KPX zcaron edieresis 10 +KPX zcaron edotaccent 10 +KPX zcaron egrave 10 +KPX zcaron emacron 10 +KPX zcaron eogonek 10 +KPX zdotaccent e 10 +KPX zdotaccent eacute 10 +KPX zdotaccent ecaron 10 +KPX zdotaccent ecircumflex 10 +KPX zdotaccent edieresis 10 +KPX zdotaccent edotaccent 10 +KPX zdotaccent egrave 10 +KPX zdotaccent emacron 10 +KPX zdotaccent eogonek 10 +EndKernPairs +EndKernData +EndFontMetrics addfile ./Core14_AFMs/Helvetica-Oblique.afm hunk ./Core14_AFMs/Helvetica-Oblique.afm 1 +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 12:44:31 1997 +Comment UniqueID 43055 +Comment VMusage 14960 69346 +FontName Helvetica-Oblique +FullName Helvetica Oblique +FamilyName Helvetica +Weight Medium +ItalicAngle -12 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -170 -225 1116 931 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 523 +Ascender 718 +Descender -207 +StdHW 76 +StdVW 88 +StartCharMetrics 315 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 278 ; N exclam ; B 90 0 340 718 ; +C 34 ; WX 355 ; N quotedbl ; B 168 463 438 718 ; +C 35 ; WX 556 ; N numbersign ; B 73 0 631 688 ; +C 36 ; WX 556 ; N dollar ; B 69 -115 617 775 ; +C 37 ; WX 889 ; N percent ; B 147 -19 889 703 ; +C 38 ; WX 667 ; N ampersand ; B 77 -15 647 718 ; +C 39 ; WX 222 ; N quoteright ; B 151 463 310 718 ; +C 40 ; WX 333 ; N parenleft ; B 108 -207 454 733 ; +C 41 ; WX 333 ; N parenright ; B -9 -207 337 733 ; +C 42 ; WX 389 ; N asterisk ; B 165 431 475 718 ; +C 43 ; WX 584 ; N plus ; B 85 0 606 505 ; +C 44 ; WX 278 ; N comma ; B 56 -147 214 106 ; +C 45 ; WX 333 ; N hyphen ; B 93 232 357 322 ; +C 46 ; WX 278 ; N period ; B 87 0 214 106 ; +C 47 ; WX 278 ; N slash ; B -21 -19 452 737 ; +C 48 ; WX 556 ; N zero ; B 93 -19 608 703 ; +C 49 ; WX 556 ; N one ; B 207 0 508 703 ; +C 50 ; WX 556 ; N two ; B 26 0 617 703 ; +C 51 ; WX 556 ; N three ; B 75 -19 610 703 ; +C 52 ; WX 556 ; N four ; B 61 0 576 703 ; +C 53 ; WX 556 ; N five ; B 68 -19 621 688 ; +C 54 ; WX 556 ; N six ; B 91 -19 615 703 ; +C 55 ; WX 556 ; N seven ; B 137 0 669 688 ; +C 56 ; WX 556 ; N eight ; B 74 -19 607 703 ; +C 57 ; WX 556 ; N nine ; B 82 -19 609 703 ; +C 58 ; WX 278 ; N colon ; B 87 0 301 516 ; +C 59 ; WX 278 ; N semicolon ; B 56 -147 301 516 ; +C 60 ; WX 584 ; N less ; B 94 11 641 495 ; +C 61 ; WX 584 ; N equal ; B 63 115 628 390 ; +C 62 ; WX 584 ; N greater ; B 50 11 597 495 ; +C 63 ; WX 556 ; N question ; B 161 0 610 727 ; +C 64 ; WX 1015 ; N at ; B 215 -19 965 737 ; +C 65 ; WX 667 ; N A ; B 14 0 654 718 ; +C 66 ; WX 667 ; N B ; B 74 0 712 718 ; +C 67 ; WX 722 ; N C ; B 108 -19 782 737 ; +C 68 ; WX 722 ; N D ; B 81 0 764 718 ; +C 69 ; WX 667 ; N E ; B 86 0 762 718 ; +C 70 ; WX 611 ; N F ; B 86 0 736 718 ; +C 71 ; WX 778 ; N G ; B 111 -19 799 737 ; +C 72 ; WX 722 ; N H ; B 77 0 799 718 ; +C 73 ; WX 278 ; N I ; B 91 0 341 718 ; +C 74 ; WX 500 ; N J ; B 47 -19 581 718 ; +C 75 ; WX 667 ; N K ; B 76 0 808 718 ; +C 76 ; WX 556 ; N L ; B 76 0 555 718 ; +C 77 ; WX 833 ; N M ; B 73 0 914 718 ; +C 78 ; WX 722 ; N N ; B 76 0 799 718 ; +C 79 ; WX 778 ; N O ; B 105 -19 826 737 ; +C 80 ; WX 667 ; N P ; B 86 0 737 718 ; +C 81 ; WX 778 ; N Q ; B 105 -56 826 737 ; +C 82 ; WX 722 ; N R ; B 88 0 773 718 ; +C 83 ; WX 667 ; N S ; B 90 -19 713 737 ; +C 84 ; WX 611 ; N T ; B 148 0 750 718 ; +C 85 ; WX 722 ; N U ; B 123 -19 797 718 ; +C 86 ; WX 667 ; N V ; B 173 0 800 718 ; +C 87 ; WX 944 ; N W ; B 169 0 1081 718 ; +C 88 ; WX 667 ; N X ; B 19 0 790 718 ; +C 89 ; WX 667 ; N Y ; B 167 0 806 718 ; +C 90 ; WX 611 ; N Z ; B 23 0 741 718 ; +C 91 ; WX 278 ; N bracketleft ; B 21 -196 403 722 ; +C 92 ; WX 278 ; N backslash ; B 140 -19 291 737 ; +C 93 ; WX 278 ; N bracketright ; B -14 -196 368 722 ; +C 94 ; WX 469 ; N asciicircum ; B 42 264 539 688 ; +C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ; +C 96 ; WX 222 ; N quoteleft ; B 165 470 323 725 ; +C 97 ; WX 556 ; N a ; B 61 -15 559 538 ; +C 98 ; WX 556 ; N b ; B 58 -15 584 718 ; +C 99 ; WX 500 ; N c ; B 74 -15 553 538 ; +C 100 ; WX 556 ; N d ; B 84 -15 652 718 ; +C 101 ; WX 556 ; N e ; B 84 -15 578 538 ; +C 102 ; WX 278 ; N f ; B 86 0 416 728 ; L i fi ; L l fl ; +C 103 ; WX 556 ; N g ; B 42 -220 610 538 ; +C 104 ; WX 556 ; N h ; B 65 0 573 718 ; +C 105 ; WX 222 ; N i ; B 67 0 308 718 ; +C 106 ; WX 222 ; N j ; B -60 -210 308 718 ; +C 107 ; WX 500 ; N k ; B 67 0 600 718 ; +C 108 ; WX 222 ; N l ; B 67 0 308 718 ; +C 109 ; WX 833 ; N m ; B 65 0 852 538 ; +C 110 ; WX 556 ; N n ; B 65 0 573 538 ; +C 111 ; WX 556 ; N o ; B 83 -14 585 538 ; +C 112 ; WX 556 ; N p ; B 14 -207 584 538 ; +C 113 ; WX 556 ; N q ; B 84 -207 605 538 ; +C 114 ; WX 333 ; N r ; B 77 0 446 538 ; +C 115 ; WX 500 ; N s ; B 63 -15 529 538 ; +C 116 ; WX 278 ; N t ; B 102 -7 368 669 ; +C 117 ; WX 556 ; N u ; B 94 -15 600 523 ; +C 118 ; WX 500 ; N v ; B 119 0 603 523 ; +C 119 ; WX 722 ; N w ; B 125 0 820 523 ; +C 120 ; WX 500 ; N x ; B 11 0 594 523 ; +C 121 ; WX 500 ; N y ; B 15 -214 600 523 ; +C 122 ; WX 500 ; N z ; B 31 0 571 523 ; +C 123 ; WX 334 ; N braceleft ; B 92 -196 445 722 ; +C 124 ; WX 260 ; N bar ; B 46 -225 332 775 ; +C 125 ; WX 334 ; N braceright ; B 0 -196 354 722 ; +C 126 ; WX 584 ; N asciitilde ; B 111 180 580 326 ; +C 161 ; WX 333 ; N exclamdown ; B 77 -195 326 523 ; +C 162 ; WX 556 ; N cent ; B 95 -115 584 623 ; +C 163 ; WX 556 ; N sterling ; B 49 -16 634 718 ; +C 164 ; WX 167 ; N fraction ; B -170 -19 482 703 ; +C 165 ; WX 556 ; N yen ; B 81 0 699 688 ; +C 166 ; WX 556 ; N florin ; B -52 -207 654 737 ; +C 167 ; WX 556 ; N section ; B 76 -191 584 737 ; +C 168 ; WX 556 ; N currency ; B 60 99 646 603 ; +C 169 ; WX 191 ; N quotesingle ; B 157 463 285 718 ; +C 170 ; WX 333 ; N quotedblleft ; B 138 470 461 725 ; +C 171 ; WX 556 ; N guillemotleft ; B 146 108 554 446 ; +C 172 ; WX 333 ; N guilsinglleft ; B 137 108 340 446 ; +C 173 ; WX 333 ; N guilsinglright ; B 111 108 314 446 ; +C 174 ; WX 500 ; N fi ; B 86 0 587 728 ; +C 175 ; WX 500 ; N fl ; B 86 0 585 728 ; +C 177 ; WX 556 ; N endash ; B 51 240 623 313 ; +C 178 ; WX 556 ; N dagger ; B 135 -159 622 718 ; +C 179 ; WX 556 ; N daggerdbl ; B 52 -159 623 718 ; +C 180 ; WX 278 ; N periodcentered ; B 129 190 257 315 ; +C 182 ; WX 537 ; N paragraph ; B 126 -173 650 718 ; +C 183 ; WX 350 ; N bullet ; B 91 202 413 517 ; +C 184 ; WX 222 ; N quotesinglbase ; B 21 -149 180 106 ; +C 185 ; WX 333 ; N quotedblbase ; B -6 -149 318 106 ; +C 186 ; WX 333 ; N quotedblright ; B 124 463 448 718 ; +C 187 ; WX 556 ; N guillemotright ; B 120 108 528 446 ; +C 188 ; WX 1000 ; N ellipsis ; B 115 0 908 106 ; +C 189 ; WX 1000 ; N perthousand ; B 88 -19 1029 703 ; +C 191 ; WX 611 ; N questiondown ; B 85 -201 534 525 ; +C 193 ; WX 333 ; N grave ; B 170 593 337 734 ; +C 194 ; WX 333 ; N acute ; B 248 593 475 734 ; +C 195 ; WX 333 ; N circumflex ; B 147 593 438 734 ; +C 196 ; WX 333 ; N tilde ; B 125 606 490 722 ; +C 197 ; WX 333 ; N macron ; B 143 627 468 684 ; +C 198 ; WX 333 ; N breve ; B 167 595 476 731 ; +C 199 ; WX 333 ; N dotaccent ; B 249 604 362 706 ; +C 200 ; WX 333 ; N dieresis ; B 168 604 443 706 ; +C 202 ; WX 333 ; N ring ; B 214 572 402 756 ; +C 203 ; WX 333 ; N cedilla ; B 2 -225 232 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 157 593 565 734 ; +C 206 ; WX 333 ; N ogonek ; B 43 -225 249 0 ; +C 207 ; WX 333 ; N caron ; B 177 593 468 734 ; +C 208 ; WX 1000 ; N emdash ; B 51 240 1067 313 ; +C 225 ; WX 1000 ; N AE ; B 8 0 1097 718 ; +C 227 ; WX 370 ; N ordfeminine ; B 127 405 449 737 ; +C 232 ; WX 556 ; N Lslash ; B 41 0 555 718 ; +C 233 ; WX 778 ; N Oslash ; B 43 -19 890 737 ; +C 234 ; WX 1000 ; N OE ; B 98 -19 1116 737 ; +C 235 ; WX 365 ; N ordmasculine ; B 141 405 468 737 ; +C 241 ; WX 889 ; N ae ; B 61 -15 909 538 ; +C 245 ; WX 278 ; N dotlessi ; B 95 0 294 523 ; +C 248 ; WX 222 ; N lslash ; B 41 0 347 718 ; +C 249 ; WX 611 ; N oslash ; B 29 -22 647 545 ; +C 250 ; WX 944 ; N oe ; B 83 -15 964 538 ; +C 251 ; WX 611 ; N germandbls ; B 67 -15 658 728 ; +C -1 ; WX 278 ; N Idieresis ; B 91 0 458 901 ; +C -1 ; WX 556 ; N eacute ; B 84 -15 587 734 ; +C -1 ; WX 556 ; N abreve ; B 61 -15 578 731 ; +C -1 ; WX 556 ; N uhungarumlaut ; B 94 -15 677 734 ; +C -1 ; WX 556 ; N ecaron ; B 84 -15 580 734 ; +C -1 ; WX 667 ; N Ydieresis ; B 167 0 806 901 ; +C -1 ; WX 584 ; N divide ; B 85 -19 606 524 ; +C -1 ; WX 667 ; N Yacute ; B 167 0 806 929 ; +C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ; +C -1 ; WX 556 ; N aacute ; B 61 -15 587 734 ; +C -1 ; WX 722 ; N Ucircumflex ; B 123 -19 797 929 ; +C -1 ; WX 500 ; N yacute ; B 15 -214 600 734 ; +C -1 ; WX 500 ; N scommaaccent ; B 63 -225 529 538 ; +C -1 ; WX 556 ; N ecircumflex ; B 84 -15 578 734 ; +C -1 ; WX 722 ; N Uring ; B 123 -19 797 931 ; +C -1 ; WX 722 ; N Udieresis ; B 123 -19 797 901 ; +C -1 ; WX 556 ; N aogonek ; B 61 -220 559 538 ; +C -1 ; WX 722 ; N Uacute ; B 123 -19 797 929 ; +C -1 ; WX 556 ; N uogonek ; B 94 -225 600 523 ; +C -1 ; WX 667 ; N Edieresis ; B 86 0 762 901 ; +C -1 ; WX 722 ; N Dcroat ; B 69 0 764 718 ; +C -1 ; WX 250 ; N commaaccent ; B 39 -225 172 -40 ; +C -1 ; WX 737 ; N copyright ; B 54 -19 837 737 ; +C -1 ; WX 667 ; N Emacron ; B 86 0 762 879 ; +C -1 ; WX 500 ; N ccaron ; B 74 -15 553 734 ; +C -1 ; WX 556 ; N aring ; B 61 -15 559 756 ; +C -1 ; WX 722 ; N Ncommaaccent ; B 76 -225 799 718 ; +C -1 ; WX 222 ; N lacute ; B 67 0 461 929 ; +C -1 ; WX 556 ; N agrave ; B 61 -15 559 734 ; +C -1 ; WX 611 ; N Tcommaaccent ; B 148 -225 750 718 ; +C -1 ; WX 722 ; N Cacute ; B 108 -19 782 929 ; +C -1 ; WX 556 ; N atilde ; B 61 -15 592 722 ; +C -1 ; WX 667 ; N Edotaccent ; B 86 0 762 901 ; +C -1 ; WX 500 ; N scaron ; B 63 -15 552 734 ; +C -1 ; WX 500 ; N scedilla ; B 63 -225 529 538 ; +C -1 ; WX 278 ; N iacute ; B 95 0 448 734 ; +C -1 ; WX 471 ; N lozenge ; B 88 0 540 728 ; +C -1 ; WX 722 ; N Rcaron ; B 88 0 773 929 ; +C -1 ; WX 778 ; N Gcommaaccent ; B 111 -225 799 737 ; +C -1 ; WX 556 ; N ucircumflex ; B 94 -15 600 734 ; +C -1 ; WX 556 ; N acircumflex ; B 61 -15 559 734 ; +C -1 ; WX 667 ; N Amacron ; B 14 0 677 879 ; +C -1 ; WX 333 ; N rcaron ; B 77 0 508 734 ; +C -1 ; WX 500 ; N ccedilla ; B 74 -225 553 538 ; +C -1 ; WX 611 ; N Zdotaccent ; B 23 0 741 901 ; +C -1 ; WX 667 ; N Thorn ; B 86 0 712 718 ; +C -1 ; WX 778 ; N Omacron ; B 105 -19 826 879 ; +C -1 ; WX 722 ; N Racute ; B 88 0 773 929 ; +C -1 ; WX 667 ; N Sacute ; B 90 -19 713 929 ; +C -1 ; WX 643 ; N dcaron ; B 84 -15 808 718 ; +C -1 ; WX 722 ; N Umacron ; B 123 -19 797 879 ; +C -1 ; WX 556 ; N uring ; B 94 -15 600 756 ; +C -1 ; WX 333 ; N threesuperior ; B 90 270 436 703 ; +C -1 ; WX 778 ; N Ograve ; B 105 -19 826 929 ; +C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ; +C -1 ; WX 667 ; N Abreve ; B 14 0 685 926 ; +C -1 ; WX 584 ; N multiply ; B 50 0 642 506 ; +C -1 ; WX 556 ; N uacute ; B 94 -15 600 734 ; +C -1 ; WX 611 ; N Tcaron ; B 148 0 750 929 ; +C -1 ; WX 476 ; N partialdiff ; B 41 -38 550 714 ; +C -1 ; WX 500 ; N ydieresis ; B 15 -214 600 706 ; +C -1 ; WX 722 ; N Nacute ; B 76 0 799 929 ; +C -1 ; WX 278 ; N icircumflex ; B 95 0 411 734 ; +C -1 ; WX 667 ; N Ecircumflex ; B 86 0 762 929 ; +C -1 ; WX 556 ; N adieresis ; B 61 -15 559 706 ; +C -1 ; WX 556 ; N edieresis ; B 84 -15 578 706 ; +C -1 ; WX 500 ; N cacute ; B 74 -15 559 734 ; +C -1 ; WX 556 ; N nacute ; B 65 0 587 734 ; +C -1 ; WX 556 ; N umacron ; B 94 -15 600 684 ; +C -1 ; WX 722 ; N Ncaron ; B 76 0 799 929 ; +C -1 ; WX 278 ; N Iacute ; B 91 0 489 929 ; +C -1 ; WX 584 ; N plusminus ; B 39 0 618 506 ; +C -1 ; WX 260 ; N brokenbar ; B 62 -150 316 700 ; +C -1 ; WX 737 ; N registered ; B 54 -19 837 737 ; +C -1 ; WX 778 ; N Gbreve ; B 111 -19 799 926 ; +C -1 ; WX 278 ; N Idotaccent ; B 91 0 377 901 ; +C -1 ; WX 600 ; N summation ; B 15 -10 671 706 ; +C -1 ; WX 667 ; N Egrave ; B 86 0 762 929 ; +C -1 ; WX 333 ; N racute ; B 77 0 475 734 ; +C -1 ; WX 556 ; N omacron ; B 83 -14 585 684 ; +C -1 ; WX 611 ; N Zacute ; B 23 0 741 929 ; +C -1 ; WX 611 ; N Zcaron ; B 23 0 741 929 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 620 674 ; +C -1 ; WX 722 ; N Eth ; B 69 0 764 718 ; +C -1 ; WX 722 ; N Ccedilla ; B 108 -225 782 737 ; +C -1 ; WX 222 ; N lcommaaccent ; B 25 -225 308 718 ; +C -1 ; WX 317 ; N tcaron ; B 102 -7 501 808 ; +C -1 ; WX 556 ; N eogonek ; B 84 -225 578 538 ; +C -1 ; WX 722 ; N Uogonek ; B 123 -225 797 718 ; +C -1 ; WX 667 ; N Aacute ; B 14 0 683 929 ; +C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ; +C -1 ; WX 556 ; N egrave ; B 84 -15 578 734 ; +C -1 ; WX 500 ; N zacute ; B 31 0 571 734 ; +C -1 ; WX 222 ; N iogonek ; B -61 -225 308 718 ; +C -1 ; WX 778 ; N Oacute ; B 105 -19 826 929 ; +C -1 ; WX 556 ; N oacute ; B 83 -14 587 734 ; +C -1 ; WX 556 ; N amacron ; B 61 -15 580 684 ; +C -1 ; WX 500 ; N sacute ; B 63 -15 559 734 ; +C -1 ; WX 278 ; N idieresis ; B 95 0 416 706 ; +C -1 ; WX 778 ; N Ocircumflex ; B 105 -19 826 929 ; +C -1 ; WX 722 ; N Ugrave ; B 123 -19 797 929 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 556 ; N thorn ; B 14 -207 584 718 ; +C -1 ; WX 333 ; N twosuperior ; B 64 281 449 703 ; +C -1 ; WX 778 ; N Odieresis ; B 105 -19 826 901 ; +C -1 ; WX 556 ; N mu ; B 24 -207 600 523 ; +C -1 ; WX 278 ; N igrave ; B 95 0 310 734 ; +C -1 ; WX 556 ; N ohungarumlaut ; B 83 -14 677 734 ; +C -1 ; WX 667 ; N Eogonek ; B 86 -220 762 718 ; +C -1 ; WX 556 ; N dcroat ; B 84 -15 689 718 ; +C -1 ; WX 834 ; N threequarters ; B 130 -19 861 703 ; +C -1 ; WX 667 ; N Scedilla ; B 90 -225 713 737 ; +C -1 ; WX 299 ; N lcaron ; B 67 0 464 718 ; +C -1 ; WX 667 ; N Kcommaaccent ; B 76 -225 808 718 ; +C -1 ; WX 556 ; N Lacute ; B 76 0 555 929 ; +C -1 ; WX 1000 ; N trademark ; B 186 306 1056 718 ; +C -1 ; WX 556 ; N edotaccent ; B 84 -15 578 706 ; +C -1 ; WX 278 ; N Igrave ; B 91 0 351 929 ; +C -1 ; WX 278 ; N Imacron ; B 91 0 483 879 ; +C -1 ; WX 556 ; N Lcaron ; B 76 0 570 718 ; +C -1 ; WX 834 ; N onehalf ; B 114 -19 839 703 ; +C -1 ; WX 549 ; N lessequal ; B 26 0 666 674 ; +C -1 ; WX 556 ; N ocircumflex ; B 83 -14 585 734 ; +C -1 ; WX 556 ; N ntilde ; B 65 0 592 722 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 123 -19 801 929 ; +C -1 ; WX 667 ; N Eacute ; B 86 0 762 929 ; +C -1 ; WX 556 ; N emacron ; B 84 -15 580 684 ; +C -1 ; WX 556 ; N gbreve ; B 42 -220 610 731 ; +C -1 ; WX 834 ; N onequarter ; B 150 -19 802 703 ; +C -1 ; WX 667 ; N Scaron ; B 90 -19 713 929 ; +C -1 ; WX 667 ; N Scommaaccent ; B 90 -225 713 737 ; +C -1 ; WX 778 ; N Ohungarumlaut ; B 105 -19 829 929 ; +C -1 ; WX 400 ; N degree ; B 169 411 468 703 ; +C -1 ; WX 556 ; N ograve ; B 83 -14 585 734 ; +C -1 ; WX 722 ; N Ccaron ; B 108 -19 782 929 ; +C -1 ; WX 556 ; N ugrave ; B 94 -15 600 734 ; +C -1 ; WX 453 ; N radical ; B 79 -80 617 762 ; +C -1 ; WX 722 ; N Dcaron ; B 81 0 764 929 ; +C -1 ; WX 333 ; N rcommaaccent ; B 30 -225 446 538 ; +C -1 ; WX 722 ; N Ntilde ; B 76 0 799 917 ; +C -1 ; WX 556 ; N otilde ; B 83 -14 602 722 ; +C -1 ; WX 722 ; N Rcommaaccent ; B 88 -225 773 718 ; +C -1 ; WX 556 ; N Lcommaaccent ; B 76 -225 555 718 ; +C -1 ; WX 667 ; N Atilde ; B 14 0 699 917 ; +C -1 ; WX 667 ; N Aogonek ; B 14 -225 654 718 ; +C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ; +C -1 ; WX 778 ; N Otilde ; B 105 -19 826 917 ; +C -1 ; WX 500 ; N zdotaccent ; B 31 0 571 706 ; +C -1 ; WX 667 ; N Ecaron ; B 86 0 762 929 ; +C -1 ; WX 278 ; N Iogonek ; B -33 -225 341 718 ; +C -1 ; WX 500 ; N kcommaaccent ; B 67 -225 600 718 ; +C -1 ; WX 584 ; N minus ; B 85 216 606 289 ; +C -1 ; WX 278 ; N Icircumflex ; B 91 0 452 929 ; +C -1 ; WX 556 ; N ncaron ; B 65 0 580 734 ; +C -1 ; WX 278 ; N tcommaaccent ; B 63 -225 368 669 ; +C -1 ; WX 584 ; N logicalnot ; B 106 108 628 390 ; +C -1 ; WX 556 ; N odieresis ; B 83 -14 585 706 ; +C -1 ; WX 556 ; N udieresis ; B 94 -15 600 706 ; +C -1 ; WX 549 ; N notequal ; B 34 -35 623 551 ; +C -1 ; WX 556 ; N gcommaaccent ; B 42 -220 610 822 ; +C -1 ; WX 556 ; N eth ; B 81 -15 617 737 ; +C -1 ; WX 500 ; N zcaron ; B 31 0 571 734 ; +C -1 ; WX 556 ; N ncommaaccent ; B 65 -225 573 538 ; +C -1 ; WX 333 ; N onesuperior ; B 166 281 371 703 ; +C -1 ; WX 278 ; N imacron ; B 95 0 417 684 ; +C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2705 +KPX A C -30 +KPX A Cacute -30 +KPX A Ccaron -30 +KPX A Ccedilla -30 +KPX A G -30 +KPX A Gbreve -30 +KPX A Gcommaaccent -30 +KPX A O -30 +KPX A Oacute -30 +KPX A Ocircumflex -30 +KPX A Odieresis -30 +KPX A Ograve -30 +KPX A Ohungarumlaut -30 +KPX A Omacron -30 +KPX A Oslash -30 +KPX A Otilde -30 +KPX A Q -30 +KPX A T -120 +KPX A Tcaron -120 +KPX A Tcommaaccent -120 +KPX A U -50 +KPX A Uacute -50 +KPX A Ucircumflex -50 +KPX A Udieresis -50 +KPX A Ugrave -50 +KPX A Uhungarumlaut -50 +KPX A Umacron -50 +KPX A Uogonek -50 +KPX A Uring -50 +KPX A V -70 +KPX A W -50 +KPX A Y -100 +KPX A Yacute -100 +KPX A Ydieresis -100 +KPX A u -30 +KPX A uacute -30 +KPX A ucircumflex -30 +KPX A udieresis -30 +KPX A ugrave -30 +KPX A uhungarumlaut -30 +KPX A umacron -30 +KPX A uogonek -30 +KPX A uring -30 +KPX A v -40 +KPX A w -40 +KPX A y -40 +KPX A yacute -40 +KPX A ydieresis -40 +KPX Aacute C -30 +KPX Aacute Cacute -30 +KPX Aacute Ccaron -30 +KPX Aacute Ccedilla -30 +KPX Aacute G -30 +KPX Aacute Gbreve -30 +KPX Aacute Gcommaaccent -30 +KPX Aacute O -30 +KPX Aacute Oacute -30 +KPX Aacute Ocircumflex -30 +KPX Aacute Odieresis -30 +KPX Aacute Ograve -30 +KPX Aacute Ohungarumlaut -30 +KPX Aacute Omacron -30 +KPX Aacute Oslash -30 +KPX Aacute Otilde -30 +KPX Aacute Q -30 +KPX Aacute T -120 +KPX Aacute Tcaron -120 +KPX Aacute Tcommaaccent -120 +KPX Aacute U -50 +KPX Aacute Uacute -50 +KPX Aacute Ucircumflex -50 +KPX Aacute Udieresis -50 +KPX Aacute Ugrave -50 +KPX Aacute Uhungarumlaut -50 +KPX Aacute Umacron -50 +KPX Aacute Uogonek -50 +KPX Aacute Uring -50 +KPX Aacute V -70 +KPX Aacute W -50 +KPX Aacute Y -100 +KPX Aacute Yacute -100 +KPX Aacute Ydieresis -100 +KPX Aacute u -30 +KPX Aacute uacute -30 +KPX Aacute ucircumflex -30 +KPX Aacute udieresis -30 +KPX Aacute ugrave -30 +KPX Aacute uhungarumlaut -30 +KPX Aacute umacron -30 +KPX Aacute uogonek -30 +KPX Aacute uring -30 +KPX Aacute v -40 +KPX Aacute w -40 +KPX Aacute y -40 +KPX Aacute yacute -40 +KPX Aacute ydieresis -40 +KPX Abreve C -30 +KPX Abreve Cacute -30 +KPX Abreve Ccaron -30 +KPX Abreve Ccedilla -30 +KPX Abreve G -30 +KPX Abreve Gbreve -30 +KPX Abreve Gcommaaccent -30 +KPX Abreve O -30 +KPX Abreve Oacute -30 +KPX Abreve Ocircumflex -30 +KPX Abreve Odieresis -30 +KPX Abreve Ograve -30 +KPX Abreve Ohungarumlaut -30 +KPX Abreve Omacron -30 +KPX Abreve Oslash -30 +KPX Abreve Otilde -30 +KPX Abreve Q -30 +KPX Abreve T -120 +KPX Abreve Tcaron -120 +KPX Abreve Tcommaaccent -120 +KPX Abreve U -50 +KPX Abreve Uacute -50 +KPX Abreve Ucircumflex -50 +KPX Abreve Udieresis -50 +KPX Abreve Ugrave -50 +KPX Abreve Uhungarumlaut -50 +KPX Abreve Umacron -50 +KPX Abreve Uogonek -50 +KPX Abreve Uring -50 +KPX Abreve V -70 +KPX Abreve W -50 +KPX Abreve Y -100 +KPX Abreve Yacute -100 +KPX Abreve Ydieresis -100 +KPX Abreve u -30 +KPX Abreve uacute -30 +KPX Abreve ucircumflex -30 +KPX Abreve udieresis -30 +KPX Abreve ugrave -30 +KPX Abreve uhungarumlaut -30 +KPX Abreve umacron -30 +KPX Abreve uogonek -30 +KPX Abreve uring -30 +KPX Abreve v -40 +KPX Abreve w -40 +KPX Abreve y -40 +KPX Abreve yacute -40 +KPX Abreve ydieresis -40 +KPX Acircumflex C -30 +KPX Acircumflex Cacute -30 +KPX Acircumflex Ccaron -30 +KPX Acircumflex Ccedilla -30 +KPX Acircumflex G -30 +KPX Acircumflex Gbreve -30 +KPX Acircumflex Gcommaaccent -30 +KPX Acircumflex O -30 +KPX Acircumflex Oacute -30 +KPX Acircumflex Ocircumflex -30 +KPX Acircumflex Odieresis -30 +KPX Acircumflex Ograve -30 +KPX Acircumflex Ohungarumlaut -30 +KPX Acircumflex Omacron -30 +KPX Acircumflex Oslash -30 +KPX Acircumflex Otilde -30 +KPX Acircumflex Q -30 +KPX Acircumflex T -120 +KPX Acircumflex Tcaron -120 +KPX Acircumflex Tcommaaccent -120 +KPX Acircumflex U -50 +KPX Acircumflex Uacute -50 +KPX Acircumflex Ucircumflex -50 +KPX Acircumflex Udieresis -50 +KPX Acircumflex Ugrave -50 +KPX Acircumflex Uhungarumlaut -50 +KPX Acircumflex Umacron -50 +KPX Acircumflex Uogonek -50 +KPX Acircumflex Uring -50 +KPX Acircumflex V -70 +KPX Acircumflex W -50 +KPX Acircumflex Y -100 +KPX Acircumflex Yacute -100 +KPX Acircumflex Ydieresis -100 +KPX Acircumflex u -30 +KPX Acircumflex uacute -30 +KPX Acircumflex ucircumflex -30 +KPX Acircumflex udieresis -30 +KPX Acircumflex ugrave -30 +KPX Acircumflex uhungarumlaut -30 +KPX Acircumflex umacron -30 +KPX Acircumflex uogonek -30 +KPX Acircumflex uring -30 +KPX Acircumflex v -40 +KPX Acircumflex w -40 +KPX Acircumflex y -40 +KPX Acircumflex yacute -40 +KPX Acircumflex ydieresis -40 +KPX Adieresis C -30 +KPX Adieresis Cacute -30 +KPX Adieresis Ccaron -30 +KPX Adieresis Ccedilla -30 +KPX Adieresis G -30 +KPX Adieresis Gbreve -30 +KPX Adieresis Gcommaaccent -30 +KPX Adieresis O -30 +KPX Adieresis Oacute -30 +KPX Adieresis Ocircumflex -30 +KPX Adieresis Odieresis -30 +KPX Adieresis Ograve -30 +KPX Adieresis Ohungarumlaut -30 +KPX Adieresis Omacron -30 +KPX Adieresis Oslash -30 +KPX Adieresis Otilde -30 +KPX Adieresis Q -30 +KPX Adieresis T -120 +KPX Adieresis Tcaron -120 +KPX Adieresis Tcommaaccent -120 +KPX Adieresis U -50 +KPX Adieresis Uacute -50 +KPX Adieresis Ucircumflex -50 +KPX Adieresis Udieresis -50 +KPX Adieresis Ugrave -50 +KPX Adieresis Uhungarumlaut -50 +KPX Adieresis Umacron -50 +KPX Adieresis Uogonek -50 +KPX Adieresis Uring -50 +KPX Adieresis V -70 +KPX Adieresis W -50 +KPX Adieresis Y -100 +KPX Adieresis Yacute -100 +KPX Adieresis Ydieresis -100 +KPX Adieresis u -30 +KPX Adieresis uacute -30 +KPX Adieresis ucircumflex -30 +KPX Adieresis udieresis -30 +KPX Adieresis ugrave -30 +KPX Adieresis uhungarumlaut -30 +KPX Adieresis umacron -30 +KPX Adieresis uogonek -30 +KPX Adieresis uring -30 +KPX Adieresis v -40 +KPX Adieresis w -40 +KPX Adieresis y -40 +KPX Adieresis yacute -40 +KPX Adieresis ydieresis -40 +KPX Agrave C -30 +KPX Agrave Cacute -30 +KPX Agrave Ccaron -30 +KPX Agrave Ccedilla -30 +KPX Agrave G -30 +KPX Agrave Gbreve -30 +KPX Agrave Gcommaaccent -30 +KPX Agrave O -30 +KPX Agrave Oacute -30 +KPX Agrave Ocircumflex -30 +KPX Agrave Odieresis -30 +KPX Agrave Ograve -30 +KPX Agrave Ohungarumlaut -30 +KPX Agrave Omacron -30 +KPX Agrave Oslash -30 +KPX Agrave Otilde -30 +KPX Agrave Q -30 +KPX Agrave T -120 +KPX Agrave Tcaron -120 +KPX Agrave Tcommaaccent -120 +KPX Agrave U -50 +KPX Agrave Uacute -50 +KPX Agrave Ucircumflex -50 +KPX Agrave Udieresis -50 +KPX Agrave Ugrave -50 +KPX Agrave Uhungarumlaut -50 +KPX Agrave Umacron -50 +KPX Agrave Uogonek -50 +KPX Agrave Uring -50 +KPX Agrave V -70 +KPX Agrave W -50 +KPX Agrave Y -100 +KPX Agrave Yacute -100 +KPX Agrave Ydieresis -100 +KPX Agrave u -30 +KPX Agrave uacute -30 +KPX Agrave ucircumflex -30 +KPX Agrave udieresis -30 +KPX Agrave ugrave -30 +KPX Agrave uhungarumlaut -30 +KPX Agrave umacron -30 +KPX Agrave uogonek -30 +KPX Agrave uring -30 +KPX Agrave v -40 +KPX Agrave w -40 +KPX Agrave y -40 +KPX Agrave yacute -40 +KPX Agrave ydieresis -40 +KPX Amacron C -30 +KPX Amacron Cacute -30 +KPX Amacron Ccaron -30 +KPX Amacron Ccedilla -30 +KPX Amacron G -30 +KPX Amacron Gbreve -30 +KPX Amacron Gcommaaccent -30 +KPX Amacron O -30 +KPX Amacron Oacute -30 +KPX Amacron Ocircumflex -30 +KPX Amacron Odieresis -30 +KPX Amacron Ograve -30 +KPX Amacron Ohungarumlaut -30 +KPX Amacron Omacron -30 +KPX Amacron Oslash -30 +KPX Amacron Otilde -30 +KPX Amacron Q -30 +KPX Amacron T -120 +KPX Amacron Tcaron -120 +KPX Amacron Tcommaaccent -120 +KPX Amacron U -50 +KPX Amacron Uacute -50 +KPX Amacron Ucircumflex -50 +KPX Amacron Udieresis -50 +KPX Amacron Ugrave -50 +KPX Amacron Uhungarumlaut -50 +KPX Amacron Umacron -50 +KPX Amacron Uogonek -50 +KPX Amacron Uring -50 +KPX Amacron V -70 +KPX Amacron W -50 +KPX Amacron Y -100 +KPX Amacron Yacute -100 +KPX Amacron Ydieresis -100 +KPX Amacron u -30 +KPX Amacron uacute -30 +KPX Amacron ucircumflex -30 +KPX Amacron udieresis -30 +KPX Amacron ugrave -30 +KPX Amacron uhungarumlaut -30 +KPX Amacron umacron -30 +KPX Amacron uogonek -30 +KPX Amacron uring -30 +KPX Amacron v -40 +KPX Amacron w -40 +KPX Amacron y -40 +KPX Amacron yacute -40 +KPX Amacron ydieresis -40 +KPX Aogonek C -30 +KPX Aogonek Cacute -30 +KPX Aogonek Ccaron -30 +KPX Aogonek Ccedilla -30 +KPX Aogonek G -30 +KPX Aogonek Gbreve -30 +KPX Aogonek Gcommaaccent -30 +KPX Aogonek O -30 +KPX Aogonek Oacute -30 +KPX Aogonek Ocircumflex -30 +KPX Aogonek Odieresis -30 +KPX Aogonek Ograve -30 +KPX Aogonek Ohungarumlaut -30 +KPX Aogonek Omacron -30 +KPX Aogonek Oslash -30 +KPX Aogonek Otilde -30 +KPX Aogonek Q -30 +KPX Aogonek T -120 +KPX Aogonek Tcaron -120 +KPX Aogonek Tcommaaccent -120 +KPX Aogonek U -50 +KPX Aogonek Uacute -50 +KPX Aogonek Ucircumflex -50 +KPX Aogonek Udieresis -50 +KPX Aogonek Ugrave -50 +KPX Aogonek Uhungarumlaut -50 +KPX Aogonek Umacron -50 +KPX Aogonek Uogonek -50 +KPX Aogonek Uring -50 +KPX Aogonek V -70 +KPX Aogonek W -50 +KPX Aogonek Y -100 +KPX Aogonek Yacute -100 +KPX Aogonek Ydieresis -100 +KPX Aogonek u -30 +KPX Aogonek uacute -30 +KPX Aogonek ucircumflex -30 +KPX Aogonek udieresis -30 +KPX Aogonek ugrave -30 +KPX Aogonek uhungarumlaut -30 +KPX Aogonek umacron -30 +KPX Aogonek uogonek -30 +KPX Aogonek uring -30 +KPX Aogonek v -40 +KPX Aogonek w -40 +KPX Aogonek y -40 +KPX Aogonek yacute -40 +KPX Aogonek ydieresis -40 +KPX Aring C -30 +KPX Aring Cacute -30 +KPX Aring Ccaron -30 +KPX Aring Ccedilla -30 +KPX Aring G -30 +KPX Aring Gbreve -30 +KPX Aring Gcommaaccent -30 +KPX Aring O -30 +KPX Aring Oacute -30 +KPX Aring Ocircumflex -30 +KPX Aring Odieresis -30 +KPX Aring Ograve -30 +KPX Aring Ohungarumlaut -30 +KPX Aring Omacron -30 +KPX Aring Oslash -30 +KPX Aring Otilde -30 +KPX Aring Q -30 +KPX Aring T -120 +KPX Aring Tcaron -120 +KPX Aring Tcommaaccent -120 +KPX Aring U -50 +KPX Aring Uacute -50 +KPX Aring Ucircumflex -50 +KPX Aring Udieresis -50 +KPX Aring Ugrave -50 +KPX Aring Uhungarumlaut -50 +KPX Aring Umacron -50 +KPX Aring Uogonek -50 +KPX Aring Uring -50 +KPX Aring V -70 +KPX Aring W -50 +KPX Aring Y -100 +KPX Aring Yacute -100 +KPX Aring Ydieresis -100 +KPX Aring u -30 +KPX Aring uacute -30 +KPX Aring ucircumflex -30 +KPX Aring udieresis -30 +KPX Aring ugrave -30 +KPX Aring uhungarumlaut -30 +KPX Aring umacron -30 +KPX Aring uogonek -30 +KPX Aring uring -30 +KPX Aring v -40 +KPX Aring w -40 +KPX Aring y -40 +KPX Aring yacute -40 +KPX Aring ydieresis -40 +KPX Atilde C -30 +KPX Atilde Cacute -30 +KPX Atilde Ccaron -30 +KPX Atilde Ccedilla -30 +KPX Atilde G -30 +KPX Atilde Gbreve -30 +KPX Atilde Gcommaaccent -30 +KPX Atilde O -30 +KPX Atilde Oacute -30 +KPX Atilde Ocircumflex -30 +KPX Atilde Odieresis -30 +KPX Atilde Ograve -30 +KPX Atilde Ohungarumlaut -30 +KPX Atilde Omacron -30 +KPX Atilde Oslash -30 +KPX Atilde Otilde -30 +KPX Atilde Q -30 +KPX Atilde T -120 +KPX Atilde Tcaron -120 +KPX Atilde Tcommaaccent -120 +KPX Atilde U -50 +KPX Atilde Uacute -50 +KPX Atilde Ucircumflex -50 +KPX Atilde Udieresis -50 +KPX Atilde Ugrave -50 +KPX Atilde Uhungarumlaut -50 +KPX Atilde Umacron -50 +KPX Atilde Uogonek -50 +KPX Atilde Uring -50 +KPX Atilde V -70 +KPX Atilde W -50 +KPX Atilde Y -100 +KPX Atilde Yacute -100 +KPX Atilde Ydieresis -100 +KPX Atilde u -30 +KPX Atilde uacute -30 +KPX Atilde ucircumflex -30 +KPX Atilde udieresis -30 +KPX Atilde ugrave -30 +KPX Atilde uhungarumlaut -30 +KPX Atilde umacron -30 +KPX Atilde uogonek -30 +KPX Atilde uring -30 +KPX Atilde v -40 +KPX Atilde w -40 +KPX Atilde y -40 +KPX Atilde yacute -40 +KPX Atilde ydieresis -40 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX B comma -20 +KPX B period -20 +KPX C comma -30 +KPX C period -30 +KPX Cacute comma -30 +KPX Cacute period -30 +KPX Ccaron comma -30 +KPX Ccaron period -30 +KPX Ccedilla comma -30 +KPX Ccedilla period -30 +KPX D A -40 +KPX D Aacute -40 +KPX D Abreve -40 +KPX D Acircumflex -40 +KPX D Adieresis -40 +KPX D Agrave -40 +KPX D Amacron -40 +KPX D Aogonek -40 +KPX D Aring -40 +KPX D Atilde -40 +KPX D V -70 +KPX D W -40 +KPX D Y -90 +KPX D Yacute -90 +KPX D Ydieresis -90 +KPX D comma -70 +KPX D period -70 +KPX Dcaron A -40 +KPX Dcaron Aacute -40 +KPX Dcaron Abreve -40 +KPX Dcaron Acircumflex -40 +KPX Dcaron Adieresis -40 +KPX Dcaron Agrave -40 +KPX Dcaron Amacron -40 +KPX Dcaron Aogonek -40 +KPX Dcaron Aring -40 +KPX Dcaron Atilde -40 +KPX Dcaron V -70 +KPX Dcaron W -40 +KPX Dcaron Y -90 +KPX Dcaron Yacute -90 +KPX Dcaron Ydieresis -90 +KPX Dcaron comma -70 +KPX Dcaron period -70 +KPX Dcroat A -40 +KPX Dcroat Aacute -40 +KPX Dcroat Abreve -40 +KPX Dcroat Acircumflex -40 +KPX Dcroat Adieresis -40 +KPX Dcroat Agrave -40 +KPX Dcroat Amacron -40 +KPX Dcroat Aogonek -40 +KPX Dcroat Aring -40 +KPX Dcroat Atilde -40 +KPX Dcroat V -70 +KPX Dcroat W -40 +KPX Dcroat Y -90 +KPX Dcroat Yacute -90 +KPX Dcroat Ydieresis -90 +KPX Dcroat comma -70 +KPX Dcroat period -70 +KPX F A -80 +KPX F Aacute -80 +KPX F Abreve -80 +KPX F Acircumflex -80 +KPX F Adieresis -80 +KPX F Agrave -80 +KPX F Amacron -80 +KPX F Aogonek -80 +KPX F Aring -80 +KPX F Atilde -80 +KPX F a -50 +KPX F aacute -50 +KPX F abreve -50 +KPX F acircumflex -50 +KPX F adieresis -50 +KPX F agrave -50 +KPX F amacron -50 +KPX F aogonek -50 +KPX F aring -50 +KPX F atilde -50 +KPX F comma -150 +KPX F e -30 +KPX F eacute -30 +KPX F ecaron -30 +KPX F ecircumflex -30 +KPX F edieresis -30 +KPX F edotaccent -30 +KPX F egrave -30 +KPX F emacron -30 +KPX F eogonek -30 +KPX F o -30 +KPX F oacute -30 +KPX F ocircumflex -30 +KPX F odieresis -30 +KPX F ograve -30 +KPX F ohungarumlaut -30 +KPX F omacron -30 +KPX F oslash -30 +KPX F otilde -30 +KPX F period -150 +KPX F r -45 +KPX F racute -45 +KPX F rcaron -45 +KPX F rcommaaccent -45 +KPX J A -20 +KPX J Aacute -20 +KPX J Abreve -20 +KPX J Acircumflex -20 +KPX J Adieresis -20 +KPX J Agrave -20 +KPX J Amacron -20 +KPX J Aogonek -20 +KPX J Aring -20 +KPX J Atilde -20 +KPX J a -20 +KPX J aacute -20 +KPX J abreve -20 +KPX J acircumflex -20 +KPX J adieresis -20 +KPX J agrave -20 +KPX J amacron -20 +KPX J aogonek -20 +KPX J aring -20 +KPX J atilde -20 +KPX J comma -30 +KPX J period -30 +KPX J u -20 +KPX J uacute -20 +KPX J ucircumflex -20 +KPX J udieresis -20 +KPX J ugrave -20 +KPX J uhungarumlaut -20 +KPX J umacron -20 +KPX J uogonek -20 +KPX J uring -20 +KPX K O -50 +KPX K Oacute -50 +KPX K Ocircumflex -50 +KPX K Odieresis -50 +KPX K Ograve -50 +KPX K Ohungarumlaut -50 +KPX K Omacron -50 +KPX K Oslash -50 +KPX K Otilde -50 +KPX K e -40 +KPX K eacute -40 +KPX K ecaron -40 +KPX K ecircumflex -40 +KPX K edieresis -40 +KPX K edotaccent -40 +KPX K egrave -40 +KPX K emacron -40 +KPX K eogonek -40 +KPX K o -40 +KPX K oacute -40 +KPX K ocircumflex -40 +KPX K odieresis -40 +KPX K ograve -40 +KPX K ohungarumlaut -40 +KPX K omacron -40 +KPX K oslash -40 +KPX K otilde -40 +KPX K u -30 +KPX K uacute -30 +KPX K ucircumflex -30 +KPX K udieresis -30 +KPX K ugrave -30 +KPX K uhungarumlaut -30 +KPX K umacron -30 +KPX K uogonek -30 +KPX K uring -30 +KPX K y -50 +KPX K yacute -50 +KPX K ydieresis -50 +KPX Kcommaaccent O -50 +KPX Kcommaaccent Oacute -50 +KPX Kcommaaccent Ocircumflex -50 +KPX Kcommaaccent Odieresis -50 +KPX Kcommaaccent Ograve -50 +KPX Kcommaaccent Ohungarumlaut -50 +KPX Kcommaaccent Omacron -50 +KPX Kcommaaccent Oslash -50 +KPX Kcommaaccent Otilde -50 +KPX Kcommaaccent e -40 +KPX Kcommaaccent eacute -40 +KPX Kcommaaccent ecaron -40 +KPX Kcommaaccent ecircumflex -40 +KPX Kcommaaccent edieresis -40 +KPX Kcommaaccent edotaccent -40 +KPX Kcommaaccent egrave -40 +KPX Kcommaaccent emacron -40 +KPX Kcommaaccent eogonek -40 +KPX Kcommaaccent o -40 +KPX Kcommaaccent oacute -40 +KPX Kcommaaccent ocircumflex -40 +KPX Kcommaaccent odieresis -40 +KPX Kcommaaccent ograve -40 +KPX Kcommaaccent ohungarumlaut -40 +KPX Kcommaaccent omacron -40 +KPX Kcommaaccent oslash -40 +KPX Kcommaaccent otilde -40 +KPX Kcommaaccent u -30 +KPX Kcommaaccent uacute -30 +KPX Kcommaaccent ucircumflex -30 +KPX Kcommaaccent udieresis -30 +KPX Kcommaaccent ugrave -30 +KPX Kcommaaccent uhungarumlaut -30 +KPX Kcommaaccent umacron -30 +KPX Kcommaaccent uogonek -30 +KPX Kcommaaccent uring -30 +KPX Kcommaaccent y -50 +KPX Kcommaaccent yacute -50 +KPX Kcommaaccent ydieresis -50 +KPX L T -110 +KPX L Tcaron -110 +KPX L Tcommaaccent -110 +KPX L V -110 +KPX L W -70 +KPX L Y -140 +KPX L Yacute -140 +KPX L Ydieresis -140 +KPX L quotedblright -140 +KPX L quoteright -160 +KPX L y -30 +KPX L yacute -30 +KPX L ydieresis -30 +KPX Lacute T -110 +KPX Lacute Tcaron -110 +KPX Lacute Tcommaaccent -110 +KPX Lacute V -110 +KPX Lacute W -70 +KPX Lacute Y -140 +KPX Lacute Yacute -140 +KPX Lacute Ydieresis -140 +KPX Lacute quotedblright -140 +KPX Lacute quoteright -160 +KPX Lacute y -30 +KPX Lacute yacute -30 +KPX Lacute ydieresis -30 +KPX Lcaron T -110 +KPX Lcaron Tcaron -110 +KPX Lcaron Tcommaaccent -110 +KPX Lcaron V -110 +KPX Lcaron W -70 +KPX Lcaron Y -140 +KPX Lcaron Yacute -140 +KPX Lcaron Ydieresis -140 +KPX Lcaron quotedblright -140 +KPX Lcaron quoteright -160 +KPX Lcaron y -30 +KPX Lcaron yacute -30 +KPX Lcaron ydieresis -30 +KPX Lcommaaccent T -110 +KPX Lcommaaccent Tcaron -110 +KPX Lcommaaccent Tcommaaccent -110 +KPX Lcommaaccent V -110 +KPX Lcommaaccent W -70 +KPX Lcommaaccent Y -140 +KPX Lcommaaccent Yacute -140 +KPX Lcommaaccent Ydieresis -140 +KPX Lcommaaccent quotedblright -140 +KPX Lcommaaccent quoteright -160 +KPX Lcommaaccent y -30 +KPX Lcommaaccent yacute -30 +KPX Lcommaaccent ydieresis -30 +KPX Lslash T -110 +KPX Lslash Tcaron -110 +KPX Lslash Tcommaaccent -110 +KPX Lslash V -110 +KPX Lslash W -70 +KPX Lslash Y -140 +KPX Lslash Yacute -140 +KPX Lslash Ydieresis -140 +KPX Lslash quotedblright -140 +KPX Lslash quoteright -160 +KPX Lslash y -30 +KPX Lslash yacute -30 +KPX Lslash ydieresis -30 +KPX O A -20 +KPX O Aacute -20 +KPX O Abreve -20 +KPX O Acircumflex -20 +KPX O Adieresis -20 +KPX O Agrave -20 +KPX O Amacron -20 +KPX O Aogonek -20 +KPX O Aring -20 +KPX O Atilde -20 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -30 +KPX O X -60 +KPX O Y -70 +KPX O Yacute -70 +KPX O Ydieresis -70 +KPX O comma -40 +KPX O period -40 +KPX Oacute A -20 +KPX Oacute Aacute -20 +KPX Oacute Abreve -20 +KPX Oacute Acircumflex -20 +KPX Oacute Adieresis -20 +KPX Oacute Agrave -20 +KPX Oacute Amacron -20 +KPX Oacute Aogonek -20 +KPX Oacute Aring -20 +KPX Oacute Atilde -20 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -30 +KPX Oacute X -60 +KPX Oacute Y -70 +KPX Oacute Yacute -70 +KPX Oacute Ydieresis -70 +KPX Oacute comma -40 +KPX Oacute period -40 +KPX Ocircumflex A -20 +KPX Ocircumflex Aacute -20 +KPX Ocircumflex Abreve -20 +KPX Ocircumflex Acircumflex -20 +KPX Ocircumflex Adieresis -20 +KPX Ocircumflex Agrave -20 +KPX Ocircumflex Amacron -20 +KPX Ocircumflex Aogonek -20 +KPX Ocircumflex Aring -20 +KPX Ocircumflex Atilde -20 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -30 +KPX Ocircumflex X -60 +KPX Ocircumflex Y -70 +KPX Ocircumflex Yacute -70 +KPX Ocircumflex Ydieresis -70 +KPX Ocircumflex comma -40 +KPX Ocircumflex period -40 +KPX Odieresis A -20 +KPX Odieresis Aacute -20 +KPX Odieresis Abreve -20 +KPX Odieresis Acircumflex -20 +KPX Odieresis Adieresis -20 +KPX Odieresis Agrave -20 +KPX Odieresis Amacron -20 +KPX Odieresis Aogonek -20 +KPX Odieresis Aring -20 +KPX Odieresis Atilde -20 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -30 +KPX Odieresis X -60 +KPX Odieresis Y -70 +KPX Odieresis Yacute -70 +KPX Odieresis Ydieresis -70 +KPX Odieresis comma -40 +KPX Odieresis period -40 +KPX Ograve A -20 +KPX Ograve Aacute -20 +KPX Ograve Abreve -20 +KPX Ograve Acircumflex -20 +KPX Ograve Adieresis -20 +KPX Ograve Agrave -20 +KPX Ograve Amacron -20 +KPX Ograve Aogonek -20 +KPX Ograve Aring -20 +KPX Ograve Atilde -20 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -30 +KPX Ograve X -60 +KPX Ograve Y -70 +KPX Ograve Yacute -70 +KPX Ograve Ydieresis -70 +KPX Ograve comma -40 +KPX Ograve period -40 +KPX Ohungarumlaut A -20 +KPX Ohungarumlaut Aacute -20 +KPX Ohungarumlaut Abreve -20 +KPX Ohungarumlaut Acircumflex -20 +KPX Ohungarumlaut Adieresis -20 +KPX Ohungarumlaut Agrave -20 +KPX Ohungarumlaut Amacron -20 +KPX Ohungarumlaut Aogonek -20 +KPX Ohungarumlaut Aring -20 +KPX Ohungarumlaut Atilde -20 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -30 +KPX Ohungarumlaut X -60 +KPX Ohungarumlaut Y -70 +KPX Ohungarumlaut Yacute -70 +KPX Ohungarumlaut Ydieresis -70 +KPX Ohungarumlaut comma -40 +KPX Ohungarumlaut period -40 +KPX Omacron A -20 +KPX Omacron Aacute -20 +KPX Omacron Abreve -20 +KPX Omacron Acircumflex -20 +KPX Omacron Adieresis -20 +KPX Omacron Agrave -20 +KPX Omacron Amacron -20 +KPX Omacron Aogonek -20 +KPX Omacron Aring -20 +KPX Omacron Atilde -20 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -30 +KPX Omacron X -60 +KPX Omacron Y -70 +KPX Omacron Yacute -70 +KPX Omacron Ydieresis -70 +KPX Omacron comma -40 +KPX Omacron period -40 +KPX Oslash A -20 +KPX Oslash Aacute -20 +KPX Oslash Abreve -20 +KPX Oslash Acircumflex -20 +KPX Oslash Adieresis -20 +KPX Oslash Agrave -20 +KPX Oslash Amacron -20 +KPX Oslash Aogonek -20 +KPX Oslash Aring -20 +KPX Oslash Atilde -20 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -30 +KPX Oslash X -60 +KPX Oslash Y -70 +KPX Oslash Yacute -70 +KPX Oslash Ydieresis -70 +KPX Oslash comma -40 +KPX Oslash period -40 +KPX Otilde A -20 +KPX Otilde Aacute -20 +KPX Otilde Abreve -20 +KPX Otilde Acircumflex -20 +KPX Otilde Adieresis -20 +KPX Otilde Agrave -20 +KPX Otilde Amacron -20 +KPX Otilde Aogonek -20 +KPX Otilde Aring -20 +KPX Otilde Atilde -20 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -30 +KPX Otilde X -60 +KPX Otilde Y -70 +KPX Otilde Yacute -70 +KPX Otilde Ydieresis -70 +KPX Otilde comma -40 +KPX Otilde period -40 +KPX P A -120 +KPX P Aacute -120 +KPX P Abreve -120 +KPX P Acircumflex -120 +KPX P Adieresis -120 +KPX P Agrave -120 +KPX P Amacron -120 +KPX P Aogonek -120 +KPX P Aring -120 +KPX P Atilde -120 +KPX P a -40 +KPX P aacute -40 +KPX P abreve -40 +KPX P acircumflex -40 +KPX P adieresis -40 +KPX P agrave -40 +KPX P amacron -40 +KPX P aogonek -40 +KPX P aring -40 +KPX P atilde -40 +KPX P comma -180 +KPX P e -50 +KPX P eacute -50 +KPX P ecaron -50 +KPX P ecircumflex -50 +KPX P edieresis -50 +KPX P edotaccent -50 +KPX P egrave -50 +KPX P emacron -50 +KPX P eogonek -50 +KPX P o -50 +KPX P oacute -50 +KPX P ocircumflex -50 +KPX P odieresis -50 +KPX P ograve -50 +KPX P ohungarumlaut -50 +KPX P omacron -50 +KPX P oslash -50 +KPX P otilde -50 +KPX P period -180 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX R O -20 +KPX R Oacute -20 +KPX R Ocircumflex -20 +KPX R Odieresis -20 +KPX R Ograve -20 +KPX R Ohungarumlaut -20 +KPX R Omacron -20 +KPX R Oslash -20 +KPX R Otilde -20 +KPX R T -30 +KPX R Tcaron -30 +KPX R Tcommaaccent -30 +KPX R U -40 +KPX R Uacute -40 +KPX R Ucircumflex -40 +KPX R Udieresis -40 +KPX R Ugrave -40 +KPX R Uhungarumlaut -40 +KPX R Umacron -40 +KPX R Uogonek -40 +KPX R Uring -40 +KPX R V -50 +KPX R W -30 +KPX R Y -50 +KPX R Yacute -50 +KPX R Ydieresis -50 +KPX Racute O -20 +KPX Racute Oacute -20 +KPX Racute Ocircumflex -20 +KPX Racute Odieresis -20 +KPX Racute Ograve -20 +KPX Racute Ohungarumlaut -20 +KPX Racute Omacron -20 +KPX Racute Oslash -20 +KPX Racute Otilde -20 +KPX Racute T -30 +KPX Racute Tcaron -30 +KPX Racute Tcommaaccent -30 +KPX Racute U -40 +KPX Racute Uacute -40 +KPX Racute Ucircumflex -40 +KPX Racute Udieresis -40 +KPX Racute Ugrave -40 +KPX Racute Uhungarumlaut -40 +KPX Racute Umacron -40 +KPX Racute Uogonek -40 +KPX Racute Uring -40 +KPX Racute V -50 +KPX Racute W -30 +KPX Racute Y -50 +KPX Racute Yacute -50 +KPX Racute Ydieresis -50 +KPX Rcaron O -20 +KPX Rcaron Oacute -20 +KPX Rcaron Ocircumflex -20 +KPX Rcaron Odieresis -20 +KPX Rcaron Ograve -20 +KPX Rcaron Ohungarumlaut -20 +KPX Rcaron Omacron -20 +KPX Rcaron Oslash -20 +KPX Rcaron Otilde -20 +KPX Rcaron T -30 +KPX Rcaron Tcaron -30 +KPX Rcaron Tcommaaccent -30 +KPX Rcaron U -40 +KPX Rcaron Uacute -40 +KPX Rcaron Ucircumflex -40 +KPX Rcaron Udieresis -40 +KPX Rcaron Ugrave -40 +KPX Rcaron Uhungarumlaut -40 +KPX Rcaron Umacron -40 +KPX Rcaron Uogonek -40 +KPX Rcaron Uring -40 +KPX Rcaron V -50 +KPX Rcaron W -30 +KPX Rcaron Y -50 +KPX Rcaron Yacute -50 +KPX Rcaron Ydieresis -50 +KPX Rcommaaccent O -20 +KPX Rcommaaccent Oacute -20 +KPX Rcommaaccent Ocircumflex -20 +KPX Rcommaaccent Odieresis -20 +KPX Rcommaaccent Ograve -20 +KPX Rcommaaccent Ohungarumlaut -20 +KPX Rcommaaccent Omacron -20 +KPX Rcommaaccent Oslash -20 +KPX Rcommaaccent Otilde -20 +KPX Rcommaaccent T -30 +KPX Rcommaaccent Tcaron -30 +KPX Rcommaaccent Tcommaaccent -30 +KPX Rcommaaccent U -40 +KPX Rcommaaccent Uacute -40 +KPX Rcommaaccent Ucircumflex -40 +KPX Rcommaaccent Udieresis -40 +KPX Rcommaaccent Ugrave -40 +KPX Rcommaaccent Uhungarumlaut -40 +KPX Rcommaaccent Umacron -40 +KPX Rcommaaccent Uogonek -40 +KPX Rcommaaccent Uring -40 +KPX Rcommaaccent V -50 +KPX Rcommaaccent W -30 +KPX Rcommaaccent Y -50 +KPX Rcommaaccent Yacute -50 +KPX Rcommaaccent Ydieresis -50 +KPX S comma -20 +KPX S period -20 +KPX Sacute comma -20 +KPX Sacute period -20 +KPX Scaron comma -20 +KPX Scaron period -20 +KPX Scedilla comma -20 +KPX Scedilla period -20 +KPX Scommaaccent comma -20 +KPX Scommaaccent period -20 +KPX T A -120 +KPX T Aacute -120 +KPX T Abreve -120 +KPX T Acircumflex -120 +KPX T Adieresis -120 +KPX T Agrave -120 +KPX T Amacron -120 +KPX T Aogonek -120 +KPX T Aring -120 +KPX T Atilde -120 +KPX T O -40 +KPX T Oacute -40 +KPX T Ocircumflex -40 +KPX T Odieresis -40 +KPX T Ograve -40 +KPX T Ohungarumlaut -40 +KPX T Omacron -40 +KPX T Oslash -40 +KPX T Otilde -40 +KPX T a -120 +KPX T aacute -120 +KPX T abreve -60 +KPX T acircumflex -120 +KPX T adieresis -120 +KPX T agrave -120 +KPX T amacron -60 +KPX T aogonek -120 +KPX T aring -120 +KPX T atilde -60 +KPX T colon -20 +KPX T comma -120 +KPX T e -120 +KPX T eacute -120 +KPX T ecaron -120 +KPX T ecircumflex -120 +KPX T edieresis -120 +KPX T edotaccent -120 +KPX T egrave -60 +KPX T emacron -60 +KPX T eogonek -120 +KPX T hyphen -140 +KPX T o -120 +KPX T oacute -120 +KPX T ocircumflex -120 +KPX T odieresis -120 +KPX T ograve -120 +KPX T ohungarumlaut -120 +KPX T omacron -60 +KPX T oslash -120 +KPX T otilde -60 +KPX T period -120 +KPX T r -120 +KPX T racute -120 +KPX T rcaron -120 +KPX T rcommaaccent -120 +KPX T semicolon -20 +KPX T u -120 +KPX T uacute -120 +KPX T ucircumflex -120 +KPX T udieresis -120 +KPX T ugrave -120 +KPX T uhungarumlaut -120 +KPX T umacron -60 +KPX T uogonek -120 +KPX T uring -120 +KPX T w -120 +KPX T y -120 +KPX T yacute -120 +KPX T ydieresis -60 +KPX Tcaron A -120 +KPX Tcaron Aacute -120 +KPX Tcaron Abreve -120 +KPX Tcaron Acircumflex -120 +KPX Tcaron Adieresis -120 +KPX Tcaron Agrave -120 +KPX Tcaron Amacron -120 +KPX Tcaron Aogonek -120 +KPX Tcaron Aring -120 +KPX Tcaron Atilde -120 +KPX Tcaron O -40 +KPX Tcaron Oacute -40 +KPX Tcaron Ocircumflex -40 +KPX Tcaron Odieresis -40 +KPX Tcaron Ograve -40 +KPX Tcaron Ohungarumlaut -40 +KPX Tcaron Omacron -40 +KPX Tcaron Oslash -40 +KPX Tcaron Otilde -40 +KPX Tcaron a -120 +KPX Tcaron aacute -120 +KPX Tcaron abreve -60 +KPX Tcaron acircumflex -120 +KPX Tcaron adieresis -120 +KPX Tcaron agrave -120 +KPX Tcaron amacron -60 +KPX Tcaron aogonek -120 +KPX Tcaron aring -120 +KPX Tcaron atilde -60 +KPX Tcaron colon -20 +KPX Tcaron comma -120 +KPX Tcaron e -120 +KPX Tcaron eacute -120 +KPX Tcaron ecaron -120 +KPX Tcaron ecircumflex -120 +KPX Tcaron edieresis -120 +KPX Tcaron edotaccent -120 +KPX Tcaron egrave -60 +KPX Tcaron emacron -60 +KPX Tcaron eogonek -120 +KPX Tcaron hyphen -140 +KPX Tcaron o -120 +KPX Tcaron oacute -120 +KPX Tcaron ocircumflex -120 +KPX Tcaron odieresis -120 +KPX Tcaron ograve -120 +KPX Tcaron ohungarumlaut -120 +KPX Tcaron omacron -60 +KPX Tcaron oslash -120 +KPX Tcaron otilde -60 +KPX Tcaron period -120 +KPX Tcaron r -120 +KPX Tcaron racute -120 +KPX Tcaron rcaron -120 +KPX Tcaron rcommaaccent -120 +KPX Tcaron semicolon -20 +KPX Tcaron u -120 +KPX Tcaron uacute -120 +KPX Tcaron ucircumflex -120 +KPX Tcaron udieresis -120 +KPX Tcaron ugrave -120 +KPX Tcaron uhungarumlaut -120 +KPX Tcaron umacron -60 +KPX Tcaron uogonek -120 +KPX Tcaron uring -120 +KPX Tcaron w -120 +KPX Tcaron y -120 +KPX Tcaron yacute -120 +KPX Tcaron ydieresis -60 +KPX Tcommaaccent A -120 +KPX Tcommaaccent Aacute -120 +KPX Tcommaaccent Abreve -120 +KPX Tcommaaccent Acircumflex -120 +KPX Tcommaaccent Adieresis -120 +KPX Tcommaaccent Agrave -120 +KPX Tcommaaccent Amacron -120 +KPX Tcommaaccent Aogonek -120 +KPX Tcommaaccent Aring -120 +KPX Tcommaaccent Atilde -120 +KPX Tcommaaccent O -40 +KPX Tcommaaccent Oacute -40 +KPX Tcommaaccent Ocircumflex -40 +KPX Tcommaaccent Odieresis -40 +KPX Tcommaaccent Ograve -40 +KPX Tcommaaccent Ohungarumlaut -40 +KPX Tcommaaccent Omacron -40 +KPX Tcommaaccent Oslash -40 +KPX Tcommaaccent Otilde -40 +KPX Tcommaaccent a -120 +KPX Tcommaaccent aacute -120 +KPX Tcommaaccent abreve -60 +KPX Tcommaaccent acircumflex -120 +KPX Tcommaaccent adieresis -120 +KPX Tcommaaccent agrave -120 +KPX Tcommaaccent amacron -60 +KPX Tcommaaccent aogonek -120 +KPX Tcommaaccent aring -120 +KPX Tcommaaccent atilde -60 +KPX Tcommaaccent colon -20 +KPX Tcommaaccent comma -120 +KPX Tcommaaccent e -120 +KPX Tcommaaccent eacute -120 +KPX Tcommaaccent ecaron -120 +KPX Tcommaaccent ecircumflex -120 +KPX Tcommaaccent edieresis -120 +KPX Tcommaaccent edotaccent -120 +KPX Tcommaaccent egrave -60 +KPX Tcommaaccent emacron -60 +KPX Tcommaaccent eogonek -120 +KPX Tcommaaccent hyphen -140 +KPX Tcommaaccent o -120 +KPX Tcommaaccent oacute -120 +KPX Tcommaaccent ocircumflex -120 +KPX Tcommaaccent odieresis -120 +KPX Tcommaaccent ograve -120 +KPX Tcommaaccent ohungarumlaut -120 +KPX Tcommaaccent omacron -60 +KPX Tcommaaccent oslash -120 +KPX Tcommaaccent otilde -60 +KPX Tcommaaccent period -120 +KPX Tcommaaccent r -120 +KPX Tcommaaccent racute -120 +KPX Tcommaaccent rcaron -120 +KPX Tcommaaccent rcommaaccent -120 +KPX Tcommaaccent semicolon -20 +KPX Tcommaaccent u -120 +KPX Tcommaaccent uacute -120 +KPX Tcommaaccent ucircumflex -120 +KPX Tcommaaccent udieresis -120 +KPX Tcommaaccent ugrave -120 +KPX Tcommaaccent uhungarumlaut -120 +KPX Tcommaaccent umacron -60 +KPX Tcommaaccent uogonek -120 +KPX Tcommaaccent uring -120 +KPX Tcommaaccent w -120 +KPX Tcommaaccent y -120 +KPX Tcommaaccent yacute -120 +KPX Tcommaaccent ydieresis -60 +KPX U A -40 +KPX U Aacute -40 +KPX U Abreve -40 +KPX U Acircumflex -40 +KPX U Adieresis -40 +KPX U Agrave -40 +KPX U Amacron -40 +KPX U Aogonek -40 +KPX U Aring -40 +KPX U Atilde -40 +KPX U comma -40 +KPX U period -40 +KPX Uacute A -40 +KPX Uacute Aacute -40 +KPX Uacute Abreve -40 +KPX Uacute Acircumflex -40 +KPX Uacute Adieresis -40 +KPX Uacute Agrave -40 +KPX Uacute Amacron -40 +KPX Uacute Aogonek -40 +KPX Uacute Aring -40 +KPX Uacute Atilde -40 +KPX Uacute comma -40 +KPX Uacute period -40 +KPX Ucircumflex A -40 +KPX Ucircumflex Aacute -40 +KPX Ucircumflex Abreve -40 +KPX Ucircumflex Acircumflex -40 +KPX Ucircumflex Adieresis -40 +KPX Ucircumflex Agrave -40 +KPX Ucircumflex Amacron -40 +KPX Ucircumflex Aogonek -40 +KPX Ucircumflex Aring -40 +KPX Ucircumflex Atilde -40 +KPX Ucircumflex comma -40 +KPX Ucircumflex period -40 +KPX Udieresis A -40 +KPX Udieresis Aacute -40 +KPX Udieresis Abreve -40 +KPX Udieresis Acircumflex -40 +KPX Udieresis Adieresis -40 +KPX Udieresis Agrave -40 +KPX Udieresis Amacron -40 +KPX Udieresis Aogonek -40 +KPX Udieresis Aring -40 +KPX Udieresis Atilde -40 +KPX Udieresis comma -40 +KPX Udieresis period -40 +KPX Ugrave A -40 +KPX Ugrave Aacute -40 +KPX Ugrave Abreve -40 +KPX Ugrave Acircumflex -40 +KPX Ugrave Adieresis -40 +KPX Ugrave Agrave -40 +KPX Ugrave Amacron -40 +KPX Ugrave Aogonek -40 +KPX Ugrave Aring -40 +KPX Ugrave Atilde -40 +KPX Ugrave comma -40 +KPX Ugrave period -40 +KPX Uhungarumlaut A -40 +KPX Uhungarumlaut Aacute -40 +KPX Uhungarumlaut Abreve -40 +KPX Uhungarumlaut Acircumflex -40 +KPX Uhungarumlaut Adieresis -40 +KPX Uhungarumlaut Agrave -40 +KPX Uhungarumlaut Amacron -40 +KPX Uhungarumlaut Aogonek -40 +KPX Uhungarumlaut Aring -40 +KPX Uhungarumlaut Atilde -40 +KPX Uhungarumlaut comma -40 +KPX Uhungarumlaut period -40 +KPX Umacron A -40 +KPX Umacron Aacute -40 +KPX Umacron Abreve -40 +KPX Umacron Acircumflex -40 +KPX Umacron Adieresis -40 +KPX Umacron Agrave -40 +KPX Umacron Amacron -40 +KPX Umacron Aogonek -40 +KPX Umacron Aring -40 +KPX Umacron Atilde -40 +KPX Umacron comma -40 +KPX Umacron period -40 +KPX Uogonek A -40 +KPX Uogonek Aacute -40 +KPX Uogonek Abreve -40 +KPX Uogonek Acircumflex -40 +KPX Uogonek Adieresis -40 +KPX Uogonek Agrave -40 +KPX Uogonek Amacron -40 +KPX Uogonek Aogonek -40 +KPX Uogonek Aring -40 +KPX Uogonek Atilde -40 +KPX Uogonek comma -40 +KPX Uogonek period -40 +KPX Uring A -40 +KPX Uring Aacute -40 +KPX Uring Abreve -40 +KPX Uring Acircumflex -40 +KPX Uring Adieresis -40 +KPX Uring Agrave -40 +KPX Uring Amacron -40 +KPX Uring Aogonek -40 +KPX Uring Aring -40 +KPX Uring Atilde -40 +KPX Uring comma -40 +KPX Uring period -40 +KPX V A -80 +KPX V Aacute -80 +KPX V Abreve -80 +KPX V Acircumflex -80 +KPX V Adieresis -80 +KPX V Agrave -80 +KPX V Amacron -80 +KPX V Aogonek -80 +KPX V Aring -80 +KPX V Atilde -80 +KPX V G -40 +KPX V Gbreve -40 +KPX V Gcommaaccent -40 +KPX V O -40 +KPX V Oacute -40 +KPX V Ocircumflex -40 +KPX V Odieresis -40 +KPX V Ograve -40 +KPX V Ohungarumlaut -40 +KPX V Omacron -40 +KPX V Oslash -40 +KPX V Otilde -40 +KPX V a -70 +KPX V aacute -70 +KPX V abreve -70 +KPX V acircumflex -70 +KPX V adieresis -70 +KPX V agrave -70 +KPX V amacron -70 +KPX V aogonek -70 +KPX V aring -70 +KPX V atilde -70 +KPX V colon -40 +KPX V comma -125 +KPX V e -80 +KPX V eacute -80 +KPX V ecaron -80 +KPX V ecircumflex -80 +KPX V edieresis -80 +KPX V edotaccent -80 +KPX V egrave -80 +KPX V emacron -80 +KPX V eogonek -80 +KPX V hyphen -80 +KPX V o -80 +KPX V oacute -80 +KPX V ocircumflex -80 +KPX V odieresis -80 +KPX V ograve -80 +KPX V ohungarumlaut -80 +KPX V omacron -80 +KPX V oslash -80 +KPX V otilde -80 +KPX V period -125 +KPX V semicolon -40 +KPX V u -70 +KPX V uacute -70 +KPX V ucircumflex -70 +KPX V udieresis -70 +KPX V ugrave -70 +KPX V uhungarumlaut -70 +KPX V umacron -70 +KPX V uogonek -70 +KPX V uring -70 +KPX W A -50 +KPX W Aacute -50 +KPX W Abreve -50 +KPX W Acircumflex -50 +KPX W Adieresis -50 +KPX W Agrave -50 +KPX W Amacron -50 +KPX W Aogonek -50 +KPX W Aring -50 +KPX W Atilde -50 +KPX W O -20 +KPX W Oacute -20 +KPX W Ocircumflex -20 +KPX W Odieresis -20 +KPX W Ograve -20 +KPX W Ohungarumlaut -20 +KPX W Omacron -20 +KPX W Oslash -20 +KPX W Otilde -20 +KPX W a -40 +KPX W aacute -40 +KPX W abreve -40 +KPX W acircumflex -40 +KPX W adieresis -40 +KPX W agrave -40 +KPX W amacron -40 +KPX W aogonek -40 +KPX W aring -40 +KPX W atilde -40 +KPX W comma -80 +KPX W e -30 +KPX W eacute -30 +KPX W ecaron -30 +KPX W ecircumflex -30 +KPX W edieresis -30 +KPX W edotaccent -30 +KPX W egrave -30 +KPX W emacron -30 +KPX W eogonek -30 +KPX W hyphen -40 +KPX W o -30 +KPX W oacute -30 +KPX W ocircumflex -30 +KPX W odieresis -30 +KPX W ograve -30 +KPX W ohungarumlaut -30 +KPX W omacron -30 +KPX W oslash -30 +KPX W otilde -30 +KPX W period -80 +KPX W u -30 +KPX W uacute -30 +KPX W ucircumflex -30 +KPX W udieresis -30 +KPX W ugrave -30 +KPX W uhungarumlaut -30 +KPX W umacron -30 +KPX W uogonek -30 +KPX W uring -30 +KPX W y -20 +KPX W yacute -20 +KPX W ydieresis -20 +KPX Y A -110 +KPX Y Aacute -110 +KPX Y Abreve -110 +KPX Y Acircumflex -110 +KPX Y Adieresis -110 +KPX Y Agrave -110 +KPX Y Amacron -110 +KPX Y Aogonek -110 +KPX Y Aring -110 +KPX Y Atilde -110 +KPX Y O -85 +KPX Y Oacute -85 +KPX Y Ocircumflex -85 +KPX Y Odieresis -85 +KPX Y Ograve -85 +KPX Y Ohungarumlaut -85 +KPX Y Omacron -85 +KPX Y Oslash -85 +KPX Y Otilde -85 +KPX Y a -140 +KPX Y aacute -140 +KPX Y abreve -70 +KPX Y acircumflex -140 +KPX Y adieresis -140 +KPX Y agrave -140 +KPX Y amacron -70 +KPX Y aogonek -140 +KPX Y aring -140 +KPX Y atilde -140 +KPX Y colon -60 +KPX Y comma -140 +KPX Y e -140 +KPX Y eacute -140 +KPX Y ecaron -140 +KPX Y ecircumflex -140 +KPX Y edieresis -140 +KPX Y edotaccent -140 +KPX Y egrave -140 +KPX Y emacron -70 +KPX Y eogonek -140 +KPX Y hyphen -140 +KPX Y i -20 +KPX Y iacute -20 +KPX Y iogonek -20 +KPX Y o -140 +KPX Y oacute -140 +KPX Y ocircumflex -140 +KPX Y odieresis -140 +KPX Y ograve -140 +KPX Y ohungarumlaut -140 +KPX Y omacron -140 +KPX Y oslash -140 +KPX Y otilde -140 +KPX Y period -140 +KPX Y semicolon -60 +KPX Y u -110 +KPX Y uacute -110 +KPX Y ucircumflex -110 +KPX Y udieresis -110 +KPX Y ugrave -110 +KPX Y uhungarumlaut -110 +KPX Y umacron -110 +KPX Y uogonek -110 +KPX Y uring -110 +KPX Yacute A -110 +KPX Yacute Aacute -110 +KPX Yacute Abreve -110 +KPX Yacute Acircumflex -110 +KPX Yacute Adieresis -110 +KPX Yacute Agrave -110 +KPX Yacute Amacron -110 +KPX Yacute Aogonek -110 +KPX Yacute Aring -110 +KPX Yacute Atilde -110 +KPX Yacute O -85 +KPX Yacute Oacute -85 +KPX Yacute Ocircumflex -85 +KPX Yacute Odieresis -85 +KPX Yacute Ograve -85 +KPX Yacute Ohungarumlaut -85 +KPX Yacute Omacron -85 +KPX Yacute Oslash -85 +KPX Yacute Otilde -85 +KPX Yacute a -140 +KPX Yacute aacute -140 +KPX Yacute abreve -70 +KPX Yacute acircumflex -140 +KPX Yacute adieresis -140 +KPX Yacute agrave -140 +KPX Yacute amacron -70 +KPX Yacute aogonek -140 +KPX Yacute aring -140 +KPX Yacute atilde -70 +KPX Yacute colon -60 +KPX Yacute comma -140 +KPX Yacute e -140 +KPX Yacute eacute -140 +KPX Yacute ecaron -140 +KPX Yacute ecircumflex -140 +KPX Yacute edieresis -140 +KPX Yacute edotaccent -140 +KPX Yacute egrave -140 +KPX Yacute emacron -70 +KPX Yacute eogonek -140 +KPX Yacute hyphen -140 +KPX Yacute i -20 +KPX Yacute iacute -20 +KPX Yacute iogonek -20 +KPX Yacute o -140 +KPX Yacute oacute -140 +KPX Yacute ocircumflex -140 +KPX Yacute odieresis -140 +KPX Yacute ograve -140 +KPX Yacute ohungarumlaut -140 +KPX Yacute omacron -70 +KPX Yacute oslash -140 +KPX Yacute otilde -140 +KPX Yacute period -140 +KPX Yacute semicolon -60 +KPX Yacute u -110 +KPX Yacute uacute -110 +KPX Yacute ucircumflex -110 +KPX Yacute udieresis -110 +KPX Yacute ugrave -110 +KPX Yacute uhungarumlaut -110 +KPX Yacute umacron -110 +KPX Yacute uogonek -110 +KPX Yacute uring -110 +KPX Ydieresis A -110 +KPX Ydieresis Aacute -110 +KPX Ydieresis Abreve -110 +KPX Ydieresis Acircumflex -110 +KPX Ydieresis Adieresis -110 +KPX Ydieresis Agrave -110 +KPX Ydieresis Amacron -110 +KPX Ydieresis Aogonek -110 +KPX Ydieresis Aring -110 +KPX Ydieresis Atilde -110 +KPX Ydieresis O -85 +KPX Ydieresis Oacute -85 +KPX Ydieresis Ocircumflex -85 +KPX Ydieresis Odieresis -85 +KPX Ydieresis Ograve -85 +KPX Ydieresis Ohungarumlaut -85 +KPX Ydieresis Omacron -85 +KPX Ydieresis Oslash -85 +KPX Ydieresis Otilde -85 +KPX Ydieresis a -140 +KPX Ydieresis aacute -140 +KPX Ydieresis abreve -70 +KPX Ydieresis acircumflex -140 +KPX Ydieresis adieresis -140 +KPX Ydieresis agrave -140 +KPX Ydieresis amacron -70 +KPX Ydieresis aogonek -140 +KPX Ydieresis aring -140 +KPX Ydieresis atilde -70 +KPX Ydieresis colon -60 +KPX Ydieresis comma -140 +KPX Ydieresis e -140 +KPX Ydieresis eacute -140 +KPX Ydieresis ecaron -140 +KPX Ydieresis ecircumflex -140 +KPX Ydieresis edieresis -140 +KPX Ydieresis edotaccent -140 +KPX Ydieresis egrave -140 +KPX Ydieresis emacron -70 +KPX Ydieresis eogonek -140 +KPX Ydieresis hyphen -140 +KPX Ydieresis i -20 +KPX Ydieresis iacute -20 +KPX Ydieresis iogonek -20 +KPX Ydieresis o -140 +KPX Ydieresis oacute -140 +KPX Ydieresis ocircumflex -140 +KPX Ydieresis odieresis -140 +KPX Ydieresis ograve -140 +KPX Ydieresis ohungarumlaut -140 +KPX Ydieresis omacron -140 +KPX Ydieresis oslash -140 +KPX Ydieresis otilde -140 +KPX Ydieresis period -140 +KPX Ydieresis semicolon -60 +KPX Ydieresis u -110 +KPX Ydieresis uacute -110 +KPX Ydieresis ucircumflex -110 +KPX Ydieresis udieresis -110 +KPX Ydieresis ugrave -110 +KPX Ydieresis uhungarumlaut -110 +KPX Ydieresis umacron -110 +KPX Ydieresis uogonek -110 +KPX Ydieresis uring -110 +KPX a v -20 +KPX a w -20 +KPX a y -30 +KPX a yacute -30 +KPX a ydieresis -30 +KPX aacute v -20 +KPX aacute w -20 +KPX aacute y -30 +KPX aacute yacute -30 +KPX aacute ydieresis -30 +KPX abreve v -20 +KPX abreve w -20 +KPX abreve y -30 +KPX abreve yacute -30 +KPX abreve ydieresis -30 +KPX acircumflex v -20 +KPX acircumflex w -20 +KPX acircumflex y -30 +KPX acircumflex yacute -30 +KPX acircumflex ydieresis -30 +KPX adieresis v -20 +KPX adieresis w -20 +KPX adieresis y -30 +KPX adieresis yacute -30 +KPX adieresis ydieresis -30 +KPX agrave v -20 +KPX agrave w -20 +KPX agrave y -30 +KPX agrave yacute -30 +KPX agrave ydieresis -30 +KPX amacron v -20 +KPX amacron w -20 +KPX amacron y -30 +KPX amacron yacute -30 +KPX amacron ydieresis -30 +KPX aogonek v -20 +KPX aogonek w -20 +KPX aogonek y -30 +KPX aogonek yacute -30 +KPX aogonek ydieresis -30 +KPX aring v -20 +KPX aring w -20 +KPX aring y -30 +KPX aring yacute -30 +KPX aring ydieresis -30 +KPX atilde v -20 +KPX atilde w -20 +KPX atilde y -30 +KPX atilde yacute -30 +KPX atilde ydieresis -30 +KPX b b -10 +KPX b comma -40 +KPX b l -20 +KPX b lacute -20 +KPX b lcommaaccent -20 +KPX b lslash -20 +KPX b period -40 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX b v -20 +KPX b y -20 +KPX b yacute -20 +KPX b ydieresis -20 +KPX c comma -15 +KPX c k -20 +KPX c kcommaaccent -20 +KPX cacute comma -15 +KPX cacute k -20 +KPX cacute kcommaaccent -20 +KPX ccaron comma -15 +KPX ccaron k -20 +KPX ccaron kcommaaccent -20 +KPX ccedilla comma -15 +KPX ccedilla k -20 +KPX ccedilla kcommaaccent -20 +KPX colon space -50 +KPX comma quotedblright -100 +KPX comma quoteright -100 +KPX e comma -15 +KPX e period -15 +KPX e v -30 +KPX e w -20 +KPX e x -30 +KPX e y -20 +KPX e yacute -20 +KPX e ydieresis -20 +KPX eacute comma -15 +KPX eacute period -15 +KPX eacute v -30 +KPX eacute w -20 +KPX eacute x -30 +KPX eacute y -20 +KPX eacute yacute -20 +KPX eacute ydieresis -20 +KPX ecaron comma -15 +KPX ecaron period -15 +KPX ecaron v -30 +KPX ecaron w -20 +KPX ecaron x -30 +KPX ecaron y -20 +KPX ecaron yacute -20 +KPX ecaron ydieresis -20 +KPX ecircumflex comma -15 +KPX ecircumflex period -15 +KPX ecircumflex v -30 +KPX ecircumflex w -20 +KPX ecircumflex x -30 +KPX ecircumflex y -20 +KPX ecircumflex yacute -20 +KPX ecircumflex ydieresis -20 +KPX edieresis comma -15 +KPX edieresis period -15 +KPX edieresis v -30 +KPX edieresis w -20 +KPX edieresis x -30 +KPX edieresis y -20 +KPX edieresis yacute -20 +KPX edieresis ydieresis -20 +KPX edotaccent comma -15 +KPX edotaccent period -15 +KPX edotaccent v -30 +KPX edotaccent w -20 +KPX edotaccent x -30 +KPX edotaccent y -20 +KPX edotaccent yacute -20 +KPX edotaccent ydieresis -20 +KPX egrave comma -15 +KPX egrave period -15 +KPX egrave v -30 +KPX egrave w -20 +KPX egrave x -30 +KPX egrave y -20 +KPX egrave yacute -20 +KPX egrave ydieresis -20 +KPX emacron comma -15 +KPX emacron period -15 +KPX emacron v -30 +KPX emacron w -20 +KPX emacron x -30 +KPX emacron y -20 +KPX emacron yacute -20 +KPX emacron ydieresis -20 +KPX eogonek comma -15 +KPX eogonek period -15 +KPX eogonek v -30 +KPX eogonek w -20 +KPX eogonek x -30 +KPX eogonek y -20 +KPX eogonek yacute -20 +KPX eogonek ydieresis -20 +KPX f a -30 +KPX f aacute -30 +KPX f abreve -30 +KPX f acircumflex -30 +KPX f adieresis -30 +KPX f agrave -30 +KPX f amacron -30 +KPX f aogonek -30 +KPX f aring -30 +KPX f atilde -30 +KPX f comma -30 +KPX f dotlessi -28 +KPX f e -30 +KPX f eacute -30 +KPX f ecaron -30 +KPX f ecircumflex -30 +KPX f edieresis -30 +KPX f edotaccent -30 +KPX f egrave -30 +KPX f emacron -30 +KPX f eogonek -30 +KPX f o -30 +KPX f oacute -30 +KPX f ocircumflex -30 +KPX f odieresis -30 +KPX f ograve -30 +KPX f ohungarumlaut -30 +KPX f omacron -30 +KPX f oslash -30 +KPX f otilde -30 +KPX f period -30 +KPX f quotedblright 60 +KPX f quoteright 50 +KPX g r -10 +KPX g racute -10 +KPX g rcaron -10 +KPX g rcommaaccent -10 +KPX gbreve r -10 +KPX gbreve racute -10 +KPX gbreve rcaron -10 +KPX gbreve rcommaaccent -10 +KPX gcommaaccent r -10 +KPX gcommaaccent racute -10 +KPX gcommaaccent rcaron -10 +KPX gcommaaccent rcommaaccent -10 +KPX h y -30 +KPX h yacute -30 +KPX h ydieresis -30 +KPX k e -20 +KPX k eacute -20 +KPX k ecaron -20 +KPX k ecircumflex -20 +KPX k edieresis -20 +KPX k edotaccent -20 +KPX k egrave -20 +KPX k emacron -20 +KPX k eogonek -20 +KPX k o -20 +KPX k oacute -20 +KPX k ocircumflex -20 +KPX k odieresis -20 +KPX k ograve -20 +KPX k ohungarumlaut -20 +KPX k omacron -20 +KPX k oslash -20 +KPX k otilde -20 +KPX kcommaaccent e -20 +KPX kcommaaccent eacute -20 +KPX kcommaaccent ecaron -20 +KPX kcommaaccent ecircumflex -20 +KPX kcommaaccent edieresis -20 +KPX kcommaaccent edotaccent -20 +KPX kcommaaccent egrave -20 +KPX kcommaaccent emacron -20 +KPX kcommaaccent eogonek -20 +KPX kcommaaccent o -20 +KPX kcommaaccent oacute -20 +KPX kcommaaccent ocircumflex -20 +KPX kcommaaccent odieresis -20 +KPX kcommaaccent ograve -20 +KPX kcommaaccent ohungarumlaut -20 +KPX kcommaaccent omacron -20 +KPX kcommaaccent oslash -20 +KPX kcommaaccent otilde -20 +KPX m u -10 +KPX m uacute -10 +KPX m ucircumflex -10 +KPX m udieresis -10 +KPX m ugrave -10 +KPX m uhungarumlaut -10 +KPX m umacron -10 +KPX m uogonek -10 +KPX m uring -10 +KPX m y -15 +KPX m yacute -15 +KPX m ydieresis -15 +KPX n u -10 +KPX n uacute -10 +KPX n ucircumflex -10 +KPX n udieresis -10 +KPX n ugrave -10 +KPX n uhungarumlaut -10 +KPX n umacron -10 +KPX n uogonek -10 +KPX n uring -10 +KPX n v -20 +KPX n y -15 +KPX n yacute -15 +KPX n ydieresis -15 +KPX nacute u -10 +KPX nacute uacute -10 +KPX nacute ucircumflex -10 +KPX nacute udieresis -10 +KPX nacute ugrave -10 +KPX nacute uhungarumlaut -10 +KPX nacute umacron -10 +KPX nacute uogonek -10 +KPX nacute uring -10 +KPX nacute v -20 +KPX nacute y -15 +KPX nacute yacute -15 +KPX nacute ydieresis -15 +KPX ncaron u -10 +KPX ncaron uacute -10 +KPX ncaron ucircumflex -10 +KPX ncaron udieresis -10 +KPX ncaron ugrave -10 +KPX ncaron uhungarumlaut -10 +KPX ncaron umacron -10 +KPX ncaron uogonek -10 +KPX ncaron uring -10 +KPX ncaron v -20 +KPX ncaron y -15 +KPX ncaron yacute -15 +KPX ncaron ydieresis -15 +KPX ncommaaccent u -10 +KPX ncommaaccent uacute -10 +KPX ncommaaccent ucircumflex -10 +KPX ncommaaccent udieresis -10 +KPX ncommaaccent ugrave -10 +KPX ncommaaccent uhungarumlaut -10 +KPX ncommaaccent umacron -10 +KPX ncommaaccent uogonek -10 +KPX ncommaaccent uring -10 +KPX ncommaaccent v -20 +KPX ncommaaccent y -15 +KPX ncommaaccent yacute -15 +KPX ncommaaccent ydieresis -15 +KPX ntilde u -10 +KPX ntilde uacute -10 +KPX ntilde ucircumflex -10 +KPX ntilde udieresis -10 +KPX ntilde ugrave -10 +KPX ntilde uhungarumlaut -10 +KPX ntilde umacron -10 +KPX ntilde uogonek -10 +KPX ntilde uring -10 +KPX ntilde v -20 +KPX ntilde y -15 +KPX ntilde yacute -15 +KPX ntilde ydieresis -15 +KPX o comma -40 +KPX o period -40 +KPX o v -15 +KPX o w -15 +KPX o x -30 +KPX o y -30 +KPX o yacute -30 +KPX o ydieresis -30 +KPX oacute comma -40 +KPX oacute period -40 +KPX oacute v -15 +KPX oacute w -15 +KPX oacute x -30 +KPX oacute y -30 +KPX oacute yacute -30 +KPX oacute ydieresis -30 +KPX ocircumflex comma -40 +KPX ocircumflex period -40 +KPX ocircumflex v -15 +KPX ocircumflex w -15 +KPX ocircumflex x -30 +KPX ocircumflex y -30 +KPX ocircumflex yacute -30 +KPX ocircumflex ydieresis -30 +KPX odieresis comma -40 +KPX odieresis period -40 +KPX odieresis v -15 +KPX odieresis w -15 +KPX odieresis x -30 +KPX odieresis y -30 +KPX odieresis yacute -30 +KPX odieresis ydieresis -30 +KPX ograve comma -40 +KPX ograve period -40 +KPX ograve v -15 +KPX ograve w -15 +KPX ograve x -30 +KPX ograve y -30 +KPX ograve yacute -30 +KPX ograve ydieresis -30 +KPX ohungarumlaut comma -40 +KPX ohungarumlaut period -40 +KPX ohungarumlaut v -15 +KPX ohungarumlaut w -15 +KPX ohungarumlaut x -30 +KPX ohungarumlaut y -30 +KPX ohungarumlaut yacute -30 +KPX ohungarumlaut ydieresis -30 +KPX omacron comma -40 +KPX omacron period -40 +KPX omacron v -15 +KPX omacron w -15 +KPX omacron x -30 +KPX omacron y -30 +KPX omacron yacute -30 +KPX omacron ydieresis -30 +KPX oslash a -55 +KPX oslash aacute -55 +KPX oslash abreve -55 +KPX oslash acircumflex -55 +KPX oslash adieresis -55 +KPX oslash agrave -55 +KPX oslash amacron -55 +KPX oslash aogonek -55 +KPX oslash aring -55 +KPX oslash atilde -55 +KPX oslash b -55 +KPX oslash c -55 +KPX oslash cacute -55 +KPX oslash ccaron -55 +KPX oslash ccedilla -55 +KPX oslash comma -95 +KPX oslash d -55 +KPX oslash dcroat -55 +KPX oslash e -55 +KPX oslash eacute -55 +KPX oslash ecaron -55 +KPX oslash ecircumflex -55 +KPX oslash edieresis -55 +KPX oslash edotaccent -55 +KPX oslash egrave -55 +KPX oslash emacron -55 +KPX oslash eogonek -55 +KPX oslash f -55 +KPX oslash g -55 +KPX oslash gbreve -55 +KPX oslash gcommaaccent -55 +KPX oslash h -55 +KPX oslash i -55 +KPX oslash iacute -55 +KPX oslash icircumflex -55 +KPX oslash idieresis -55 +KPX oslash igrave -55 +KPX oslash imacron -55 +KPX oslash iogonek -55 +KPX oslash j -55 +KPX oslash k -55 +KPX oslash kcommaaccent -55 +KPX oslash l -55 +KPX oslash lacute -55 +KPX oslash lcommaaccent -55 +KPX oslash lslash -55 +KPX oslash m -55 +KPX oslash n -55 +KPX oslash nacute -55 +KPX oslash ncaron -55 +KPX oslash ncommaaccent -55 +KPX oslash ntilde -55 +KPX oslash o -55 +KPX oslash oacute -55 +KPX oslash ocircumflex -55 +KPX oslash odieresis -55 +KPX oslash ograve -55 +KPX oslash ohungarumlaut -55 +KPX oslash omacron -55 +KPX oslash oslash -55 +KPX oslash otilde -55 +KPX oslash p -55 +KPX oslash period -95 +KPX oslash q -55 +KPX oslash r -55 +KPX oslash racute -55 +KPX oslash rcaron -55 +KPX oslash rcommaaccent -55 +KPX oslash s -55 +KPX oslash sacute -55 +KPX oslash scaron -55 +KPX oslash scedilla -55 +KPX oslash scommaaccent -55 +KPX oslash t -55 +KPX oslash tcommaaccent -55 +KPX oslash u -55 +KPX oslash uacute -55 +KPX oslash ucircumflex -55 +KPX oslash udieresis -55 +KPX oslash ugrave -55 +KPX oslash uhungarumlaut -55 +KPX oslash umacron -55 +KPX oslash uogonek -55 +KPX oslash uring -55 +KPX oslash v -70 +KPX oslash w -70 +KPX oslash x -85 +KPX oslash y -70 +KPX oslash yacute -70 +KPX oslash ydieresis -70 +KPX oslash z -55 +KPX oslash zacute -55 +KPX oslash zcaron -55 +KPX oslash zdotaccent -55 +KPX otilde comma -40 +KPX otilde period -40 +KPX otilde v -15 +KPX otilde w -15 +KPX otilde x -30 +KPX otilde y -30 +KPX otilde yacute -30 +KPX otilde ydieresis -30 +KPX p comma -35 +KPX p period -35 +KPX p y -30 +KPX p yacute -30 +KPX p ydieresis -30 +KPX period quotedblright -100 +KPX period quoteright -100 +KPX period space -60 +KPX quotedblright space -40 +KPX quoteleft quoteleft -57 +KPX quoteright d -50 +KPX quoteright dcroat -50 +KPX quoteright quoteright -57 +KPX quoteright r -50 +KPX quoteright racute -50 +KPX quoteright rcaron -50 +KPX quoteright rcommaaccent -50 +KPX quoteright s -50 +KPX quoteright sacute -50 +KPX quoteright scaron -50 +KPX quoteright scedilla -50 +KPX quoteright scommaaccent -50 +KPX quoteright space -70 +KPX r a -10 +KPX r aacute -10 +KPX r abreve -10 +KPX r acircumflex -10 +KPX r adieresis -10 +KPX r agrave -10 +KPX r amacron -10 +KPX r aogonek -10 +KPX r aring -10 +KPX r atilde -10 +KPX r colon 30 +KPX r comma -50 +KPX r i 15 +KPX r iacute 15 +KPX r icircumflex 15 +KPX r idieresis 15 +KPX r igrave 15 +KPX r imacron 15 +KPX r iogonek 15 +KPX r k 15 +KPX r kcommaaccent 15 +KPX r l 15 +KPX r lacute 15 +KPX r lcommaaccent 15 +KPX r lslash 15 +KPX r m 25 +KPX r n 25 +KPX r nacute 25 +KPX r ncaron 25 +KPX r ncommaaccent 25 +KPX r ntilde 25 +KPX r p 30 +KPX r period -50 +KPX r semicolon 30 +KPX r t 40 +KPX r tcommaaccent 40 +KPX r u 15 +KPX r uacute 15 +KPX r ucircumflex 15 +KPX r udieresis 15 +KPX r ugrave 15 +KPX r uhungarumlaut 15 +KPX r umacron 15 +KPX r uogonek 15 +KPX r uring 15 +KPX r v 30 +KPX r y 30 +KPX r yacute 30 +KPX r ydieresis 30 +KPX racute a -10 +KPX racute aacute -10 +KPX racute abreve -10 +KPX racute acircumflex -10 +KPX racute adieresis -10 +KPX racute agrave -10 +KPX racute amacron -10 +KPX racute aogonek -10 +KPX racute aring -10 +KPX racute atilde -10 +KPX racute colon 30 +KPX racute comma -50 +KPX racute i 15 +KPX racute iacute 15 +KPX racute icircumflex 15 +KPX racute idieresis 15 +KPX racute igrave 15 +KPX racute imacron 15 +KPX racute iogonek 15 +KPX racute k 15 +KPX racute kcommaaccent 15 +KPX racute l 15 +KPX racute lacute 15 +KPX racute lcommaaccent 15 +KPX racute lslash 15 +KPX racute m 25 +KPX racute n 25 +KPX racute nacute 25 +KPX racute ncaron 25 +KPX racute ncommaaccent 25 +KPX racute ntilde 25 +KPX racute p 30 +KPX racute period -50 +KPX racute semicolon 30 +KPX racute t 40 +KPX racute tcommaaccent 40 +KPX racute u 15 +KPX racute uacute 15 +KPX racute ucircumflex 15 +KPX racute udieresis 15 +KPX racute ugrave 15 +KPX racute uhungarumlaut 15 +KPX racute umacron 15 +KPX racute uogonek 15 +KPX racute uring 15 +KPX racute v 30 +KPX racute y 30 +KPX racute yacute 30 +KPX racute ydieresis 30 +KPX rcaron a -10 +KPX rcaron aacute -10 +KPX rcaron abreve -10 +KPX rcaron acircumflex -10 +KPX rcaron adieresis -10 +KPX rcaron agrave -10 +KPX rcaron amacron -10 +KPX rcaron aogonek -10 +KPX rcaron aring -10 +KPX rcaron atilde -10 +KPX rcaron colon 30 +KPX rcaron comma -50 +KPX rcaron i 15 +KPX rcaron iacute 15 +KPX rcaron icircumflex 15 +KPX rcaron idieresis 15 +KPX rcaron igrave 15 +KPX rcaron imacron 15 +KPX rcaron iogonek 15 +KPX rcaron k 15 +KPX rcaron kcommaaccent 15 +KPX rcaron l 15 +KPX rcaron lacute 15 +KPX rcaron lcommaaccent 15 +KPX rcaron lslash 15 +KPX rcaron m 25 +KPX rcaron n 25 +KPX rcaron nacute 25 +KPX rcaron ncaron 25 +KPX rcaron ncommaaccent 25 +KPX rcaron ntilde 25 +KPX rcaron p 30 +KPX rcaron period -50 +KPX rcaron semicolon 30 +KPX rcaron t 40 +KPX rcaron tcommaaccent 40 +KPX rcaron u 15 +KPX rcaron uacute 15 +KPX rcaron ucircumflex 15 +KPX rcaron udieresis 15 +KPX rcaron ugrave 15 +KPX rcaron uhungarumlaut 15 +KPX rcaron umacron 15 +KPX rcaron uogonek 15 +KPX rcaron uring 15 +KPX rcaron v 30 +KPX rcaron y 30 +KPX rcaron yacute 30 +KPX rcaron ydieresis 30 +KPX rcommaaccent a -10 +KPX rcommaaccent aacute -10 +KPX rcommaaccent abreve -10 +KPX rcommaaccent acircumflex -10 +KPX rcommaaccent adieresis -10 +KPX rcommaaccent agrave -10 +KPX rcommaaccent amacron -10 +KPX rcommaaccent aogonek -10 +KPX rcommaaccent aring -10 +KPX rcommaaccent atilde -10 +KPX rcommaaccent colon 30 +KPX rcommaaccent comma -50 +KPX rcommaaccent i 15 +KPX rcommaaccent iacute 15 +KPX rcommaaccent icircumflex 15 +KPX rcommaaccent idieresis 15 +KPX rcommaaccent igrave 15 +KPX rcommaaccent imacron 15 +KPX rcommaaccent iogonek 15 +KPX rcommaaccent k 15 +KPX rcommaaccent kcommaaccent 15 +KPX rcommaaccent l 15 +KPX rcommaaccent lacute 15 +KPX rcommaaccent lcommaaccent 15 +KPX rcommaaccent lslash 15 +KPX rcommaaccent m 25 +KPX rcommaaccent n 25 +KPX rcommaaccent nacute 25 +KPX rcommaaccent ncaron 25 +KPX rcommaaccent ncommaaccent 25 +KPX rcommaaccent ntilde 25 +KPX rcommaaccent p 30 +KPX rcommaaccent period -50 +KPX rcommaaccent semicolon 30 +KPX rcommaaccent t 40 +KPX rcommaaccent tcommaaccent 40 +KPX rcommaaccent u 15 +KPX rcommaaccent uacute 15 +KPX rcommaaccent ucircumflex 15 +KPX rcommaaccent udieresis 15 +KPX rcommaaccent ugrave 15 +KPX rcommaaccent uhungarumlaut 15 +KPX rcommaaccent umacron 15 +KPX rcommaaccent uogonek 15 +KPX rcommaaccent uring 15 +KPX rcommaaccent v 30 +KPX rcommaaccent y 30 +KPX rcommaaccent yacute 30 +KPX rcommaaccent ydieresis 30 +KPX s comma -15 +KPX s period -15 +KPX s w -30 +KPX sacute comma -15 +KPX sacute period -15 +KPX sacute w -30 +KPX scaron comma -15 +KPX scaron period -15 +KPX scaron w -30 +KPX scedilla comma -15 +KPX scedilla period -15 +KPX scedilla w -30 +KPX scommaaccent comma -15 +KPX scommaaccent period -15 +KPX scommaaccent w -30 +KPX semicolon space -50 +KPX space T -50 +KPX space Tcaron -50 +KPX space Tcommaaccent -50 +KPX space V -50 +KPX space W -40 +KPX space Y -90 +KPX space Yacute -90 +KPX space Ydieresis -90 +KPX space quotedblleft -30 +KPX space quoteleft -60 +KPX v a -25 +KPX v aacute -25 +KPX v abreve -25 +KPX v acircumflex -25 +KPX v adieresis -25 +KPX v agrave -25 +KPX v amacron -25 +KPX v aogonek -25 +KPX v aring -25 +KPX v atilde -25 +KPX v comma -80 +KPX v e -25 +KPX v eacute -25 +KPX v ecaron -25 +KPX v ecircumflex -25 +KPX v edieresis -25 +KPX v edotaccent -25 +KPX v egrave -25 +KPX v emacron -25 +KPX v eogonek -25 +KPX v o -25 +KPX v oacute -25 +KPX v ocircumflex -25 +KPX v odieresis -25 +KPX v ograve -25 +KPX v ohungarumlaut -25 +KPX v omacron -25 +KPX v oslash -25 +KPX v otilde -25 +KPX v period -80 +KPX w a -15 +KPX w aacute -15 +KPX w abreve -15 +KPX w acircumflex -15 +KPX w adieresis -15 +KPX w agrave -15 +KPX w amacron -15 +KPX w aogonek -15 +KPX w aring -15 +KPX w atilde -15 +KPX w comma -60 +KPX w e -10 +KPX w eacute -10 +KPX w ecaron -10 +KPX w ecircumflex -10 +KPX w edieresis -10 +KPX w edotaccent -10 +KPX w egrave -10 +KPX w emacron -10 +KPX w eogonek -10 +KPX w o -10 +KPX w oacute -10 +KPX w ocircumflex -10 +KPX w odieresis -10 +KPX w ograve -10 +KPX w ohungarumlaut -10 +KPX w omacron -10 +KPX w oslash -10 +KPX w otilde -10 +KPX w period -60 +KPX x e -30 +KPX x eacute -30 +KPX x ecaron -30 +KPX x ecircumflex -30 +KPX x edieresis -30 +KPX x edotaccent -30 +KPX x egrave -30 +KPX x emacron -30 +KPX x eogonek -30 +KPX y a -20 +KPX y aacute -20 +KPX y abreve -20 +KPX y acircumflex -20 +KPX y adieresis -20 +KPX y agrave -20 +KPX y amacron -20 +KPX y aogonek -20 +KPX y aring -20 +KPX y atilde -20 +KPX y comma -100 +KPX y e -20 +KPX y eacute -20 +KPX y ecaron -20 +KPX y ecircumflex -20 +KPX y edieresis -20 +KPX y edotaccent -20 +KPX y egrave -20 +KPX y emacron -20 +KPX y eogonek -20 +KPX y o -20 +KPX y oacute -20 +KPX y ocircumflex -20 +KPX y odieresis -20 +KPX y ograve -20 +KPX y ohungarumlaut -20 +KPX y omacron -20 +KPX y oslash -20 +KPX y otilde -20 +KPX y period -100 +KPX yacute a -20 +KPX yacute aacute -20 +KPX yacute abreve -20 +KPX yacute acircumflex -20 +KPX yacute adieresis -20 +KPX yacute agrave -20 +KPX yacute amacron -20 +KPX yacute aogonek -20 +KPX yacute aring -20 +KPX yacute atilde -20 +KPX yacute comma -100 +KPX yacute e -20 +KPX yacute eacute -20 +KPX yacute ecaron -20 +KPX yacute ecircumflex -20 +KPX yacute edieresis -20 +KPX yacute edotaccent -20 +KPX yacute egrave -20 +KPX yacute emacron -20 +KPX yacute eogonek -20 +KPX yacute o -20 +KPX yacute oacute -20 +KPX yacute ocircumflex -20 +KPX yacute odieresis -20 +KPX yacute ograve -20 +KPX yacute ohungarumlaut -20 +KPX yacute omacron -20 +KPX yacute oslash -20 +KPX yacute otilde -20 +KPX yacute period -100 +KPX ydieresis a -20 +KPX ydieresis aacute -20 +KPX ydieresis abreve -20 +KPX ydieresis acircumflex -20 +KPX ydieresis adieresis -20 +KPX ydieresis agrave -20 +KPX ydieresis amacron -20 +KPX ydieresis aogonek -20 +KPX ydieresis aring -20 +KPX ydieresis atilde -20 +KPX ydieresis comma -100 +KPX ydieresis e -20 +KPX ydieresis eacute -20 +KPX ydieresis ecaron -20 +KPX ydieresis ecircumflex -20 +KPX ydieresis edieresis -20 +KPX ydieresis edotaccent -20 +KPX ydieresis egrave -20 +KPX ydieresis emacron -20 +KPX ydieresis eogonek -20 +KPX ydieresis o -20 +KPX ydieresis oacute -20 +KPX ydieresis ocircumflex -20 +KPX ydieresis odieresis -20 +KPX ydieresis ograve -20 +KPX ydieresis ohungarumlaut -20 +KPX ydieresis omacron -20 +KPX ydieresis oslash -20 +KPX ydieresis otilde -20 +KPX ydieresis period -100 +KPX z e -15 +KPX z eacute -15 +KPX z ecaron -15 +KPX z ecircumflex -15 +KPX z edieresis -15 +KPX z edotaccent -15 +KPX z egrave -15 +KPX z emacron -15 +KPX z eogonek -15 +KPX z o -15 +KPX z oacute -15 +KPX z ocircumflex -15 +KPX z odieresis -15 +KPX z ograve -15 +KPX z ohungarumlaut -15 +KPX z omacron -15 +KPX z oslash -15 +KPX z otilde -15 +KPX zacute e -15 +KPX zacute eacute -15 +KPX zacute ecaron -15 +KPX zacute ecircumflex -15 +KPX zacute edieresis -15 +KPX zacute edotaccent -15 +KPX zacute egrave -15 +KPX zacute emacron -15 +KPX zacute eogonek -15 +KPX zacute o -15 +KPX zacute oacute -15 +KPX zacute ocircumflex -15 +KPX zacute odieresis -15 +KPX zacute ograve -15 +KPX zacute ohungarumlaut -15 +KPX zacute omacron -15 +KPX zacute oslash -15 +KPX zacute otilde -15 +KPX zcaron e -15 +KPX zcaron eacute -15 +KPX zcaron ecaron -15 +KPX zcaron ecircumflex -15 +KPX zcaron edieresis -15 +KPX zcaron edotaccent -15 +KPX zcaron egrave -15 +KPX zcaron emacron -15 +KPX zcaron eogonek -15 +KPX zcaron o -15 +KPX zcaron oacute -15 +KPX zcaron ocircumflex -15 +KPX zcaron odieresis -15 +KPX zcaron ograve -15 +KPX zcaron ohungarumlaut -15 +KPX zcaron omacron -15 +KPX zcaron oslash -15 +KPX zcaron otilde -15 +KPX zdotaccent e -15 +KPX zdotaccent eacute -15 +KPX zdotaccent ecaron -15 +KPX zdotaccent ecircumflex -15 +KPX zdotaccent edieresis -15 +KPX zdotaccent edotaccent -15 +KPX zdotaccent egrave -15 +KPX zdotaccent emacron -15 +KPX zdotaccent eogonek -15 +KPX zdotaccent o -15 +KPX zdotaccent oacute -15 +KPX zdotaccent ocircumflex -15 +KPX zdotaccent odieresis -15 +KPX zdotaccent ograve -15 +KPX zdotaccent ohungarumlaut -15 +KPX zdotaccent omacron -15 +KPX zdotaccent oslash -15 +KPX zdotaccent otilde -15 +EndKernPairs +EndKernData +EndFontMetrics addfile ./Core14_AFMs/Helvetica.afm hunk ./Core14_AFMs/Helvetica.afm 1 +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 12:38:23 1997 +Comment UniqueID 43054 +Comment VMusage 37069 48094 +FontName Helvetica +FullName Helvetica +FamilyName Helvetica +Weight Medium +ItalicAngle 0 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -166 -225 1000 931 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 718 +XHeight 523 +Ascender 718 +Descender -207 +StdHW 76 +StdVW 88 +StartCharMetrics 315 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 278 ; N exclam ; B 90 0 187 718 ; +C 34 ; WX 355 ; N quotedbl ; B 70 463 285 718 ; +C 35 ; WX 556 ; N numbersign ; B 28 0 529 688 ; +C 36 ; WX 556 ; N dollar ; B 32 -115 520 775 ; +C 37 ; WX 889 ; N percent ; B 39 -19 850 703 ; +C 38 ; WX 667 ; N ampersand ; B 44 -15 645 718 ; +C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ; +C 40 ; WX 333 ; N parenleft ; B 68 -207 299 733 ; +C 41 ; WX 333 ; N parenright ; B 34 -207 265 733 ; +C 42 ; WX 389 ; N asterisk ; B 39 431 349 718 ; +C 43 ; WX 584 ; N plus ; B 39 0 545 505 ; +C 44 ; WX 278 ; N comma ; B 87 -147 191 106 ; +C 45 ; WX 333 ; N hyphen ; B 44 232 289 322 ; +C 46 ; WX 278 ; N period ; B 87 0 191 106 ; +C 47 ; WX 278 ; N slash ; B -17 -19 295 737 ; +C 48 ; WX 556 ; N zero ; B 37 -19 519 703 ; +C 49 ; WX 556 ; N one ; B 101 0 359 703 ; +C 50 ; WX 556 ; N two ; B 26 0 507 703 ; +C 51 ; WX 556 ; N three ; B 34 -19 522 703 ; +C 52 ; WX 556 ; N four ; B 25 0 523 703 ; +C 53 ; WX 556 ; N five ; B 32 -19 514 688 ; +C 54 ; WX 556 ; N six ; B 38 -19 518 703 ; +C 55 ; WX 556 ; N seven ; B 37 0 523 688 ; +C 56 ; WX 556 ; N eight ; B 38 -19 517 703 ; +C 57 ; WX 556 ; N nine ; B 42 -19 514 703 ; +C 58 ; WX 278 ; N colon ; B 87 0 191 516 ; +C 59 ; WX 278 ; N semicolon ; B 87 -147 191 516 ; +C 60 ; WX 584 ; N less ; B 48 11 536 495 ; +C 61 ; WX 584 ; N equal ; B 39 115 545 390 ; +C 62 ; WX 584 ; N greater ; B 48 11 536 495 ; +C 63 ; WX 556 ; N question ; B 56 0 492 727 ; +C 64 ; WX 1015 ; N at ; B 147 -19 868 737 ; +C 65 ; WX 667 ; N A ; B 14 0 654 718 ; +C 66 ; WX 667 ; N B ; B 74 0 627 718 ; +C 67 ; WX 722 ; N C ; B 44 -19 681 737 ; +C 68 ; WX 722 ; N D ; B 81 0 674 718 ; +C 69 ; WX 667 ; N E ; B 86 0 616 718 ; +C 70 ; WX 611 ; N F ; B 86 0 583 718 ; +C 71 ; WX 778 ; N G ; B 48 -19 704 737 ; +C 72 ; WX 722 ; N H ; B 77 0 646 718 ; +C 73 ; WX 278 ; N I ; B 91 0 188 718 ; +C 74 ; WX 500 ; N J ; B 17 -19 428 718 ; +C 75 ; WX 667 ; N K ; B 76 0 663 718 ; +C 76 ; WX 556 ; N L ; B 76 0 537 718 ; +C 77 ; WX 833 ; N M ; B 73 0 761 718 ; +C 78 ; WX 722 ; N N ; B 76 0 646 718 ; +C 79 ; WX 778 ; N O ; B 39 -19 739 737 ; +C 80 ; WX 667 ; N P ; B 86 0 622 718 ; +C 81 ; WX 778 ; N Q ; B 39 -56 739 737 ; +C 82 ; WX 722 ; N R ; B 88 0 684 718 ; +C 83 ; WX 667 ; N S ; B 49 -19 620 737 ; +C 84 ; WX 611 ; N T ; B 14 0 597 718 ; +C 85 ; WX 722 ; N U ; B 79 -19 644 718 ; +C 86 ; WX 667 ; N V ; B 20 0 647 718 ; +C 87 ; WX 944 ; N W ; B 16 0 928 718 ; +C 88 ; WX 667 ; N X ; B 19 0 648 718 ; +C 89 ; WX 667 ; N Y ; B 14 0 653 718 ; +C 90 ; WX 611 ; N Z ; B 23 0 588 718 ; +C 91 ; WX 278 ; N bracketleft ; B 63 -196 250 722 ; +C 92 ; WX 278 ; N backslash ; B -17 -19 295 737 ; +C 93 ; WX 278 ; N bracketright ; B 28 -196 215 722 ; +C 94 ; WX 469 ; N asciicircum ; B -14 264 483 688 ; +C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ; +C 96 ; WX 222 ; N quoteleft ; B 65 470 169 725 ; +C 97 ; WX 556 ; N a ; B 36 -15 530 538 ; +C 98 ; WX 556 ; N b ; B 58 -15 517 718 ; +C 99 ; WX 500 ; N c ; B 30 -15 477 538 ; +C 100 ; WX 556 ; N d ; B 35 -15 499 718 ; +C 101 ; WX 556 ; N e ; B 40 -15 516 538 ; +C 102 ; WX 278 ; N f ; B 14 0 262 728 ; L i fi ; L l fl ; +C 103 ; WX 556 ; N g ; B 40 -220 499 538 ; +C 104 ; WX 556 ; N h ; B 65 0 491 718 ; +C 105 ; WX 222 ; N i ; B 67 0 155 718 ; +C 106 ; WX 222 ; N j ; B -16 -210 155 718 ; +C 107 ; WX 500 ; N k ; B 67 0 501 718 ; +C 108 ; WX 222 ; N l ; B 67 0 155 718 ; +C 109 ; WX 833 ; N m ; B 65 0 769 538 ; +C 110 ; WX 556 ; N n ; B 65 0 491 538 ; +C 111 ; WX 556 ; N o ; B 35 -14 521 538 ; +C 112 ; WX 556 ; N p ; B 58 -207 517 538 ; +C 113 ; WX 556 ; N q ; B 35 -207 494 538 ; +C 114 ; WX 333 ; N r ; B 77 0 332 538 ; +C 115 ; WX 500 ; N s ; B 32 -15 464 538 ; +C 116 ; WX 278 ; N t ; B 14 -7 257 669 ; +C 117 ; WX 556 ; N u ; B 68 -15 489 523 ; +C 118 ; WX 500 ; N v ; B 8 0 492 523 ; +C 119 ; WX 722 ; N w ; B 14 0 709 523 ; +C 120 ; WX 500 ; N x ; B 11 0 490 523 ; +C 121 ; WX 500 ; N y ; B 11 -214 489 523 ; +C 122 ; WX 500 ; N z ; B 31 0 469 523 ; +C 123 ; WX 334 ; N braceleft ; B 42 -196 292 722 ; +C 124 ; WX 260 ; N bar ; B 94 -225 167 775 ; +C 125 ; WX 334 ; N braceright ; B 42 -196 292 722 ; +C 126 ; WX 584 ; N asciitilde ; B 61 180 523 326 ; +C 161 ; WX 333 ; N exclamdown ; B 118 -195 215 523 ; +C 162 ; WX 556 ; N cent ; B 51 -115 513 623 ; +C 163 ; WX 556 ; N sterling ; B 33 -16 539 718 ; +C 164 ; WX 167 ; N fraction ; B -166 -19 333 703 ; +C 165 ; WX 556 ; N yen ; B 3 0 553 688 ; +C 166 ; WX 556 ; N florin ; B -11 -207 501 737 ; +C 167 ; WX 556 ; N section ; B 43 -191 512 737 ; +C 168 ; WX 556 ; N currency ; B 28 99 528 603 ; +C 169 ; WX 191 ; N quotesingle ; B 59 463 132 718 ; +C 170 ; WX 333 ; N quotedblleft ; B 38 470 307 725 ; +C 171 ; WX 556 ; N guillemotleft ; B 97 108 459 446 ; +C 172 ; WX 333 ; N guilsinglleft ; B 88 108 245 446 ; +C 173 ; WX 333 ; N guilsinglright ; B 88 108 245 446 ; +C 174 ; WX 500 ; N fi ; B 14 0 434 728 ; +C 175 ; WX 500 ; N fl ; B 14 0 432 728 ; +C 177 ; WX 556 ; N endash ; B 0 240 556 313 ; +C 178 ; WX 556 ; N dagger ; B 43 -159 514 718 ; +C 179 ; WX 556 ; N daggerdbl ; B 43 -159 514 718 ; +C 180 ; WX 278 ; N periodcentered ; B 77 190 202 315 ; +C 182 ; WX 537 ; N paragraph ; B 18 -173 497 718 ; +C 183 ; WX 350 ; N bullet ; B 18 202 333 517 ; +C 184 ; WX 222 ; N quotesinglbase ; B 53 -149 157 106 ; +C 185 ; WX 333 ; N quotedblbase ; B 26 -149 295 106 ; +C 186 ; WX 333 ; N quotedblright ; B 26 463 295 718 ; +C 187 ; WX 556 ; N guillemotright ; B 97 108 459 446 ; +C 188 ; WX 1000 ; N ellipsis ; B 115 0 885 106 ; +C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 703 ; +C 191 ; WX 611 ; N questiondown ; B 91 -201 527 525 ; +C 193 ; WX 333 ; N grave ; B 14 593 211 734 ; +C 194 ; WX 333 ; N acute ; B 122 593 319 734 ; +C 195 ; WX 333 ; N circumflex ; B 21 593 312 734 ; +C 196 ; WX 333 ; N tilde ; B -4 606 337 722 ; +C 197 ; WX 333 ; N macron ; B 10 627 323 684 ; +C 198 ; WX 333 ; N breve ; B 13 595 321 731 ; +C 199 ; WX 333 ; N dotaccent ; B 121 604 212 706 ; +C 200 ; WX 333 ; N dieresis ; B 40 604 293 706 ; +C 202 ; WX 333 ; N ring ; B 75 572 259 756 ; +C 203 ; WX 333 ; N cedilla ; B 45 -225 259 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 31 593 409 734 ; +C 206 ; WX 333 ; N ogonek ; B 73 -225 287 0 ; +C 207 ; WX 333 ; N caron ; B 21 593 312 734 ; +C 208 ; WX 1000 ; N emdash ; B 0 240 1000 313 ; +C 225 ; WX 1000 ; N AE ; B 8 0 951 718 ; +C 227 ; WX 370 ; N ordfeminine ; B 24 405 346 737 ; +C 232 ; WX 556 ; N Lslash ; B -20 0 537 718 ; +C 233 ; WX 778 ; N Oslash ; B 39 -19 740 737 ; +C 234 ; WX 1000 ; N OE ; B 36 -19 965 737 ; +C 235 ; WX 365 ; N ordmasculine ; B 25 405 341 737 ; +C 241 ; WX 889 ; N ae ; B 36 -15 847 538 ; +C 245 ; WX 278 ; N dotlessi ; B 95 0 183 523 ; +C 248 ; WX 222 ; N lslash ; B -20 0 242 718 ; +C 249 ; WX 611 ; N oslash ; B 28 -22 537 545 ; +C 250 ; WX 944 ; N oe ; B 35 -15 902 538 ; +C 251 ; WX 611 ; N germandbls ; B 67 -15 571 728 ; +C -1 ; WX 278 ; N Idieresis ; B 13 0 266 901 ; +C -1 ; WX 556 ; N eacute ; B 40 -15 516 734 ; +C -1 ; WX 556 ; N abreve ; B 36 -15 530 731 ; +C -1 ; WX 556 ; N uhungarumlaut ; B 68 -15 521 734 ; +C -1 ; WX 556 ; N ecaron ; B 40 -15 516 734 ; +C -1 ; WX 667 ; N Ydieresis ; B 14 0 653 901 ; +C -1 ; WX 584 ; N divide ; B 39 -19 545 524 ; +C -1 ; WX 667 ; N Yacute ; B 14 0 653 929 ; +C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ; +C -1 ; WX 556 ; N aacute ; B 36 -15 530 734 ; +C -1 ; WX 722 ; N Ucircumflex ; B 79 -19 644 929 ; +C -1 ; WX 500 ; N yacute ; B 11 -214 489 734 ; +C -1 ; WX 500 ; N scommaaccent ; B 32 -225 464 538 ; +C -1 ; WX 556 ; N ecircumflex ; B 40 -15 516 734 ; +C -1 ; WX 722 ; N Uring ; B 79 -19 644 931 ; +C -1 ; WX 722 ; N Udieresis ; B 79 -19 644 901 ; +C -1 ; WX 556 ; N aogonek ; B 36 -220 547 538 ; +C -1 ; WX 722 ; N Uacute ; B 79 -19 644 929 ; +C -1 ; WX 556 ; N uogonek ; B 68 -225 519 523 ; +C -1 ; WX 667 ; N Edieresis ; B 86 0 616 901 ; +C -1 ; WX 722 ; N Dcroat ; B 0 0 674 718 ; +C -1 ; WX 250 ; N commaaccent ; B 87 -225 181 -40 ; +C -1 ; WX 737 ; N copyright ; B -14 -19 752 737 ; +C -1 ; WX 667 ; N Emacron ; B 86 0 616 879 ; +C -1 ; WX 500 ; N ccaron ; B 30 -15 477 734 ; +C -1 ; WX 556 ; N aring ; B 36 -15 530 756 ; +C -1 ; WX 722 ; N Ncommaaccent ; B 76 -225 646 718 ; +C -1 ; WX 222 ; N lacute ; B 67 0 264 929 ; +C -1 ; WX 556 ; N agrave ; B 36 -15 530 734 ; +C -1 ; WX 611 ; N Tcommaaccent ; B 14 -225 597 718 ; +C -1 ; WX 722 ; N Cacute ; B 44 -19 681 929 ; +C -1 ; WX 556 ; N atilde ; B 36 -15 530 722 ; +C -1 ; WX 667 ; N Edotaccent ; B 86 0 616 901 ; +C -1 ; WX 500 ; N scaron ; B 32 -15 464 734 ; +C -1 ; WX 500 ; N scedilla ; B 32 -225 464 538 ; +C -1 ; WX 278 ; N iacute ; B 95 0 292 734 ; +C -1 ; WX 471 ; N lozenge ; B 10 0 462 728 ; +C -1 ; WX 722 ; N Rcaron ; B 88 0 684 929 ; +C -1 ; WX 778 ; N Gcommaaccent ; B 48 -225 704 737 ; +C -1 ; WX 556 ; N ucircumflex ; B 68 -15 489 734 ; +C -1 ; WX 556 ; N acircumflex ; B 36 -15 530 734 ; +C -1 ; WX 667 ; N Amacron ; B 14 0 654 879 ; +C -1 ; WX 333 ; N rcaron ; B 61 0 352 734 ; +C -1 ; WX 500 ; N ccedilla ; B 30 -225 477 538 ; +C -1 ; WX 611 ; N Zdotaccent ; B 23 0 588 901 ; +C -1 ; WX 667 ; N Thorn ; B 86 0 622 718 ; +C -1 ; WX 778 ; N Omacron ; B 39 -19 739 879 ; +C -1 ; WX 722 ; N Racute ; B 88 0 684 929 ; +C -1 ; WX 667 ; N Sacute ; B 49 -19 620 929 ; +C -1 ; WX 643 ; N dcaron ; B 35 -15 655 718 ; +C -1 ; WX 722 ; N Umacron ; B 79 -19 644 879 ; +C -1 ; WX 556 ; N uring ; B 68 -15 489 756 ; +C -1 ; WX 333 ; N threesuperior ; B 5 270 325 703 ; +C -1 ; WX 778 ; N Ograve ; B 39 -19 739 929 ; +C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ; +C -1 ; WX 667 ; N Abreve ; B 14 0 654 926 ; +C -1 ; WX 584 ; N multiply ; B 39 0 545 506 ; +C -1 ; WX 556 ; N uacute ; B 68 -15 489 734 ; +C -1 ; WX 611 ; N Tcaron ; B 14 0 597 929 ; +C -1 ; WX 476 ; N partialdiff ; B 13 -38 463 714 ; +C -1 ; WX 500 ; N ydieresis ; B 11 -214 489 706 ; +C -1 ; WX 722 ; N Nacute ; B 76 0 646 929 ; +C -1 ; WX 278 ; N icircumflex ; B -6 0 285 734 ; +C -1 ; WX 667 ; N Ecircumflex ; B 86 0 616 929 ; +C -1 ; WX 556 ; N adieresis ; B 36 -15 530 706 ; +C -1 ; WX 556 ; N edieresis ; B 40 -15 516 706 ; +C -1 ; WX 500 ; N cacute ; B 30 -15 477 734 ; +C -1 ; WX 556 ; N nacute ; B 65 0 491 734 ; +C -1 ; WX 556 ; N umacron ; B 68 -15 489 684 ; +C -1 ; WX 722 ; N Ncaron ; B 76 0 646 929 ; +C -1 ; WX 278 ; N Iacute ; B 91 0 292 929 ; +C -1 ; WX 584 ; N plusminus ; B 39 0 545 506 ; +C -1 ; WX 260 ; N brokenbar ; B 94 -150 167 700 ; +C -1 ; WX 737 ; N registered ; B -14 -19 752 737 ; +C -1 ; WX 778 ; N Gbreve ; B 48 -19 704 926 ; +C -1 ; WX 278 ; N Idotaccent ; B 91 0 188 901 ; +C -1 ; WX 600 ; N summation ; B 15 -10 586 706 ; +C -1 ; WX 667 ; N Egrave ; B 86 0 616 929 ; +C -1 ; WX 333 ; N racute ; B 77 0 332 734 ; +C -1 ; WX 556 ; N omacron ; B 35 -14 521 684 ; +C -1 ; WX 611 ; N Zacute ; B 23 0 588 929 ; +C -1 ; WX 611 ; N Zcaron ; B 23 0 588 929 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 523 674 ; +C -1 ; WX 722 ; N Eth ; B 0 0 674 718 ; +C -1 ; WX 722 ; N Ccedilla ; B 44 -225 681 737 ; +C -1 ; WX 222 ; N lcommaaccent ; B 67 -225 167 718 ; +C -1 ; WX 317 ; N tcaron ; B 14 -7 329 808 ; +C -1 ; WX 556 ; N eogonek ; B 40 -225 516 538 ; +C -1 ; WX 722 ; N Uogonek ; B 79 -225 644 718 ; +C -1 ; WX 667 ; N Aacute ; B 14 0 654 929 ; +C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ; +C -1 ; WX 556 ; N egrave ; B 40 -15 516 734 ; +C -1 ; WX 500 ; N zacute ; B 31 0 469 734 ; +C -1 ; WX 222 ; N iogonek ; B -31 -225 183 718 ; +C -1 ; WX 778 ; N Oacute ; B 39 -19 739 929 ; +C -1 ; WX 556 ; N oacute ; B 35 -14 521 734 ; +C -1 ; WX 556 ; N amacron ; B 36 -15 530 684 ; +C -1 ; WX 500 ; N sacute ; B 32 -15 464 734 ; +C -1 ; WX 278 ; N idieresis ; B 13 0 266 706 ; +C -1 ; WX 778 ; N Ocircumflex ; B 39 -19 739 929 ; +C -1 ; WX 722 ; N Ugrave ; B 79 -19 644 929 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 556 ; N thorn ; B 58 -207 517 718 ; +C -1 ; WX 333 ; N twosuperior ; B 4 281 323 703 ; +C -1 ; WX 778 ; N Odieresis ; B 39 -19 739 901 ; +C -1 ; WX 556 ; N mu ; B 68 -207 489 523 ; +C -1 ; WX 278 ; N igrave ; B -13 0 184 734 ; +C -1 ; WX 556 ; N ohungarumlaut ; B 35 -14 521 734 ; +C -1 ; WX 667 ; N Eogonek ; B 86 -220 633 718 ; +C -1 ; WX 556 ; N dcroat ; B 35 -15 550 718 ; +C -1 ; WX 834 ; N threequarters ; B 45 -19 810 703 ; +C -1 ; WX 667 ; N Scedilla ; B 49 -225 620 737 ; +C -1 ; WX 299 ; N lcaron ; B 67 0 311 718 ; +C -1 ; WX 667 ; N Kcommaaccent ; B 76 -225 663 718 ; +C -1 ; WX 556 ; N Lacute ; B 76 0 537 929 ; +C -1 ; WX 1000 ; N trademark ; B 46 306 903 718 ; +C -1 ; WX 556 ; N edotaccent ; B 40 -15 516 706 ; +C -1 ; WX 278 ; N Igrave ; B -13 0 188 929 ; +C -1 ; WX 278 ; N Imacron ; B -17 0 296 879 ; +C -1 ; WX 556 ; N Lcaron ; B 76 0 537 718 ; +C -1 ; WX 834 ; N onehalf ; B 43 -19 773 703 ; +C -1 ; WX 549 ; N lessequal ; B 26 0 523 674 ; +C -1 ; WX 556 ; N ocircumflex ; B 35 -14 521 734 ; +C -1 ; WX 556 ; N ntilde ; B 65 0 491 722 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 79 -19 644 929 ; +C -1 ; WX 667 ; N Eacute ; B 86 0 616 929 ; +C -1 ; WX 556 ; N emacron ; B 40 -15 516 684 ; +C -1 ; WX 556 ; N gbreve ; B 40 -220 499 731 ; +C -1 ; WX 834 ; N onequarter ; B 73 -19 756 703 ; +C -1 ; WX 667 ; N Scaron ; B 49 -19 620 929 ; +C -1 ; WX 667 ; N Scommaaccent ; B 49 -225 620 737 ; +C -1 ; WX 778 ; N Ohungarumlaut ; B 39 -19 739 929 ; +C -1 ; WX 400 ; N degree ; B 54 411 346 703 ; +C -1 ; WX 556 ; N ograve ; B 35 -14 521 734 ; +C -1 ; WX 722 ; N Ccaron ; B 44 -19 681 929 ; +C -1 ; WX 556 ; N ugrave ; B 68 -15 489 734 ; +C -1 ; WX 453 ; N radical ; B -4 -80 458 762 ; +C -1 ; WX 722 ; N Dcaron ; B 81 0 674 929 ; +C -1 ; WX 333 ; N rcommaaccent ; B 77 -225 332 538 ; +C -1 ; WX 722 ; N Ntilde ; B 76 0 646 917 ; +C -1 ; WX 556 ; N otilde ; B 35 -14 521 722 ; +C -1 ; WX 722 ; N Rcommaaccent ; B 88 -225 684 718 ; +C -1 ; WX 556 ; N Lcommaaccent ; B 76 -225 537 718 ; +C -1 ; WX 667 ; N Atilde ; B 14 0 654 917 ; +C -1 ; WX 667 ; N Aogonek ; B 14 -225 654 718 ; +C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ; +C -1 ; WX 778 ; N Otilde ; B 39 -19 739 917 ; +C -1 ; WX 500 ; N zdotaccent ; B 31 0 469 706 ; +C -1 ; WX 667 ; N Ecaron ; B 86 0 616 929 ; +C -1 ; WX 278 ; N Iogonek ; B -3 -225 211 718 ; +C -1 ; WX 500 ; N kcommaaccent ; B 67 -225 501 718 ; +C -1 ; WX 584 ; N minus ; B 39 216 545 289 ; +C -1 ; WX 278 ; N Icircumflex ; B -6 0 285 929 ; +C -1 ; WX 556 ; N ncaron ; B 65 0 491 734 ; +C -1 ; WX 278 ; N tcommaaccent ; B 14 -225 257 669 ; +C -1 ; WX 584 ; N logicalnot ; B 39 108 545 390 ; +C -1 ; WX 556 ; N odieresis ; B 35 -14 521 706 ; +C -1 ; WX 556 ; N udieresis ; B 68 -15 489 706 ; +C -1 ; WX 549 ; N notequal ; B 12 -35 537 551 ; +C -1 ; WX 556 ; N gcommaaccent ; B 40 -220 499 822 ; +C -1 ; WX 556 ; N eth ; B 35 -15 522 737 ; +C -1 ; WX 500 ; N zcaron ; B 31 0 469 734 ; +C -1 ; WX 556 ; N ncommaaccent ; B 65 -225 491 538 ; +C -1 ; WX 333 ; N onesuperior ; B 43 281 222 703 ; +C -1 ; WX 278 ; N imacron ; B 5 0 272 684 ; +C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2705 +KPX A C -30 +KPX A Cacute -30 +KPX A Ccaron -30 +KPX A Ccedilla -30 +KPX A G -30 +KPX A Gbreve -30 +KPX A Gcommaaccent -30 +KPX A O -30 +KPX A Oacute -30 +KPX A Ocircumflex -30 +KPX A Odieresis -30 +KPX A Ograve -30 +KPX A Ohungarumlaut -30 +KPX A Omacron -30 +KPX A Oslash -30 +KPX A Otilde -30 +KPX A Q -30 +KPX A T -120 +KPX A Tcaron -120 +KPX A Tcommaaccent -120 +KPX A U -50 +KPX A Uacute -50 +KPX A Ucircumflex -50 +KPX A Udieresis -50 +KPX A Ugrave -50 +KPX A Uhungarumlaut -50 +KPX A Umacron -50 +KPX A Uogonek -50 +KPX A Uring -50 +KPX A V -70 +KPX A W -50 +KPX A Y -100 +KPX A Yacute -100 +KPX A Ydieresis -100 +KPX A u -30 +KPX A uacute -30 +KPX A ucircumflex -30 +KPX A udieresis -30 +KPX A ugrave -30 +KPX A uhungarumlaut -30 +KPX A umacron -30 +KPX A uogonek -30 +KPX A uring -30 +KPX A v -40 +KPX A w -40 +KPX A y -40 +KPX A yacute -40 +KPX A ydieresis -40 +KPX Aacute C -30 +KPX Aacute Cacute -30 +KPX Aacute Ccaron -30 +KPX Aacute Ccedilla -30 +KPX Aacute G -30 +KPX Aacute Gbreve -30 +KPX Aacute Gcommaaccent -30 +KPX Aacute O -30 +KPX Aacute Oacute -30 +KPX Aacute Ocircumflex -30 +KPX Aacute Odieresis -30 +KPX Aacute Ograve -30 +KPX Aacute Ohungarumlaut -30 +KPX Aacute Omacron -30 +KPX Aacute Oslash -30 +KPX Aacute Otilde -30 +KPX Aacute Q -30 +KPX Aacute T -120 +KPX Aacute Tcaron -120 +KPX Aacute Tcommaaccent -120 +KPX Aacute U -50 +KPX Aacute Uacute -50 +KPX Aacute Ucircumflex -50 +KPX Aacute Udieresis -50 +KPX Aacute Ugrave -50 +KPX Aacute Uhungarumlaut -50 +KPX Aacute Umacron -50 +KPX Aacute Uogonek -50 +KPX Aacute Uring -50 +KPX Aacute V -70 +KPX Aacute W -50 +KPX Aacute Y -100 +KPX Aacute Yacute -100 +KPX Aacute Ydieresis -100 +KPX Aacute u -30 +KPX Aacute uacute -30 +KPX Aacute ucircumflex -30 +KPX Aacute udieresis -30 +KPX Aacute ugrave -30 +KPX Aacute uhungarumlaut -30 +KPX Aacute umacron -30 +KPX Aacute uogonek -30 +KPX Aacute uring -30 +KPX Aacute v -40 +KPX Aacute w -40 +KPX Aacute y -40 +KPX Aacute yacute -40 +KPX Aacute ydieresis -40 +KPX Abreve C -30 +KPX Abreve Cacute -30 +KPX Abreve Ccaron -30 +KPX Abreve Ccedilla -30 +KPX Abreve G -30 +KPX Abreve Gbreve -30 +KPX Abreve Gcommaaccent -30 +KPX Abreve O -30 +KPX Abreve Oacute -30 +KPX Abreve Ocircumflex -30 +KPX Abreve Odieresis -30 +KPX Abreve Ograve -30 +KPX Abreve Ohungarumlaut -30 +KPX Abreve Omacron -30 +KPX Abreve Oslash -30 +KPX Abreve Otilde -30 +KPX Abreve Q -30 +KPX Abreve T -120 +KPX Abreve Tcaron -120 +KPX Abreve Tcommaaccent -120 +KPX Abreve U -50 +KPX Abreve Uacute -50 +KPX Abreve Ucircumflex -50 +KPX Abreve Udieresis -50 +KPX Abreve Ugrave -50 +KPX Abreve Uhungarumlaut -50 +KPX Abreve Umacron -50 +KPX Abreve Uogonek -50 +KPX Abreve Uring -50 +KPX Abreve V -70 +KPX Abreve W -50 +KPX Abreve Y -100 +KPX Abreve Yacute -100 +KPX Abreve Ydieresis -100 +KPX Abreve u -30 +KPX Abreve uacute -30 +KPX Abreve ucircumflex -30 +KPX Abreve udieresis -30 +KPX Abreve ugrave -30 +KPX Abreve uhungarumlaut -30 +KPX Abreve umacron -30 +KPX Abreve uogonek -30 +KPX Abreve uring -30 +KPX Abreve v -40 +KPX Abreve w -40 +KPX Abreve y -40 +KPX Abreve yacute -40 +KPX Abreve ydieresis -40 +KPX Acircumflex C -30 +KPX Acircumflex Cacute -30 +KPX Acircumflex Ccaron -30 +KPX Acircumflex Ccedilla -30 +KPX Acircumflex G -30 +KPX Acircumflex Gbreve -30 +KPX Acircumflex Gcommaaccent -30 +KPX Acircumflex O -30 +KPX Acircumflex Oacute -30 +KPX Acircumflex Ocircumflex -30 +KPX Acircumflex Odieresis -30 +KPX Acircumflex Ograve -30 +KPX Acircumflex Ohungarumlaut -30 +KPX Acircumflex Omacron -30 +KPX Acircumflex Oslash -30 +KPX Acircumflex Otilde -30 +KPX Acircumflex Q -30 +KPX Acircumflex T -120 +KPX Acircumflex Tcaron -120 +KPX Acircumflex Tcommaaccent -120 +KPX Acircumflex U -50 +KPX Acircumflex Uacute -50 +KPX Acircumflex Ucircumflex -50 +KPX Acircumflex Udieresis -50 +KPX Acircumflex Ugrave -50 +KPX Acircumflex Uhungarumlaut -50 +KPX Acircumflex Umacron -50 +KPX Acircumflex Uogonek -50 +KPX Acircumflex Uring -50 +KPX Acircumflex V -70 +KPX Acircumflex W -50 +KPX Acircumflex Y -100 +KPX Acircumflex Yacute -100 +KPX Acircumflex Ydieresis -100 +KPX Acircumflex u -30 +KPX Acircumflex uacute -30 +KPX Acircumflex ucircumflex -30 +KPX Acircumflex udieresis -30 +KPX Acircumflex ugrave -30 +KPX Acircumflex uhungarumlaut -30 +KPX Acircumflex umacron -30 +KPX Acircumflex uogonek -30 +KPX Acircumflex uring -30 +KPX Acircumflex v -40 +KPX Acircumflex w -40 +KPX Acircumflex y -40 +KPX Acircumflex yacute -40 +KPX Acircumflex ydieresis -40 +KPX Adieresis C -30 +KPX Adieresis Cacute -30 +KPX Adieresis Ccaron -30 +KPX Adieresis Ccedilla -30 +KPX Adieresis G -30 +KPX Adieresis Gbreve -30 +KPX Adieresis Gcommaaccent -30 +KPX Adieresis O -30 +KPX Adieresis Oacute -30 +KPX Adieresis Ocircumflex -30 +KPX Adieresis Odieresis -30 +KPX Adieresis Ograve -30 +KPX Adieresis Ohungarumlaut -30 +KPX Adieresis Omacron -30 +KPX Adieresis Oslash -30 +KPX Adieresis Otilde -30 +KPX Adieresis Q -30 +KPX Adieresis T -120 +KPX Adieresis Tcaron -120 +KPX Adieresis Tcommaaccent -120 +KPX Adieresis U -50 +KPX Adieresis Uacute -50 +KPX Adieresis Ucircumflex -50 +KPX Adieresis Udieresis -50 +KPX Adieresis Ugrave -50 +KPX Adieresis Uhungarumlaut -50 +KPX Adieresis Umacron -50 +KPX Adieresis Uogonek -50 +KPX Adieresis Uring -50 +KPX Adieresis V -70 +KPX Adieresis W -50 +KPX Adieresis Y -100 +KPX Adieresis Yacute -100 +KPX Adieresis Ydieresis -100 +KPX Adieresis u -30 +KPX Adieresis uacute -30 +KPX Adieresis ucircumflex -30 +KPX Adieresis udieresis -30 +KPX Adieresis ugrave -30 +KPX Adieresis uhungarumlaut -30 +KPX Adieresis umacron -30 +KPX Adieresis uogonek -30 +KPX Adieresis uring -30 +KPX Adieresis v -40 +KPX Adieresis w -40 +KPX Adieresis y -40 +KPX Adieresis yacute -40 +KPX Adieresis ydieresis -40 +KPX Agrave C -30 +KPX Agrave Cacute -30 +KPX Agrave Ccaron -30 +KPX Agrave Ccedilla -30 +KPX Agrave G -30 +KPX Agrave Gbreve -30 +KPX Agrave Gcommaaccent -30 +KPX Agrave O -30 +KPX Agrave Oacute -30 +KPX Agrave Ocircumflex -30 +KPX Agrave Odieresis -30 +KPX Agrave Ograve -30 +KPX Agrave Ohungarumlaut -30 +KPX Agrave Omacron -30 +KPX Agrave Oslash -30 +KPX Agrave Otilde -30 +KPX Agrave Q -30 +KPX Agrave T -120 +KPX Agrave Tcaron -120 +KPX Agrave Tcommaaccent -120 +KPX Agrave U -50 +KPX Agrave Uacute -50 +KPX Agrave Ucircumflex -50 +KPX Agrave Udieresis -50 +KPX Agrave Ugrave -50 +KPX Agrave Uhungarumlaut -50 +KPX Agrave Umacron -50 +KPX Agrave Uogonek -50 +KPX Agrave Uring -50 +KPX Agrave V -70 +KPX Agrave W -50 +KPX Agrave Y -100 +KPX Agrave Yacute -100 +KPX Agrave Ydieresis -100 +KPX Agrave u -30 +KPX Agrave uacute -30 +KPX Agrave ucircumflex -30 +KPX Agrave udieresis -30 +KPX Agrave ugrave -30 +KPX Agrave uhungarumlaut -30 +KPX Agrave umacron -30 +KPX Agrave uogonek -30 +KPX Agrave uring -30 +KPX Agrave v -40 +KPX Agrave w -40 +KPX Agrave y -40 +KPX Agrave yacute -40 +KPX Agrave ydieresis -40 +KPX Amacron C -30 +KPX Amacron Cacute -30 +KPX Amacron Ccaron -30 +KPX Amacron Ccedilla -30 +KPX Amacron G -30 +KPX Amacron Gbreve -30 +KPX Amacron Gcommaaccent -30 +KPX Amacron O -30 +KPX Amacron Oacute -30 +KPX Amacron Ocircumflex -30 +KPX Amacron Odieresis -30 +KPX Amacron Ograve -30 +KPX Amacron Ohungarumlaut -30 +KPX Amacron Omacron -30 +KPX Amacron Oslash -30 +KPX Amacron Otilde -30 +KPX Amacron Q -30 +KPX Amacron T -120 +KPX Amacron Tcaron -120 +KPX Amacron Tcommaaccent -120 +KPX Amacron U -50 +KPX Amacron Uacute -50 +KPX Amacron Ucircumflex -50 +KPX Amacron Udieresis -50 +KPX Amacron Ugrave -50 +KPX Amacron Uhungarumlaut -50 +KPX Amacron Umacron -50 +KPX Amacron Uogonek -50 +KPX Amacron Uring -50 +KPX Amacron V -70 +KPX Amacron W -50 +KPX Amacron Y -100 +KPX Amacron Yacute -100 +KPX Amacron Ydieresis -100 +KPX Amacron u -30 +KPX Amacron uacute -30 +KPX Amacron ucircumflex -30 +KPX Amacron udieresis -30 +KPX Amacron ugrave -30 +KPX Amacron uhungarumlaut -30 +KPX Amacron umacron -30 +KPX Amacron uogonek -30 +KPX Amacron uring -30 +KPX Amacron v -40 +KPX Amacron w -40 +KPX Amacron y -40 +KPX Amacron yacute -40 +KPX Amacron ydieresis -40 +KPX Aogonek C -30 +KPX Aogonek Cacute -30 +KPX Aogonek Ccaron -30 +KPX Aogonek Ccedilla -30 +KPX Aogonek G -30 +KPX Aogonek Gbreve -30 +KPX Aogonek Gcommaaccent -30 +KPX Aogonek O -30 +KPX Aogonek Oacute -30 +KPX Aogonek Ocircumflex -30 +KPX Aogonek Odieresis -30 +KPX Aogonek Ograve -30 +KPX Aogonek Ohungarumlaut -30 +KPX Aogonek Omacron -30 +KPX Aogonek Oslash -30 +KPX Aogonek Otilde -30 +KPX Aogonek Q -30 +KPX Aogonek T -120 +KPX Aogonek Tcaron -120 +KPX Aogonek Tcommaaccent -120 +KPX Aogonek U -50 +KPX Aogonek Uacute -50 +KPX Aogonek Ucircumflex -50 +KPX Aogonek Udieresis -50 +KPX Aogonek Ugrave -50 +KPX Aogonek Uhungarumlaut -50 +KPX Aogonek Umacron -50 +KPX Aogonek Uogonek -50 +KPX Aogonek Uring -50 +KPX Aogonek V -70 +KPX Aogonek W -50 +KPX Aogonek Y -100 +KPX Aogonek Yacute -100 +KPX Aogonek Ydieresis -100 +KPX Aogonek u -30 +KPX Aogonek uacute -30 +KPX Aogonek ucircumflex -30 +KPX Aogonek udieresis -30 +KPX Aogonek ugrave -30 +KPX Aogonek uhungarumlaut -30 +KPX Aogonek umacron -30 +KPX Aogonek uogonek -30 +KPX Aogonek uring -30 +KPX Aogonek v -40 +KPX Aogonek w -40 +KPX Aogonek y -40 +KPX Aogonek yacute -40 +KPX Aogonek ydieresis -40 +KPX Aring C -30 +KPX Aring Cacute -30 +KPX Aring Ccaron -30 +KPX Aring Ccedilla -30 +KPX Aring G -30 +KPX Aring Gbreve -30 +KPX Aring Gcommaaccent -30 +KPX Aring O -30 +KPX Aring Oacute -30 +KPX Aring Ocircumflex -30 +KPX Aring Odieresis -30 +KPX Aring Ograve -30 +KPX Aring Ohungarumlaut -30 +KPX Aring Omacron -30 +KPX Aring Oslash -30 +KPX Aring Otilde -30 +KPX Aring Q -30 +KPX Aring T -120 +KPX Aring Tcaron -120 +KPX Aring Tcommaaccent -120 +KPX Aring U -50 +KPX Aring Uacute -50 +KPX Aring Ucircumflex -50 +KPX Aring Udieresis -50 +KPX Aring Ugrave -50 +KPX Aring Uhungarumlaut -50 +KPX Aring Umacron -50 +KPX Aring Uogonek -50 +KPX Aring Uring -50 +KPX Aring V -70 +KPX Aring W -50 +KPX Aring Y -100 +KPX Aring Yacute -100 +KPX Aring Ydieresis -100 +KPX Aring u -30 +KPX Aring uacute -30 +KPX Aring ucircumflex -30 +KPX Aring udieresis -30 +KPX Aring ugrave -30 +KPX Aring uhungarumlaut -30 +KPX Aring umacron -30 +KPX Aring uogonek -30 +KPX Aring uring -30 +KPX Aring v -40 +KPX Aring w -40 +KPX Aring y -40 +KPX Aring yacute -40 +KPX Aring ydieresis -40 +KPX Atilde C -30 +KPX Atilde Cacute -30 +KPX Atilde Ccaron -30 +KPX Atilde Ccedilla -30 +KPX Atilde G -30 +KPX Atilde Gbreve -30 +KPX Atilde Gcommaaccent -30 +KPX Atilde O -30 +KPX Atilde Oacute -30 +KPX Atilde Ocircumflex -30 +KPX Atilde Odieresis -30 +KPX Atilde Ograve -30 +KPX Atilde Ohungarumlaut -30 +KPX Atilde Omacron -30 +KPX Atilde Oslash -30 +KPX Atilde Otilde -30 +KPX Atilde Q -30 +KPX Atilde T -120 +KPX Atilde Tcaron -120 +KPX Atilde Tcommaaccent -120 +KPX Atilde U -50 +KPX Atilde Uacute -50 +KPX Atilde Ucircumflex -50 +KPX Atilde Udieresis -50 +KPX Atilde Ugrave -50 +KPX Atilde Uhungarumlaut -50 +KPX Atilde Umacron -50 +KPX Atilde Uogonek -50 +KPX Atilde Uring -50 +KPX Atilde V -70 +KPX Atilde W -50 +KPX Atilde Y -100 +KPX Atilde Yacute -100 +KPX Atilde Ydieresis -100 +KPX Atilde u -30 +KPX Atilde uacute -30 +KPX Atilde ucircumflex -30 +KPX Atilde udieresis -30 +KPX Atilde ugrave -30 +KPX Atilde uhungarumlaut -30 +KPX Atilde umacron -30 +KPX Atilde uogonek -30 +KPX Atilde uring -30 +KPX Atilde v -40 +KPX Atilde w -40 +KPX Atilde y -40 +KPX Atilde yacute -40 +KPX Atilde ydieresis -40 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX B comma -20 +KPX B period -20 +KPX C comma -30 +KPX C period -30 +KPX Cacute comma -30 +KPX Cacute period -30 +KPX Ccaron comma -30 +KPX Ccaron period -30 +KPX Ccedilla comma -30 +KPX Ccedilla period -30 +KPX D A -40 +KPX D Aacute -40 +KPX D Abreve -40 +KPX D Acircumflex -40 +KPX D Adieresis -40 +KPX D Agrave -40 +KPX D Amacron -40 +KPX D Aogonek -40 +KPX D Aring -40 +KPX D Atilde -40 +KPX D V -70 +KPX D W -40 +KPX D Y -90 +KPX D Yacute -90 +KPX D Ydieresis -90 +KPX D comma -70 +KPX D period -70 +KPX Dcaron A -40 +KPX Dcaron Aacute -40 +KPX Dcaron Abreve -40 +KPX Dcaron Acircumflex -40 +KPX Dcaron Adieresis -40 +KPX Dcaron Agrave -40 +KPX Dcaron Amacron -40 +KPX Dcaron Aogonek -40 +KPX Dcaron Aring -40 +KPX Dcaron Atilde -40 +KPX Dcaron V -70 +KPX Dcaron W -40 +KPX Dcaron Y -90 +KPX Dcaron Yacute -90 +KPX Dcaron Ydieresis -90 +KPX Dcaron comma -70 +KPX Dcaron period -70 +KPX Dcroat A -40 +KPX Dcroat Aacute -40 +KPX Dcroat Abreve -40 +KPX Dcroat Acircumflex -40 +KPX Dcroat Adieresis -40 +KPX Dcroat Agrave -40 +KPX Dcroat Amacron -40 +KPX Dcroat Aogonek -40 +KPX Dcroat Aring -40 +KPX Dcroat Atilde -40 +KPX Dcroat V -70 +KPX Dcroat W -40 +KPX Dcroat Y -90 +KPX Dcroat Yacute -90 +KPX Dcroat Ydieresis -90 +KPX Dcroat comma -70 +KPX Dcroat period -70 +KPX F A -80 +KPX F Aacute -80 +KPX F Abreve -80 +KPX F Acircumflex -80 +KPX F Adieresis -80 +KPX F Agrave -80 +KPX F Amacron -80 +KPX F Aogonek -80 +KPX F Aring -80 +KPX F Atilde -80 +KPX F a -50 +KPX F aacute -50 +KPX F abreve -50 +KPX F acircumflex -50 +KPX F adieresis -50 +KPX F agrave -50 +KPX F amacron -50 +KPX F aogonek -50 +KPX F aring -50 +KPX F atilde -50 +KPX F comma -150 +KPX F e -30 +KPX F eacute -30 +KPX F ecaron -30 +KPX F ecircumflex -30 +KPX F edieresis -30 +KPX F edotaccent -30 +KPX F egrave -30 +KPX F emacron -30 +KPX F eogonek -30 +KPX F o -30 +KPX F oacute -30 +KPX F ocircumflex -30 +KPX F odieresis -30 +KPX F ograve -30 +KPX F ohungarumlaut -30 +KPX F omacron -30 +KPX F oslash -30 +KPX F otilde -30 +KPX F period -150 +KPX F r -45 +KPX F racute -45 +KPX F rcaron -45 +KPX F rcommaaccent -45 +KPX J A -20 +KPX J Aacute -20 +KPX J Abreve -20 +KPX J Acircumflex -20 +KPX J Adieresis -20 +KPX J Agrave -20 +KPX J Amacron -20 +KPX J Aogonek -20 +KPX J Aring -20 +KPX J Atilde -20 +KPX J a -20 +KPX J aacute -20 +KPX J abreve -20 +KPX J acircumflex -20 +KPX J adieresis -20 +KPX J agrave -20 +KPX J amacron -20 +KPX J aogonek -20 +KPX J aring -20 +KPX J atilde -20 +KPX J comma -30 +KPX J period -30 +KPX J u -20 +KPX J uacute -20 +KPX J ucircumflex -20 +KPX J udieresis -20 +KPX J ugrave -20 +KPX J uhungarumlaut -20 +KPX J umacron -20 +KPX J uogonek -20 +KPX J uring -20 +KPX K O -50 +KPX K Oacute -50 +KPX K Ocircumflex -50 +KPX K Odieresis -50 +KPX K Ograve -50 +KPX K Ohungarumlaut -50 +KPX K Omacron -50 +KPX K Oslash -50 +KPX K Otilde -50 +KPX K e -40 +KPX K eacute -40 +KPX K ecaron -40 +KPX K ecircumflex -40 +KPX K edieresis -40 +KPX K edotaccent -40 +KPX K egrave -40 +KPX K emacron -40 +KPX K eogonek -40 +KPX K o -40 +KPX K oacute -40 +KPX K ocircumflex -40 +KPX K odieresis -40 +KPX K ograve -40 +KPX K ohungarumlaut -40 +KPX K omacron -40 +KPX K oslash -40 +KPX K otilde -40 +KPX K u -30 +KPX K uacute -30 +KPX K ucircumflex -30 +KPX K udieresis -30 +KPX K ugrave -30 +KPX K uhungarumlaut -30 +KPX K umacron -30 +KPX K uogonek -30 +KPX K uring -30 +KPX K y -50 +KPX K yacute -50 +KPX K ydieresis -50 +KPX Kcommaaccent O -50 +KPX Kcommaaccent Oacute -50 +KPX Kcommaaccent Ocircumflex -50 +KPX Kcommaaccent Odieresis -50 +KPX Kcommaaccent Ograve -50 +KPX Kcommaaccent Ohungarumlaut -50 +KPX Kcommaaccent Omacron -50 +KPX Kcommaaccent Oslash -50 +KPX Kcommaaccent Otilde -50 +KPX Kcommaaccent e -40 +KPX Kcommaaccent eacute -40 +KPX Kcommaaccent ecaron -40 +KPX Kcommaaccent ecircumflex -40 +KPX Kcommaaccent edieresis -40 +KPX Kcommaaccent edotaccent -40 +KPX Kcommaaccent egrave -40 +KPX Kcommaaccent emacron -40 +KPX Kcommaaccent eogonek -40 +KPX Kcommaaccent o -40 +KPX Kcommaaccent oacute -40 +KPX Kcommaaccent ocircumflex -40 +KPX Kcommaaccent odieresis -40 +KPX Kcommaaccent ograve -40 +KPX Kcommaaccent ohungarumlaut -40 +KPX Kcommaaccent omacron -40 +KPX Kcommaaccent oslash -40 +KPX Kcommaaccent otilde -40 +KPX Kcommaaccent u -30 +KPX Kcommaaccent uacute -30 +KPX Kcommaaccent ucircumflex -30 +KPX Kcommaaccent udieresis -30 +KPX Kcommaaccent ugrave -30 +KPX Kcommaaccent uhungarumlaut -30 +KPX Kcommaaccent umacron -30 +KPX Kcommaaccent uogonek -30 +KPX Kcommaaccent uring -30 +KPX Kcommaaccent y -50 +KPX Kcommaaccent yacute -50 +KPX Kcommaaccent ydieresis -50 +KPX L T -110 +KPX L Tcaron -110 +KPX L Tcommaaccent -110 +KPX L V -110 +KPX L W -70 +KPX L Y -140 +KPX L Yacute -140 +KPX L Ydieresis -140 +KPX L quotedblright -140 +KPX L quoteright -160 +KPX L y -30 +KPX L yacute -30 +KPX L ydieresis -30 +KPX Lacute T -110 +KPX Lacute Tcaron -110 +KPX Lacute Tcommaaccent -110 +KPX Lacute V -110 +KPX Lacute W -70 +KPX Lacute Y -140 +KPX Lacute Yacute -140 +KPX Lacute Ydieresis -140 +KPX Lacute quotedblright -140 +KPX Lacute quoteright -160 +KPX Lacute y -30 +KPX Lacute yacute -30 +KPX Lacute ydieresis -30 +KPX Lcaron T -110 +KPX Lcaron Tcaron -110 +KPX Lcaron Tcommaaccent -110 +KPX Lcaron V -110 +KPX Lcaron W -70 +KPX Lcaron Y -140 +KPX Lcaron Yacute -140 +KPX Lcaron Ydieresis -140 +KPX Lcaron quotedblright -140 +KPX Lcaron quoteright -160 +KPX Lcaron y -30 +KPX Lcaron yacute -30 +KPX Lcaron ydieresis -30 +KPX Lcommaaccent T -110 +KPX Lcommaaccent Tcaron -110 +KPX Lcommaaccent Tcommaaccent -110 +KPX Lcommaaccent V -110 +KPX Lcommaaccent W -70 +KPX Lcommaaccent Y -140 +KPX Lcommaaccent Yacute -140 +KPX Lcommaaccent Ydieresis -140 +KPX Lcommaaccent quotedblright -140 +KPX Lcommaaccent quoteright -160 +KPX Lcommaaccent y -30 +KPX Lcommaaccent yacute -30 +KPX Lcommaaccent ydieresis -30 +KPX Lslash T -110 +KPX Lslash Tcaron -110 +KPX Lslash Tcommaaccent -110 +KPX Lslash V -110 +KPX Lslash W -70 +KPX Lslash Y -140 +KPX Lslash Yacute -140 +KPX Lslash Ydieresis -140 +KPX Lslash quotedblright -140 +KPX Lslash quoteright -160 +KPX Lslash y -30 +KPX Lslash yacute -30 +KPX Lslash ydieresis -30 +KPX O A -20 +KPX O Aacute -20 +KPX O Abreve -20 +KPX O Acircumflex -20 +KPX O Adieresis -20 +KPX O Agrave -20 +KPX O Amacron -20 +KPX O Aogonek -20 +KPX O Aring -20 +KPX O Atilde -20 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -30 +KPX O X -60 +KPX O Y -70 +KPX O Yacute -70 +KPX O Ydieresis -70 +KPX O comma -40 +KPX O period -40 +KPX Oacute A -20 +KPX Oacute Aacute -20 +KPX Oacute Abreve -20 +KPX Oacute Acircumflex -20 +KPX Oacute Adieresis -20 +KPX Oacute Agrave -20 +KPX Oacute Amacron -20 +KPX Oacute Aogonek -20 +KPX Oacute Aring -20 +KPX Oacute Atilde -20 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -30 +KPX Oacute X -60 +KPX Oacute Y -70 +KPX Oacute Yacute -70 +KPX Oacute Ydieresis -70 +KPX Oacute comma -40 +KPX Oacute period -40 +KPX Ocircumflex A -20 +KPX Ocircumflex Aacute -20 +KPX Ocircumflex Abreve -20 +KPX Ocircumflex Acircumflex -20 +KPX Ocircumflex Adieresis -20 +KPX Ocircumflex Agrave -20 +KPX Ocircumflex Amacron -20 +KPX Ocircumflex Aogonek -20 +KPX Ocircumflex Aring -20 +KPX Ocircumflex Atilde -20 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -30 +KPX Ocircumflex X -60 +KPX Ocircumflex Y -70 +KPX Ocircumflex Yacute -70 +KPX Ocircumflex Ydieresis -70 +KPX Ocircumflex comma -40 +KPX Ocircumflex period -40 +KPX Odieresis A -20 +KPX Odieresis Aacute -20 +KPX Odieresis Abreve -20 +KPX Odieresis Acircumflex -20 +KPX Odieresis Adieresis -20 +KPX Odieresis Agrave -20 +KPX Odieresis Amacron -20 +KPX Odieresis Aogonek -20 +KPX Odieresis Aring -20 +KPX Odieresis Atilde -20 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -30 +KPX Odieresis X -60 +KPX Odieresis Y -70 +KPX Odieresis Yacute -70 +KPX Odieresis Ydieresis -70 +KPX Odieresis comma -40 +KPX Odieresis period -40 +KPX Ograve A -20 +KPX Ograve Aacute -20 +KPX Ograve Abreve -20 +KPX Ograve Acircumflex -20 +KPX Ograve Adieresis -20 +KPX Ograve Agrave -20 +KPX Ograve Amacron -20 +KPX Ograve Aogonek -20 +KPX Ograve Aring -20 +KPX Ograve Atilde -20 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -30 +KPX Ograve X -60 +KPX Ograve Y -70 +KPX Ograve Yacute -70 +KPX Ograve Ydieresis -70 +KPX Ograve comma -40 +KPX Ograve period -40 +KPX Ohungarumlaut A -20 +KPX Ohungarumlaut Aacute -20 +KPX Ohungarumlaut Abreve -20 +KPX Ohungarumlaut Acircumflex -20 +KPX Ohungarumlaut Adieresis -20 +KPX Ohungarumlaut Agrave -20 +KPX Ohungarumlaut Amacron -20 +KPX Ohungarumlaut Aogonek -20 +KPX Ohungarumlaut Aring -20 +KPX Ohungarumlaut Atilde -20 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -30 +KPX Ohungarumlaut X -60 +KPX Ohungarumlaut Y -70 +KPX Ohungarumlaut Yacute -70 +KPX Ohungarumlaut Ydieresis -70 +KPX Ohungarumlaut comma -40 +KPX Ohungarumlaut period -40 +KPX Omacron A -20 +KPX Omacron Aacute -20 +KPX Omacron Abreve -20 +KPX Omacron Acircumflex -20 +KPX Omacron Adieresis -20 +KPX Omacron Agrave -20 +KPX Omacron Amacron -20 +KPX Omacron Aogonek -20 +KPX Omacron Aring -20 +KPX Omacron Atilde -20 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -30 +KPX Omacron X -60 +KPX Omacron Y -70 +KPX Omacron Yacute -70 +KPX Omacron Ydieresis -70 +KPX Omacron comma -40 +KPX Omacron period -40 +KPX Oslash A -20 +KPX Oslash Aacute -20 +KPX Oslash Abreve -20 +KPX Oslash Acircumflex -20 +KPX Oslash Adieresis -20 +KPX Oslash Agrave -20 +KPX Oslash Amacron -20 +KPX Oslash Aogonek -20 +KPX Oslash Aring -20 +KPX Oslash Atilde -20 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -30 +KPX Oslash X -60 +KPX Oslash Y -70 +KPX Oslash Yacute -70 +KPX Oslash Ydieresis -70 +KPX Oslash comma -40 +KPX Oslash period -40 +KPX Otilde A -20 +KPX Otilde Aacute -20 +KPX Otilde Abreve -20 +KPX Otilde Acircumflex -20 +KPX Otilde Adieresis -20 +KPX Otilde Agrave -20 +KPX Otilde Amacron -20 +KPX Otilde Aogonek -20 +KPX Otilde Aring -20 +KPX Otilde Atilde -20 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -30 +KPX Otilde X -60 +KPX Otilde Y -70 +KPX Otilde Yacute -70 +KPX Otilde Ydieresis -70 +KPX Otilde comma -40 +KPX Otilde period -40 +KPX P A -120 +KPX P Aacute -120 +KPX P Abreve -120 +KPX P Acircumflex -120 +KPX P Adieresis -120 +KPX P Agrave -120 +KPX P Amacron -120 +KPX P Aogonek -120 +KPX P Aring -120 +KPX P Atilde -120 +KPX P a -40 +KPX P aacute -40 +KPX P abreve -40 +KPX P acircumflex -40 +KPX P adieresis -40 +KPX P agrave -40 +KPX P amacron -40 +KPX P aogonek -40 +KPX P aring -40 +KPX P atilde -40 +KPX P comma -180 +KPX P e -50 +KPX P eacute -50 +KPX P ecaron -50 +KPX P ecircumflex -50 +KPX P edieresis -50 +KPX P edotaccent -50 +KPX P egrave -50 +KPX P emacron -50 +KPX P eogonek -50 +KPX P o -50 +KPX P oacute -50 +KPX P ocircumflex -50 +KPX P odieresis -50 +KPX P ograve -50 +KPX P ohungarumlaut -50 +KPX P omacron -50 +KPX P oslash -50 +KPX P otilde -50 +KPX P period -180 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX R O -20 +KPX R Oacute -20 +KPX R Ocircumflex -20 +KPX R Odieresis -20 +KPX R Ograve -20 +KPX R Ohungarumlaut -20 +KPX R Omacron -20 +KPX R Oslash -20 +KPX R Otilde -20 +KPX R T -30 +KPX R Tcaron -30 +KPX R Tcommaaccent -30 +KPX R U -40 +KPX R Uacute -40 +KPX R Ucircumflex -40 +KPX R Udieresis -40 +KPX R Ugrave -40 +KPX R Uhungarumlaut -40 +KPX R Umacron -40 +KPX R Uogonek -40 +KPX R Uring -40 +KPX R V -50 +KPX R W -30 +KPX R Y -50 +KPX R Yacute -50 +KPX R Ydieresis -50 +KPX Racute O -20 +KPX Racute Oacute -20 +KPX Racute Ocircumflex -20 +KPX Racute Odieresis -20 +KPX Racute Ograve -20 +KPX Racute Ohungarumlaut -20 +KPX Racute Omacron -20 +KPX Racute Oslash -20 +KPX Racute Otilde -20 +KPX Racute T -30 +KPX Racute Tcaron -30 +KPX Racute Tcommaaccent -30 +KPX Racute U -40 +KPX Racute Uacute -40 +KPX Racute Ucircumflex -40 +KPX Racute Udieresis -40 +KPX Racute Ugrave -40 +KPX Racute Uhungarumlaut -40 +KPX Racute Umacron -40 +KPX Racute Uogonek -40 +KPX Racute Uring -40 +KPX Racute V -50 +KPX Racute W -30 +KPX Racute Y -50 +KPX Racute Yacute -50 +KPX Racute Ydieresis -50 +KPX Rcaron O -20 +KPX Rcaron Oacute -20 +KPX Rcaron Ocircumflex -20 +KPX Rcaron Odieresis -20 +KPX Rcaron Ograve -20 +KPX Rcaron Ohungarumlaut -20 +KPX Rcaron Omacron -20 +KPX Rcaron Oslash -20 +KPX Rcaron Otilde -20 +KPX Rcaron T -30 +KPX Rcaron Tcaron -30 +KPX Rcaron Tcommaaccent -30 +KPX Rcaron U -40 +KPX Rcaron Uacute -40 +KPX Rcaron Ucircumflex -40 +KPX Rcaron Udieresis -40 +KPX Rcaron Ugrave -40 +KPX Rcaron Uhungarumlaut -40 +KPX Rcaron Umacron -40 +KPX Rcaron Uogonek -40 +KPX Rcaron Uring -40 +KPX Rcaron V -50 +KPX Rcaron W -30 +KPX Rcaron Y -50 +KPX Rcaron Yacute -50 +KPX Rcaron Ydieresis -50 +KPX Rcommaaccent O -20 +KPX Rcommaaccent Oacute -20 +KPX Rcommaaccent Ocircumflex -20 +KPX Rcommaaccent Odieresis -20 +KPX Rcommaaccent Ograve -20 +KPX Rcommaaccent Ohungarumlaut -20 +KPX Rcommaaccent Omacron -20 +KPX Rcommaaccent Oslash -20 +KPX Rcommaaccent Otilde -20 +KPX Rcommaaccent T -30 +KPX Rcommaaccent Tcaron -30 +KPX Rcommaaccent Tcommaaccent -30 +KPX Rcommaaccent U -40 +KPX Rcommaaccent Uacute -40 +KPX Rcommaaccent Ucircumflex -40 +KPX Rcommaaccent Udieresis -40 +KPX Rcommaaccent Ugrave -40 +KPX Rcommaaccent Uhungarumlaut -40 +KPX Rcommaaccent Umacron -40 +KPX Rcommaaccent Uogonek -40 +KPX Rcommaaccent Uring -40 +KPX Rcommaaccent V -50 +KPX Rcommaaccent W -30 +KPX Rcommaaccent Y -50 +KPX Rcommaaccent Yacute -50 +KPX Rcommaaccent Ydieresis -50 +KPX S comma -20 +KPX S period -20 +KPX Sacute comma -20 +KPX Sacute period -20 +KPX Scaron comma -20 +KPX Scaron period -20 +KPX Scedilla comma -20 +KPX Scedilla period -20 +KPX Scommaaccent comma -20 +KPX Scommaaccent period -20 +KPX T A -120 +KPX T Aacute -120 +KPX T Abreve -120 +KPX T Acircumflex -120 +KPX T Adieresis -120 +KPX T Agrave -120 +KPX T Amacron -120 +KPX T Aogonek -120 +KPX T Aring -120 +KPX T Atilde -120 +KPX T O -40 +KPX T Oacute -40 +KPX T Ocircumflex -40 +KPX T Odieresis -40 +KPX T Ograve -40 +KPX T Ohungarumlaut -40 +KPX T Omacron -40 +KPX T Oslash -40 +KPX T Otilde -40 +KPX T a -120 +KPX T aacute -120 +KPX T abreve -60 +KPX T acircumflex -120 +KPX T adieresis -120 +KPX T agrave -120 +KPX T amacron -60 +KPX T aogonek -120 +KPX T aring -120 +KPX T atilde -60 +KPX T colon -20 +KPX T comma -120 +KPX T e -120 +KPX T eacute -120 +KPX T ecaron -120 +KPX T ecircumflex -120 +KPX T edieresis -120 +KPX T edotaccent -120 +KPX T egrave -60 +KPX T emacron -60 +KPX T eogonek -120 +KPX T hyphen -140 +KPX T o -120 +KPX T oacute -120 +KPX T ocircumflex -120 +KPX T odieresis -120 +KPX T ograve -120 +KPX T ohungarumlaut -120 +KPX T omacron -60 +KPX T oslash -120 +KPX T otilde -60 +KPX T period -120 +KPX T r -120 +KPX T racute -120 +KPX T rcaron -120 +KPX T rcommaaccent -120 +KPX T semicolon -20 +KPX T u -120 +KPX T uacute -120 +KPX T ucircumflex -120 +KPX T udieresis -120 +KPX T ugrave -120 +KPX T uhungarumlaut -120 +KPX T umacron -60 +KPX T uogonek -120 +KPX T uring -120 +KPX T w -120 +KPX T y -120 +KPX T yacute -120 +KPX T ydieresis -60 +KPX Tcaron A -120 +KPX Tcaron Aacute -120 +KPX Tcaron Abreve -120 +KPX Tcaron Acircumflex -120 +KPX Tcaron Adieresis -120 +KPX Tcaron Agrave -120 +KPX Tcaron Amacron -120 +KPX Tcaron Aogonek -120 +KPX Tcaron Aring -120 +KPX Tcaron Atilde -120 +KPX Tcaron O -40 +KPX Tcaron Oacute -40 +KPX Tcaron Ocircumflex -40 +KPX Tcaron Odieresis -40 +KPX Tcaron Ograve -40 +KPX Tcaron Ohungarumlaut -40 +KPX Tcaron Omacron -40 +KPX Tcaron Oslash -40 +KPX Tcaron Otilde -40 +KPX Tcaron a -120 +KPX Tcaron aacute -120 +KPX Tcaron abreve -60 +KPX Tcaron acircumflex -120 +KPX Tcaron adieresis -120 +KPX Tcaron agrave -120 +KPX Tcaron amacron -60 +KPX Tcaron aogonek -120 +KPX Tcaron aring -120 +KPX Tcaron atilde -60 +KPX Tcaron colon -20 +KPX Tcaron comma -120 +KPX Tcaron e -120 +KPX Tcaron eacute -120 +KPX Tcaron ecaron -120 +KPX Tcaron ecircumflex -120 +KPX Tcaron edieresis -120 +KPX Tcaron edotaccent -120 +KPX Tcaron egrave -60 +KPX Tcaron emacron -60 +KPX Tcaron eogonek -120 +KPX Tcaron hyphen -140 +KPX Tcaron o -120 +KPX Tcaron oacute -120 +KPX Tcaron ocircumflex -120 +KPX Tcaron odieresis -120 +KPX Tcaron ograve -120 +KPX Tcaron ohungarumlaut -120 +KPX Tcaron omacron -60 +KPX Tcaron oslash -120 +KPX Tcaron otilde -60 +KPX Tcaron period -120 +KPX Tcaron r -120 +KPX Tcaron racute -120 +KPX Tcaron rcaron -120 +KPX Tcaron rcommaaccent -120 +KPX Tcaron semicolon -20 +KPX Tcaron u -120 +KPX Tcaron uacute -120 +KPX Tcaron ucircumflex -120 +KPX Tcaron udieresis -120 +KPX Tcaron ugrave -120 +KPX Tcaron uhungarumlaut -120 +KPX Tcaron umacron -60 +KPX Tcaron uogonek -120 +KPX Tcaron uring -120 +KPX Tcaron w -120 +KPX Tcaron y -120 +KPX Tcaron yacute -120 +KPX Tcaron ydieresis -60 +KPX Tcommaaccent A -120 +KPX Tcommaaccent Aacute -120 +KPX Tcommaaccent Abreve -120 +KPX Tcommaaccent Acircumflex -120 +KPX Tcommaaccent Adieresis -120 +KPX Tcommaaccent Agrave -120 +KPX Tcommaaccent Amacron -120 +KPX Tcommaaccent Aogonek -120 +KPX Tcommaaccent Aring -120 +KPX Tcommaaccent Atilde -120 +KPX Tcommaaccent O -40 +KPX Tcommaaccent Oacute -40 +KPX Tcommaaccent Ocircumflex -40 +KPX Tcommaaccent Odieresis -40 +KPX Tcommaaccent Ograve -40 +KPX Tcommaaccent Ohungarumlaut -40 +KPX Tcommaaccent Omacron -40 +KPX Tcommaaccent Oslash -40 +KPX Tcommaaccent Otilde -40 +KPX Tcommaaccent a -120 +KPX Tcommaaccent aacute -120 +KPX Tcommaaccent abreve -60 +KPX Tcommaaccent acircumflex -120 +KPX Tcommaaccent adieresis -120 +KPX Tcommaaccent agrave -120 +KPX Tcommaaccent amacron -60 +KPX Tcommaaccent aogonek -120 +KPX Tcommaaccent aring -120 +KPX Tcommaaccent atilde -60 +KPX Tcommaaccent colon -20 +KPX Tcommaaccent comma -120 +KPX Tcommaaccent e -120 +KPX Tcommaaccent eacute -120 +KPX Tcommaaccent ecaron -120 +KPX Tcommaaccent ecircumflex -120 +KPX Tcommaaccent edieresis -120 +KPX Tcommaaccent edotaccent -120 +KPX Tcommaaccent egrave -60 +KPX Tcommaaccent emacron -60 +KPX Tcommaaccent eogonek -120 +KPX Tcommaaccent hyphen -140 +KPX Tcommaaccent o -120 +KPX Tcommaaccent oacute -120 +KPX Tcommaaccent ocircumflex -120 +KPX Tcommaaccent odieresis -120 +KPX Tcommaaccent ograve -120 +KPX Tcommaaccent ohungarumlaut -120 +KPX Tcommaaccent omacron -60 +KPX Tcommaaccent oslash -120 +KPX Tcommaaccent otilde -60 +KPX Tcommaaccent period -120 +KPX Tcommaaccent r -120 +KPX Tcommaaccent racute -120 +KPX Tcommaaccent rcaron -120 +KPX Tcommaaccent rcommaaccent -120 +KPX Tcommaaccent semicolon -20 +KPX Tcommaaccent u -120 +KPX Tcommaaccent uacute -120 +KPX Tcommaaccent ucircumflex -120 +KPX Tcommaaccent udieresis -120 +KPX Tcommaaccent ugrave -120 +KPX Tcommaaccent uhungarumlaut -120 +KPX Tcommaaccent umacron -60 +KPX Tcommaaccent uogonek -120 +KPX Tcommaaccent uring -120 +KPX Tcommaaccent w -120 +KPX Tcommaaccent y -120 +KPX Tcommaaccent yacute -120 +KPX Tcommaaccent ydieresis -60 +KPX U A -40 +KPX U Aacute -40 +KPX U Abreve -40 +KPX U Acircumflex -40 +KPX U Adieresis -40 +KPX U Agrave -40 +KPX U Amacron -40 +KPX U Aogonek -40 +KPX U Aring -40 +KPX U Atilde -40 +KPX U comma -40 +KPX U period -40 +KPX Uacute A -40 +KPX Uacute Aacute -40 +KPX Uacute Abreve -40 +KPX Uacute Acircumflex -40 +KPX Uacute Adieresis -40 +KPX Uacute Agrave -40 +KPX Uacute Amacron -40 +KPX Uacute Aogonek -40 +KPX Uacute Aring -40 +KPX Uacute Atilde -40 +KPX Uacute comma -40 +KPX Uacute period -40 +KPX Ucircumflex A -40 +KPX Ucircumflex Aacute -40 +KPX Ucircumflex Abreve -40 +KPX Ucircumflex Acircumflex -40 +KPX Ucircumflex Adieresis -40 +KPX Ucircumflex Agrave -40 +KPX Ucircumflex Amacron -40 +KPX Ucircumflex Aogonek -40 +KPX Ucircumflex Aring -40 +KPX Ucircumflex Atilde -40 +KPX Ucircumflex comma -40 +KPX Ucircumflex period -40 +KPX Udieresis A -40 +KPX Udieresis Aacute -40 +KPX Udieresis Abreve -40 +KPX Udieresis Acircumflex -40 +KPX Udieresis Adieresis -40 +KPX Udieresis Agrave -40 +KPX Udieresis Amacron -40 +KPX Udieresis Aogonek -40 +KPX Udieresis Aring -40 +KPX Udieresis Atilde -40 +KPX Udieresis comma -40 +KPX Udieresis period -40 +KPX Ugrave A -40 +KPX Ugrave Aacute -40 +KPX Ugrave Abreve -40 +KPX Ugrave Acircumflex -40 +KPX Ugrave Adieresis -40 +KPX Ugrave Agrave -40 +KPX Ugrave Amacron -40 +KPX Ugrave Aogonek -40 +KPX Ugrave Aring -40 +KPX Ugrave Atilde -40 +KPX Ugrave comma -40 +KPX Ugrave period -40 +KPX Uhungarumlaut A -40 +KPX Uhungarumlaut Aacute -40 +KPX Uhungarumlaut Abreve -40 +KPX Uhungarumlaut Acircumflex -40 +KPX Uhungarumlaut Adieresis -40 +KPX Uhungarumlaut Agrave -40 +KPX Uhungarumlaut Amacron -40 +KPX Uhungarumlaut Aogonek -40 +KPX Uhungarumlaut Aring -40 +KPX Uhungarumlaut Atilde -40 +KPX Uhungarumlaut comma -40 +KPX Uhungarumlaut period -40 +KPX Umacron A -40 +KPX Umacron Aacute -40 +KPX Umacron Abreve -40 +KPX Umacron Acircumflex -40 +KPX Umacron Adieresis -40 +KPX Umacron Agrave -40 +KPX Umacron Amacron -40 +KPX Umacron Aogonek -40 +KPX Umacron Aring -40 +KPX Umacron Atilde -40 +KPX Umacron comma -40 +KPX Umacron period -40 +KPX Uogonek A -40 +KPX Uogonek Aacute -40 +KPX Uogonek Abreve -40 +KPX Uogonek Acircumflex -40 +KPX Uogonek Adieresis -40 +KPX Uogonek Agrave -40 +KPX Uogonek Amacron -40 +KPX Uogonek Aogonek -40 +KPX Uogonek Aring -40 +KPX Uogonek Atilde -40 +KPX Uogonek comma -40 +KPX Uogonek period -40 +KPX Uring A -40 +KPX Uring Aacute -40 +KPX Uring Abreve -40 +KPX Uring Acircumflex -40 +KPX Uring Adieresis -40 +KPX Uring Agrave -40 +KPX Uring Amacron -40 +KPX Uring Aogonek -40 +KPX Uring Aring -40 +KPX Uring Atilde -40 +KPX Uring comma -40 +KPX Uring period -40 +KPX V A -80 +KPX V Aacute -80 +KPX V Abreve -80 +KPX V Acircumflex -80 +KPX V Adieresis -80 +KPX V Agrave -80 +KPX V Amacron -80 +KPX V Aogonek -80 +KPX V Aring -80 +KPX V Atilde -80 +KPX V G -40 +KPX V Gbreve -40 +KPX V Gcommaaccent -40 +KPX V O -40 +KPX V Oacute -40 +KPX V Ocircumflex -40 +KPX V Odieresis -40 +KPX V Ograve -40 +KPX V Ohungarumlaut -40 +KPX V Omacron -40 +KPX V Oslash -40 +KPX V Otilde -40 +KPX V a -70 +KPX V aacute -70 +KPX V abreve -70 +KPX V acircumflex -70 +KPX V adieresis -70 +KPX V agrave -70 +KPX V amacron -70 +KPX V aogonek -70 +KPX V aring -70 +KPX V atilde -70 +KPX V colon -40 +KPX V comma -125 +KPX V e -80 +KPX V eacute -80 +KPX V ecaron -80 +KPX V ecircumflex -80 +KPX V edieresis -80 +KPX V edotaccent -80 +KPX V egrave -80 +KPX V emacron -80 +KPX V eogonek -80 +KPX V hyphen -80 +KPX V o -80 +KPX V oacute -80 +KPX V ocircumflex -80 +KPX V odieresis -80 +KPX V ograve -80 +KPX V ohungarumlaut -80 +KPX V omacron -80 +KPX V oslash -80 +KPX V otilde -80 +KPX V period -125 +KPX V semicolon -40 +KPX V u -70 +KPX V uacute -70 +KPX V ucircumflex -70 +KPX V udieresis -70 +KPX V ugrave -70 +KPX V uhungarumlaut -70 +KPX V umacron -70 +KPX V uogonek -70 +KPX V uring -70 +KPX W A -50 +KPX W Aacute -50 +KPX W Abreve -50 +KPX W Acircumflex -50 +KPX W Adieresis -50 +KPX W Agrave -50 +KPX W Amacron -50 +KPX W Aogonek -50 +KPX W Aring -50 +KPX W Atilde -50 +KPX W O -20 +KPX W Oacute -20 +KPX W Ocircumflex -20 +KPX W Odieresis -20 +KPX W Ograve -20 +KPX W Ohungarumlaut -20 +KPX W Omacron -20 +KPX W Oslash -20 +KPX W Otilde -20 +KPX W a -40 +KPX W aacute -40 +KPX W abreve -40 +KPX W acircumflex -40 +KPX W adieresis -40 +KPX W agrave -40 +KPX W amacron -40 +KPX W aogonek -40 +KPX W aring -40 +KPX W atilde -40 +KPX W comma -80 +KPX W e -30 +KPX W eacute -30 +KPX W ecaron -30 +KPX W ecircumflex -30 +KPX W edieresis -30 +KPX W edotaccent -30 +KPX W egrave -30 +KPX W emacron -30 +KPX W eogonek -30 +KPX W hyphen -40 +KPX W o -30 +KPX W oacute -30 +KPX W ocircumflex -30 +KPX W odieresis -30 +KPX W ograve -30 +KPX W ohungarumlaut -30 +KPX W omacron -30 +KPX W oslash -30 +KPX W otilde -30 +KPX W period -80 +KPX W u -30 +KPX W uacute -30 +KPX W ucircumflex -30 +KPX W udieresis -30 +KPX W ugrave -30 +KPX W uhungarumlaut -30 +KPX W umacron -30 +KPX W uogonek -30 +KPX W uring -30 +KPX W y -20 +KPX W yacute -20 +KPX W ydieresis -20 +KPX Y A -110 +KPX Y Aacute -110 +KPX Y Abreve -110 +KPX Y Acircumflex -110 +KPX Y Adieresis -110 +KPX Y Agrave -110 +KPX Y Amacron -110 +KPX Y Aogonek -110 +KPX Y Aring -110 +KPX Y Atilde -110 +KPX Y O -85 +KPX Y Oacute -85 +KPX Y Ocircumflex -85 +KPX Y Odieresis -85 +KPX Y Ograve -85 +KPX Y Ohungarumlaut -85 +KPX Y Omacron -85 +KPX Y Oslash -85 +KPX Y Otilde -85 +KPX Y a -140 +KPX Y aacute -140 +KPX Y abreve -70 +KPX Y acircumflex -140 +KPX Y adieresis -140 +KPX Y agrave -140 +KPX Y amacron -70 +KPX Y aogonek -140 +KPX Y aring -140 +KPX Y atilde -140 +KPX Y colon -60 +KPX Y comma -140 +KPX Y e -140 +KPX Y eacute -140 +KPX Y ecaron -140 +KPX Y ecircumflex -140 +KPX Y edieresis -140 +KPX Y edotaccent -140 +KPX Y egrave -140 +KPX Y emacron -70 +KPX Y eogonek -140 +KPX Y hyphen -140 +KPX Y i -20 +KPX Y iacute -20 +KPX Y iogonek -20 +KPX Y o -140 +KPX Y oacute -140 +KPX Y ocircumflex -140 +KPX Y odieresis -140 +KPX Y ograve -140 +KPX Y ohungarumlaut -140 +KPX Y omacron -140 +KPX Y oslash -140 +KPX Y otilde -140 +KPX Y period -140 +KPX Y semicolon -60 +KPX Y u -110 +KPX Y uacute -110 +KPX Y ucircumflex -110 +KPX Y udieresis -110 +KPX Y ugrave -110 +KPX Y uhungarumlaut -110 +KPX Y umacron -110 +KPX Y uogonek -110 +KPX Y uring -110 +KPX Yacute A -110 +KPX Yacute Aacute -110 +KPX Yacute Abreve -110 +KPX Yacute Acircumflex -110 +KPX Yacute Adieresis -110 +KPX Yacute Agrave -110 +KPX Yacute Amacron -110 +KPX Yacute Aogonek -110 +KPX Yacute Aring -110 +KPX Yacute Atilde -110 +KPX Yacute O -85 +KPX Yacute Oacute -85 +KPX Yacute Ocircumflex -85 +KPX Yacute Odieresis -85 +KPX Yacute Ograve -85 +KPX Yacute Ohungarumlaut -85 +KPX Yacute Omacron -85 +KPX Yacute Oslash -85 +KPX Yacute Otilde -85 +KPX Yacute a -140 +KPX Yacute aacute -140 +KPX Yacute abreve -70 +KPX Yacute acircumflex -140 +KPX Yacute adieresis -140 +KPX Yacute agrave -140 +KPX Yacute amacron -70 +KPX Yacute aogonek -140 +KPX Yacute aring -140 +KPX Yacute atilde -70 +KPX Yacute colon -60 +KPX Yacute comma -140 +KPX Yacute e -140 +KPX Yacute eacute -140 +KPX Yacute ecaron -140 +KPX Yacute ecircumflex -140 +KPX Yacute edieresis -140 +KPX Yacute edotaccent -140 +KPX Yacute egrave -140 +KPX Yacute emacron -70 +KPX Yacute eogonek -140 +KPX Yacute hyphen -140 +KPX Yacute i -20 +KPX Yacute iacute -20 +KPX Yacute iogonek -20 +KPX Yacute o -140 +KPX Yacute oacute -140 +KPX Yacute ocircumflex -140 +KPX Yacute odieresis -140 +KPX Yacute ograve -140 +KPX Yacute ohungarumlaut -140 +KPX Yacute omacron -70 +KPX Yacute oslash -140 +KPX Yacute otilde -140 +KPX Yacute period -140 +KPX Yacute semicolon -60 +KPX Yacute u -110 +KPX Yacute uacute -110 +KPX Yacute ucircumflex -110 +KPX Yacute udieresis -110 +KPX Yacute ugrave -110 +KPX Yacute uhungarumlaut -110 +KPX Yacute umacron -110 +KPX Yacute uogonek -110 +KPX Yacute uring -110 +KPX Ydieresis A -110 +KPX Ydieresis Aacute -110 +KPX Ydieresis Abreve -110 +KPX Ydieresis Acircumflex -110 +KPX Ydieresis Adieresis -110 +KPX Ydieresis Agrave -110 +KPX Ydieresis Amacron -110 +KPX Ydieresis Aogonek -110 +KPX Ydieresis Aring -110 +KPX Ydieresis Atilde -110 +KPX Ydieresis O -85 +KPX Ydieresis Oacute -85 +KPX Ydieresis Ocircumflex -85 +KPX Ydieresis Odieresis -85 +KPX Ydieresis Ograve -85 +KPX Ydieresis Ohungarumlaut -85 +KPX Ydieresis Omacron -85 +KPX Ydieresis Oslash -85 +KPX Ydieresis Otilde -85 +KPX Ydieresis a -140 +KPX Ydieresis aacute -140 +KPX Ydieresis abreve -70 +KPX Ydieresis acircumflex -140 +KPX Ydieresis adieresis -140 +KPX Ydieresis agrave -140 +KPX Ydieresis amacron -70 +KPX Ydieresis aogonek -140 +KPX Ydieresis aring -140 +KPX Ydieresis atilde -70 +KPX Ydieresis colon -60 +KPX Ydieresis comma -140 +KPX Ydieresis e -140 +KPX Ydieresis eacute -140 +KPX Ydieresis ecaron -140 +KPX Ydieresis ecircumflex -140 +KPX Ydieresis edieresis -140 +KPX Ydieresis edotaccent -140 +KPX Ydieresis egrave -140 +KPX Ydieresis emacron -70 +KPX Ydieresis eogonek -140 +KPX Ydieresis hyphen -140 +KPX Ydieresis i -20 +KPX Ydieresis iacute -20 +KPX Ydieresis iogonek -20 +KPX Ydieresis o -140 +KPX Ydieresis oacute -140 +KPX Ydieresis ocircumflex -140 +KPX Ydieresis odieresis -140 +KPX Ydieresis ograve -140 +KPX Ydieresis ohungarumlaut -140 +KPX Ydieresis omacron -140 +KPX Ydieresis oslash -140 +KPX Ydieresis otilde -140 +KPX Ydieresis period -140 +KPX Ydieresis semicolon -60 +KPX Ydieresis u -110 +KPX Ydieresis uacute -110 +KPX Ydieresis ucircumflex -110 +KPX Ydieresis udieresis -110 +KPX Ydieresis ugrave -110 +KPX Ydieresis uhungarumlaut -110 +KPX Ydieresis umacron -110 +KPX Ydieresis uogonek -110 +KPX Ydieresis uring -110 +KPX a v -20 +KPX a w -20 +KPX a y -30 +KPX a yacute -30 +KPX a ydieresis -30 +KPX aacute v -20 +KPX aacute w -20 +KPX aacute y -30 +KPX aacute yacute -30 +KPX aacute ydieresis -30 +KPX abreve v -20 +KPX abreve w -20 +KPX abreve y -30 +KPX abreve yacute -30 +KPX abreve ydieresis -30 +KPX acircumflex v -20 +KPX acircumflex w -20 +KPX acircumflex y -30 +KPX acircumflex yacute -30 +KPX acircumflex ydieresis -30 +KPX adieresis v -20 +KPX adieresis w -20 +KPX adieresis y -30 +KPX adieresis yacute -30 +KPX adieresis ydieresis -30 +KPX agrave v -20 +KPX agrave w -20 +KPX agrave y -30 +KPX agrave yacute -30 +KPX agrave ydieresis -30 +KPX amacron v -20 +KPX amacron w -20 +KPX amacron y -30 +KPX amacron yacute -30 +KPX amacron ydieresis -30 +KPX aogonek v -20 +KPX aogonek w -20 +KPX aogonek y -30 +KPX aogonek yacute -30 +KPX aogonek ydieresis -30 +KPX aring v -20 +KPX aring w -20 +KPX aring y -30 +KPX aring yacute -30 +KPX aring ydieresis -30 +KPX atilde v -20 +KPX atilde w -20 +KPX atilde y -30 +KPX atilde yacute -30 +KPX atilde ydieresis -30 +KPX b b -10 +KPX b comma -40 +KPX b l -20 +KPX b lacute -20 +KPX b lcommaaccent -20 +KPX b lslash -20 +KPX b period -40 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX b v -20 +KPX b y -20 +KPX b yacute -20 +KPX b ydieresis -20 +KPX c comma -15 +KPX c k -20 +KPX c kcommaaccent -20 +KPX cacute comma -15 +KPX cacute k -20 +KPX cacute kcommaaccent -20 +KPX ccaron comma -15 +KPX ccaron k -20 +KPX ccaron kcommaaccent -20 +KPX ccedilla comma -15 +KPX ccedilla k -20 +KPX ccedilla kcommaaccent -20 +KPX colon space -50 +KPX comma quotedblright -100 +KPX comma quoteright -100 +KPX e comma -15 +KPX e period -15 +KPX e v -30 +KPX e w -20 +KPX e x -30 +KPX e y -20 +KPX e yacute -20 +KPX e ydieresis -20 +KPX eacute comma -15 +KPX eacute period -15 +KPX eacute v -30 +KPX eacute w -20 +KPX eacute x -30 +KPX eacute y -20 +KPX eacute yacute -20 +KPX eacute ydieresis -20 +KPX ecaron comma -15 +KPX ecaron period -15 +KPX ecaron v -30 +KPX ecaron w -20 +KPX ecaron x -30 +KPX ecaron y -20 +KPX ecaron yacute -20 +KPX ecaron ydieresis -20 +KPX ecircumflex comma -15 +KPX ecircumflex period -15 +KPX ecircumflex v -30 +KPX ecircumflex w -20 +KPX ecircumflex x -30 +KPX ecircumflex y -20 +KPX ecircumflex yacute -20 +KPX ecircumflex ydieresis -20 +KPX edieresis comma -15 +KPX edieresis period -15 +KPX edieresis v -30 +KPX edieresis w -20 +KPX edieresis x -30 +KPX edieresis y -20 +KPX edieresis yacute -20 +KPX edieresis ydieresis -20 +KPX edotaccent comma -15 +KPX edotaccent period -15 +KPX edotaccent v -30 +KPX edotaccent w -20 +KPX edotaccent x -30 +KPX edotaccent y -20 +KPX edotaccent yacute -20 +KPX edotaccent ydieresis -20 +KPX egrave comma -15 +KPX egrave period -15 +KPX egrave v -30 +KPX egrave w -20 +KPX egrave x -30 +KPX egrave y -20 +KPX egrave yacute -20 +KPX egrave ydieresis -20 +KPX emacron comma -15 +KPX emacron period -15 +KPX emacron v -30 +KPX emacron w -20 +KPX emacron x -30 +KPX emacron y -20 +KPX emacron yacute -20 +KPX emacron ydieresis -20 +KPX eogonek comma -15 +KPX eogonek period -15 +KPX eogonek v -30 +KPX eogonek w -20 +KPX eogonek x -30 +KPX eogonek y -20 +KPX eogonek yacute -20 +KPX eogonek ydieresis -20 +KPX f a -30 +KPX f aacute -30 +KPX f abreve -30 +KPX f acircumflex -30 +KPX f adieresis -30 +KPX f agrave -30 +KPX f amacron -30 +KPX f aogonek -30 +KPX f aring -30 +KPX f atilde -30 +KPX f comma -30 +KPX f dotlessi -28 +KPX f e -30 +KPX f eacute -30 +KPX f ecaron -30 +KPX f ecircumflex -30 +KPX f edieresis -30 +KPX f edotaccent -30 +KPX f egrave -30 +KPX f emacron -30 +KPX f eogonek -30 +KPX f o -30 +KPX f oacute -30 +KPX f ocircumflex -30 +KPX f odieresis -30 +KPX f ograve -30 +KPX f ohungarumlaut -30 +KPX f omacron -30 +KPX f oslash -30 +KPX f otilde -30 +KPX f period -30 +KPX f quotedblright 60 +KPX f quoteright 50 +KPX g r -10 +KPX g racute -10 +KPX g rcaron -10 +KPX g rcommaaccent -10 +KPX gbreve r -10 +KPX gbreve racute -10 +KPX gbreve rcaron -10 +KPX gbreve rcommaaccent -10 +KPX gcommaaccent r -10 +KPX gcommaaccent racute -10 +KPX gcommaaccent rcaron -10 +KPX gcommaaccent rcommaaccent -10 +KPX h y -30 +KPX h yacute -30 +KPX h ydieresis -30 +KPX k e -20 +KPX k eacute -20 +KPX k ecaron -20 +KPX k ecircumflex -20 +KPX k edieresis -20 +KPX k edotaccent -20 +KPX k egrave -20 +KPX k emacron -20 +KPX k eogonek -20 +KPX k o -20 +KPX k oacute -20 +KPX k ocircumflex -20 +KPX k odieresis -20 +KPX k ograve -20 +KPX k ohungarumlaut -20 +KPX k omacron -20 +KPX k oslash -20 +KPX k otilde -20 +KPX kcommaaccent e -20 +KPX kcommaaccent eacute -20 +KPX kcommaaccent ecaron -20 +KPX kcommaaccent ecircumflex -20 +KPX kcommaaccent edieresis -20 +KPX kcommaaccent edotaccent -20 +KPX kcommaaccent egrave -20 +KPX kcommaaccent emacron -20 +KPX kcommaaccent eogonek -20 +KPX kcommaaccent o -20 +KPX kcommaaccent oacute -20 +KPX kcommaaccent ocircumflex -20 +KPX kcommaaccent odieresis -20 +KPX kcommaaccent ograve -20 +KPX kcommaaccent ohungarumlaut -20 +KPX kcommaaccent omacron -20 +KPX kcommaaccent oslash -20 +KPX kcommaaccent otilde -20 +KPX m u -10 +KPX m uacute -10 +KPX m ucircumflex -10 +KPX m udieresis -10 +KPX m ugrave -10 +KPX m uhungarumlaut -10 +KPX m umacron -10 +KPX m uogonek -10 +KPX m uring -10 +KPX m y -15 +KPX m yacute -15 +KPX m ydieresis -15 +KPX n u -10 +KPX n uacute -10 +KPX n ucircumflex -10 +KPX n udieresis -10 +KPX n ugrave -10 +KPX n uhungarumlaut -10 +KPX n umacron -10 +KPX n uogonek -10 +KPX n uring -10 +KPX n v -20 +KPX n y -15 +KPX n yacute -15 +KPX n ydieresis -15 +KPX nacute u -10 +KPX nacute uacute -10 +KPX nacute ucircumflex -10 +KPX nacute udieresis -10 +KPX nacute ugrave -10 +KPX nacute uhungarumlaut -10 +KPX nacute umacron -10 +KPX nacute uogonek -10 +KPX nacute uring -10 +KPX nacute v -20 +KPX nacute y -15 +KPX nacute yacute -15 +KPX nacute ydieresis -15 +KPX ncaron u -10 +KPX ncaron uacute -10 +KPX ncaron ucircumflex -10 +KPX ncaron udieresis -10 +KPX ncaron ugrave -10 +KPX ncaron uhungarumlaut -10 +KPX ncaron umacron -10 +KPX ncaron uogonek -10 +KPX ncaron uring -10 +KPX ncaron v -20 +KPX ncaron y -15 +KPX ncaron yacute -15 +KPX ncaron ydieresis -15 +KPX ncommaaccent u -10 +KPX ncommaaccent uacute -10 +KPX ncommaaccent ucircumflex -10 +KPX ncommaaccent udieresis -10 +KPX ncommaaccent ugrave -10 +KPX ncommaaccent uhungarumlaut -10 +KPX ncommaaccent umacron -10 +KPX ncommaaccent uogonek -10 +KPX ncommaaccent uring -10 +KPX ncommaaccent v -20 +KPX ncommaaccent y -15 +KPX ncommaaccent yacute -15 +KPX ncommaaccent ydieresis -15 +KPX ntilde u -10 +KPX ntilde uacute -10 +KPX ntilde ucircumflex -10 +KPX ntilde udieresis -10 +KPX ntilde ugrave -10 +KPX ntilde uhungarumlaut -10 +KPX ntilde umacron -10 +KPX ntilde uogonek -10 +KPX ntilde uring -10 +KPX ntilde v -20 +KPX ntilde y -15 +KPX ntilde yacute -15 +KPX ntilde ydieresis -15 +KPX o comma -40 +KPX o period -40 +KPX o v -15 +KPX o w -15 +KPX o x -30 +KPX o y -30 +KPX o yacute -30 +KPX o ydieresis -30 +KPX oacute comma -40 +KPX oacute period -40 +KPX oacute v -15 +KPX oacute w -15 +KPX oacute x -30 +KPX oacute y -30 +KPX oacute yacute -30 +KPX oacute ydieresis -30 +KPX ocircumflex comma -40 +KPX ocircumflex period -40 +KPX ocircumflex v -15 +KPX ocircumflex w -15 +KPX ocircumflex x -30 +KPX ocircumflex y -30 +KPX ocircumflex yacute -30 +KPX ocircumflex ydieresis -30 +KPX odieresis comma -40 +KPX odieresis period -40 +KPX odieresis v -15 +KPX odieresis w -15 +KPX odieresis x -30 +KPX odieresis y -30 +KPX odieresis yacute -30 +KPX odieresis ydieresis -30 +KPX ograve comma -40 +KPX ograve period -40 +KPX ograve v -15 +KPX ograve w -15 +KPX ograve x -30 +KPX ograve y -30 +KPX ograve yacute -30 +KPX ograve ydieresis -30 +KPX ohungarumlaut comma -40 +KPX ohungarumlaut period -40 +KPX ohungarumlaut v -15 +KPX ohungarumlaut w -15 +KPX ohungarumlaut x -30 +KPX ohungarumlaut y -30 +KPX ohungarumlaut yacute -30 +KPX ohungarumlaut ydieresis -30 +KPX omacron comma -40 +KPX omacron period -40 +KPX omacron v -15 +KPX omacron w -15 +KPX omacron x -30 +KPX omacron y -30 +KPX omacron yacute -30 +KPX omacron ydieresis -30 +KPX oslash a -55 +KPX oslash aacute -55 +KPX oslash abreve -55 +KPX oslash acircumflex -55 +KPX oslash adieresis -55 +KPX oslash agrave -55 +KPX oslash amacron -55 +KPX oslash aogonek -55 +KPX oslash aring -55 +KPX oslash atilde -55 +KPX oslash b -55 +KPX oslash c -55 +KPX oslash cacute -55 +KPX oslash ccaron -55 +KPX oslash ccedilla -55 +KPX oslash comma -95 +KPX oslash d -55 +KPX oslash dcroat -55 +KPX oslash e -55 +KPX oslash eacute -55 +KPX oslash ecaron -55 +KPX oslash ecircumflex -55 +KPX oslash edieresis -55 +KPX oslash edotaccent -55 +KPX oslash egrave -55 +KPX oslash emacron -55 +KPX oslash eogonek -55 +KPX oslash f -55 +KPX oslash g -55 +KPX oslash gbreve -55 +KPX oslash gcommaaccent -55 +KPX oslash h -55 +KPX oslash i -55 +KPX oslash iacute -55 +KPX oslash icircumflex -55 +KPX oslash idieresis -55 +KPX oslash igrave -55 +KPX oslash imacron -55 +KPX oslash iogonek -55 +KPX oslash j -55 +KPX oslash k -55 +KPX oslash kcommaaccent -55 +KPX oslash l -55 +KPX oslash lacute -55 +KPX oslash lcommaaccent -55 +KPX oslash lslash -55 +KPX oslash m -55 +KPX oslash n -55 +KPX oslash nacute -55 +KPX oslash ncaron -55 +KPX oslash ncommaaccent -55 +KPX oslash ntilde -55 +KPX oslash o -55 +KPX oslash oacute -55 +KPX oslash ocircumflex -55 +KPX oslash odieresis -55 +KPX oslash ograve -55 +KPX oslash ohungarumlaut -55 +KPX oslash omacron -55 +KPX oslash oslash -55 +KPX oslash otilde -55 +KPX oslash p -55 +KPX oslash period -95 +KPX oslash q -55 +KPX oslash r -55 +KPX oslash racute -55 +KPX oslash rcaron -55 +KPX oslash rcommaaccent -55 +KPX oslash s -55 +KPX oslash sacute -55 +KPX oslash scaron -55 +KPX oslash scedilla -55 +KPX oslash scommaaccent -55 +KPX oslash t -55 +KPX oslash tcommaaccent -55 +KPX oslash u -55 +KPX oslash uacute -55 +KPX oslash ucircumflex -55 +KPX oslash udieresis -55 +KPX oslash ugrave -55 +KPX oslash uhungarumlaut -55 +KPX oslash umacron -55 +KPX oslash uogonek -55 +KPX oslash uring -55 +KPX oslash v -70 +KPX oslash w -70 +KPX oslash x -85 +KPX oslash y -70 +KPX oslash yacute -70 +KPX oslash ydieresis -70 +KPX oslash z -55 +KPX oslash zacute -55 +KPX oslash zcaron -55 +KPX oslash zdotaccent -55 +KPX otilde comma -40 +KPX otilde period -40 +KPX otilde v -15 +KPX otilde w -15 +KPX otilde x -30 +KPX otilde y -30 +KPX otilde yacute -30 +KPX otilde ydieresis -30 +KPX p comma -35 +KPX p period -35 +KPX p y -30 +KPX p yacute -30 +KPX p ydieresis -30 +KPX period quotedblright -100 +KPX period quoteright -100 +KPX period space -60 +KPX quotedblright space -40 +KPX quoteleft quoteleft -57 +KPX quoteright d -50 +KPX quoteright dcroat -50 +KPX quoteright quoteright -57 +KPX quoteright r -50 +KPX quoteright racute -50 +KPX quoteright rcaron -50 +KPX quoteright rcommaaccent -50 +KPX quoteright s -50 +KPX quoteright sacute -50 +KPX quoteright scaron -50 +KPX quoteright scedilla -50 +KPX quoteright scommaaccent -50 +KPX quoteright space -70 +KPX r a -10 +KPX r aacute -10 +KPX r abreve -10 +KPX r acircumflex -10 +KPX r adieresis -10 +KPX r agrave -10 +KPX r amacron -10 +KPX r aogonek -10 +KPX r aring -10 +KPX r atilde -10 +KPX r colon 30 +KPX r comma -50 +KPX r i 15 +KPX r iacute 15 +KPX r icircumflex 15 +KPX r idieresis 15 +KPX r igrave 15 +KPX r imacron 15 +KPX r iogonek 15 +KPX r k 15 +KPX r kcommaaccent 15 +KPX r l 15 +KPX r lacute 15 +KPX r lcommaaccent 15 +KPX r lslash 15 +KPX r m 25 +KPX r n 25 +KPX r nacute 25 +KPX r ncaron 25 +KPX r ncommaaccent 25 +KPX r ntilde 25 +KPX r p 30 +KPX r period -50 +KPX r semicolon 30 +KPX r t 40 +KPX r tcommaaccent 40 +KPX r u 15 +KPX r uacute 15 +KPX r ucircumflex 15 +KPX r udieresis 15 +KPX r ugrave 15 +KPX r uhungarumlaut 15 +KPX r umacron 15 +KPX r uogonek 15 +KPX r uring 15 +KPX r v 30 +KPX r y 30 +KPX r yacute 30 +KPX r ydieresis 30 +KPX racute a -10 +KPX racute aacute -10 +KPX racute abreve -10 +KPX racute acircumflex -10 +KPX racute adieresis -10 +KPX racute agrave -10 +KPX racute amacron -10 +KPX racute aogonek -10 +KPX racute aring -10 +KPX racute atilde -10 +KPX racute colon 30 +KPX racute comma -50 +KPX racute i 15 +KPX racute iacute 15 +KPX racute icircumflex 15 +KPX racute idieresis 15 +KPX racute igrave 15 +KPX racute imacron 15 +KPX racute iogonek 15 +KPX racute k 15 +KPX racute kcommaaccent 15 +KPX racute l 15 +KPX racute lacute 15 +KPX racute lcommaaccent 15 +KPX racute lslash 15 +KPX racute m 25 +KPX racute n 25 +KPX racute nacute 25 +KPX racute ncaron 25 +KPX racute ncommaaccent 25 +KPX racute ntilde 25 +KPX racute p 30 +KPX racute period -50 +KPX racute semicolon 30 +KPX racute t 40 +KPX racute tcommaaccent 40 +KPX racute u 15 +KPX racute uacute 15 +KPX racute ucircumflex 15 +KPX racute udieresis 15 +KPX racute ugrave 15 +KPX racute uhungarumlaut 15 +KPX racute umacron 15 +KPX racute uogonek 15 +KPX racute uring 15 +KPX racute v 30 +KPX racute y 30 +KPX racute yacute 30 +KPX racute ydieresis 30 +KPX rcaron a -10 +KPX rcaron aacute -10 +KPX rcaron abreve -10 +KPX rcaron acircumflex -10 +KPX rcaron adieresis -10 +KPX rcaron agrave -10 +KPX rcaron amacron -10 +KPX rcaron aogonek -10 +KPX rcaron aring -10 +KPX rcaron atilde -10 +KPX rcaron colon 30 +KPX rcaron comma -50 +KPX rcaron i 15 +KPX rcaron iacute 15 +KPX rcaron icircumflex 15 +KPX rcaron idieresis 15 +KPX rcaron igrave 15 +KPX rcaron imacron 15 +KPX rcaron iogonek 15 +KPX rcaron k 15 +KPX rcaron kcommaaccent 15 +KPX rcaron l 15 +KPX rcaron lacute 15 +KPX rcaron lcommaaccent 15 +KPX rcaron lslash 15 +KPX rcaron m 25 +KPX rcaron n 25 +KPX rcaron nacute 25 +KPX rcaron ncaron 25 +KPX rcaron ncommaaccent 25 +KPX rcaron ntilde 25 +KPX rcaron p 30 +KPX rcaron period -50 +KPX rcaron semicolon 30 +KPX rcaron t 40 +KPX rcaron tcommaaccent 40 +KPX rcaron u 15 +KPX rcaron uacute 15 +KPX rcaron ucircumflex 15 +KPX rcaron udieresis 15 +KPX rcaron ugrave 15 +KPX rcaron uhungarumlaut 15 +KPX rcaron umacron 15 +KPX rcaron uogonek 15 +KPX rcaron uring 15 +KPX rcaron v 30 +KPX rcaron y 30 +KPX rcaron yacute 30 +KPX rcaron ydieresis 30 +KPX rcommaaccent a -10 +KPX rcommaaccent aacute -10 +KPX rcommaaccent abreve -10 +KPX rcommaaccent acircumflex -10 +KPX rcommaaccent adieresis -10 +KPX rcommaaccent agrave -10 +KPX rcommaaccent amacron -10 +KPX rcommaaccent aogonek -10 +KPX rcommaaccent aring -10 +KPX rcommaaccent atilde -10 +KPX rcommaaccent colon 30 +KPX rcommaaccent comma -50 +KPX rcommaaccent i 15 +KPX rcommaaccent iacute 15 +KPX rcommaaccent icircumflex 15 +KPX rcommaaccent idieresis 15 +KPX rcommaaccent igrave 15 +KPX rcommaaccent imacron 15 +KPX rcommaaccent iogonek 15 +KPX rcommaaccent k 15 +KPX rcommaaccent kcommaaccent 15 +KPX rcommaaccent l 15 +KPX rcommaaccent lacute 15 +KPX rcommaaccent lcommaaccent 15 +KPX rcommaaccent lslash 15 +KPX rcommaaccent m 25 +KPX rcommaaccent n 25 +KPX rcommaaccent nacute 25 +KPX rcommaaccent ncaron 25 +KPX rcommaaccent ncommaaccent 25 +KPX rcommaaccent ntilde 25 +KPX rcommaaccent p 30 +KPX rcommaaccent period -50 +KPX rcommaaccent semicolon 30 +KPX rcommaaccent t 40 +KPX rcommaaccent tcommaaccent 40 +KPX rcommaaccent u 15 +KPX rcommaaccent uacute 15 +KPX rcommaaccent ucircumflex 15 +KPX rcommaaccent udieresis 15 +KPX rcommaaccent ugrave 15 +KPX rcommaaccent uhungarumlaut 15 +KPX rcommaaccent umacron 15 +KPX rcommaaccent uogonek 15 +KPX rcommaaccent uring 15 +KPX rcommaaccent v 30 +KPX rcommaaccent y 30 +KPX rcommaaccent yacute 30 +KPX rcommaaccent ydieresis 30 +KPX s comma -15 +KPX s period -15 +KPX s w -30 +KPX sacute comma -15 +KPX sacute period -15 +KPX sacute w -30 +KPX scaron comma -15 +KPX scaron period -15 +KPX scaron w -30 +KPX scedilla comma -15 +KPX scedilla period -15 +KPX scedilla w -30 +KPX scommaaccent comma -15 +KPX scommaaccent period -15 +KPX scommaaccent w -30 +KPX semicolon space -50 +KPX space T -50 +KPX space Tcaron -50 +KPX space Tcommaaccent -50 +KPX space V -50 +KPX space W -40 +KPX space Y -90 +KPX space Yacute -90 +KPX space Ydieresis -90 +KPX space quotedblleft -30 +KPX space quoteleft -60 +KPX v a -25 +KPX v aacute -25 +KPX v abreve -25 +KPX v acircumflex -25 +KPX v adieresis -25 +KPX v agrave -25 +KPX v amacron -25 +KPX v aogonek -25 +KPX v aring -25 +KPX v atilde -25 +KPX v comma -80 +KPX v e -25 +KPX v eacute -25 +KPX v ecaron -25 +KPX v ecircumflex -25 +KPX v edieresis -25 +KPX v edotaccent -25 +KPX v egrave -25 +KPX v emacron -25 +KPX v eogonek -25 +KPX v o -25 +KPX v oacute -25 +KPX v ocircumflex -25 +KPX v odieresis -25 +KPX v ograve -25 +KPX v ohungarumlaut -25 +KPX v omacron -25 +KPX v oslash -25 +KPX v otilde -25 +KPX v period -80 +KPX w a -15 +KPX w aacute -15 +KPX w abreve -15 +KPX w acircumflex -15 +KPX w adieresis -15 +KPX w agrave -15 +KPX w amacron -15 +KPX w aogonek -15 +KPX w aring -15 +KPX w atilde -15 +KPX w comma -60 +KPX w e -10 +KPX w eacute -10 +KPX w ecaron -10 +KPX w ecircumflex -10 +KPX w edieresis -10 +KPX w edotaccent -10 +KPX w egrave -10 +KPX w emacron -10 +KPX w eogonek -10 +KPX w o -10 +KPX w oacute -10 +KPX w ocircumflex -10 +KPX w odieresis -10 +KPX w ograve -10 +KPX w ohungarumlaut -10 +KPX w omacron -10 +KPX w oslash -10 +KPX w otilde -10 +KPX w period -60 +KPX x e -30 +KPX x eacute -30 +KPX x ecaron -30 +KPX x ecircumflex -30 +KPX x edieresis -30 +KPX x edotaccent -30 +KPX x egrave -30 +KPX x emacron -30 +KPX x eogonek -30 +KPX y a -20 +KPX y aacute -20 +KPX y abreve -20 +KPX y acircumflex -20 +KPX y adieresis -20 +KPX y agrave -20 +KPX y amacron -20 +KPX y aogonek -20 +KPX y aring -20 +KPX y atilde -20 +KPX y comma -100 +KPX y e -20 +KPX y eacute -20 +KPX y ecaron -20 +KPX y ecircumflex -20 +KPX y edieresis -20 +KPX y edotaccent -20 +KPX y egrave -20 +KPX y emacron -20 +KPX y eogonek -20 +KPX y o -20 +KPX y oacute -20 +KPX y ocircumflex -20 +KPX y odieresis -20 +KPX y ograve -20 +KPX y ohungarumlaut -20 +KPX y omacron -20 +KPX y oslash -20 +KPX y otilde -20 +KPX y period -100 +KPX yacute a -20 +KPX yacute aacute -20 +KPX yacute abreve -20 +KPX yacute acircumflex -20 +KPX yacute adieresis -20 +KPX yacute agrave -20 +KPX yacute amacron -20 +KPX yacute aogonek -20 +KPX yacute aring -20 +KPX yacute atilde -20 +KPX yacute comma -100 +KPX yacute e -20 +KPX yacute eacute -20 +KPX yacute ecaron -20 +KPX yacute ecircumflex -20 +KPX yacute edieresis -20 +KPX yacute edotaccent -20 +KPX yacute egrave -20 +KPX yacute emacron -20 +KPX yacute eogonek -20 +KPX yacute o -20 +KPX yacute oacute -20 +KPX yacute ocircumflex -20 +KPX yacute odieresis -20 +KPX yacute ograve -20 +KPX yacute ohungarumlaut -20 +KPX yacute omacron -20 +KPX yacute oslash -20 +KPX yacute otilde -20 +KPX yacute period -100 +KPX ydieresis a -20 +KPX ydieresis aacute -20 +KPX ydieresis abreve -20 +KPX ydieresis acircumflex -20 +KPX ydieresis adieresis -20 +KPX ydieresis agrave -20 +KPX ydieresis amacron -20 +KPX ydieresis aogonek -20 +KPX ydieresis aring -20 +KPX ydieresis atilde -20 +KPX ydieresis comma -100 +KPX ydieresis e -20 +KPX ydieresis eacute -20 +KPX ydieresis ecaron -20 +KPX ydieresis ecircumflex -20 +KPX ydieresis edieresis -20 +KPX ydieresis edotaccent -20 +KPX ydieresis egrave -20 +KPX ydieresis emacron -20 +KPX ydieresis eogonek -20 +KPX ydieresis o -20 +KPX ydieresis oacute -20 +KPX ydieresis ocircumflex -20 +KPX ydieresis odieresis -20 +KPX ydieresis ograve -20 +KPX ydieresis ohungarumlaut -20 +KPX ydieresis omacron -20 +KPX ydieresis oslash -20 +KPX ydieresis otilde -20 +KPX ydieresis period -100 +KPX z e -15 +KPX z eacute -15 +KPX z ecaron -15 +KPX z ecircumflex -15 +KPX z edieresis -15 +KPX z edotaccent -15 +KPX z egrave -15 +KPX z emacron -15 +KPX z eogonek -15 +KPX z o -15 +KPX z oacute -15 +KPX z ocircumflex -15 +KPX z odieresis -15 +KPX z ograve -15 +KPX z ohungarumlaut -15 +KPX z omacron -15 +KPX z oslash -15 +KPX z otilde -15 +KPX zacute e -15 +KPX zacute eacute -15 +KPX zacute ecaron -15 +KPX zacute ecircumflex -15 +KPX zacute edieresis -15 +KPX zacute edotaccent -15 +KPX zacute egrave -15 +KPX zacute emacron -15 +KPX zacute eogonek -15 +KPX zacute o -15 +KPX zacute oacute -15 +KPX zacute ocircumflex -15 +KPX zacute odieresis -15 +KPX zacute ograve -15 +KPX zacute ohungarumlaut -15 +KPX zacute omacron -15 +KPX zacute oslash -15 +KPX zacute otilde -15 +KPX zcaron e -15 +KPX zcaron eacute -15 +KPX zcaron ecaron -15 +KPX zcaron ecircumflex -15 +KPX zcaron edieresis -15 +KPX zcaron edotaccent -15 +KPX zcaron egrave -15 +KPX zcaron emacron -15 +KPX zcaron eogonek -15 +KPX zcaron o -15 +KPX zcaron oacute -15 +KPX zcaron ocircumflex -15 +KPX zcaron odieresis -15 +KPX zcaron ograve -15 +KPX zcaron ohungarumlaut -15 +KPX zcaron omacron -15 +KPX zcaron oslash -15 +KPX zcaron otilde -15 +KPX zdotaccent e -15 +KPX zdotaccent eacute -15 +KPX zdotaccent ecaron -15 +KPX zdotaccent ecircumflex -15 +KPX zdotaccent edieresis -15 +KPX zdotaccent edotaccent -15 +KPX zdotaccent egrave -15 +KPX zdotaccent emacron -15 +KPX zdotaccent eogonek -15 +KPX zdotaccent o -15 +KPX zdotaccent oacute -15 +KPX zdotaccent ocircumflex -15 +KPX zdotaccent odieresis -15 +KPX zdotaccent ograve -15 +KPX zdotaccent ohungarumlaut -15 +KPX zdotaccent omacron -15 +KPX zdotaccent oslash -15 +KPX zdotaccent otilde -15 +EndKernPairs +EndKernData +EndFontMetrics addfile ./Core14_AFMs/MustRead.html hunk ./Core14_AFMs/MustRead.html 1 + + + + + + Core 14 AFM Files - ReadMe + + + + or + + + + + +
This file and the 14 PostScript(R) AFM files it accompanies may be used, copied, and distributed for any purpose and without charge, with or without modification, provided that all copyright notices are retained; that the AFM files are not distributed without this file; that all modifications to this file or any of the AFM files are prominently noted in the modified file(s); and that this paragraph is not modified. Adobe Systems has no responsibility or obligation to support the use of the AFM files. Col
+ + + addfile ./Core14_AFMs/Symbol.afm hunk ./Core14_AFMs/Symbol.afm 1 +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All rights reserved. +Comment Creation Date: Thu May 1 15:12:25 1997 +Comment UniqueID 43064 +Comment VMusage 30820 39997 +FontName Symbol +FullName Symbol +FamilyName Symbol +Weight Medium +ItalicAngle 0 +IsFixedPitch false +CharacterSet Special +FontBBox -180 -293 1090 1010 +UnderlinePosition -100 +UnderlineThickness 50 +Version 001.008 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All rights reserved. +EncodingScheme FontSpecific +StdHW 92 +StdVW 85 +StartCharMetrics 190 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 128 -17 240 672 ; +C 34 ; WX 713 ; N universal ; B 31 0 681 705 ; +C 35 ; WX 500 ; N numbersign ; B 20 -16 481 673 ; +C 36 ; WX 549 ; N existential ; B 25 0 478 707 ; +C 37 ; WX 833 ; N percent ; B 63 -36 771 655 ; +C 38 ; WX 778 ; N ampersand ; B 41 -18 750 661 ; +C 39 ; WX 439 ; N suchthat ; B 48 -17 414 500 ; +C 40 ; WX 333 ; N parenleft ; B 53 -191 300 673 ; +C 41 ; WX 333 ; N parenright ; B 30 -191 277 673 ; +C 42 ; WX 500 ; N asteriskmath ; B 65 134 427 551 ; +C 43 ; WX 549 ; N plus ; B 10 0 539 533 ; +C 44 ; WX 250 ; N comma ; B 56 -152 194 104 ; +C 45 ; WX 549 ; N minus ; B 11 233 535 288 ; +C 46 ; WX 250 ; N period ; B 69 -17 181 95 ; +C 47 ; WX 278 ; N slash ; B 0 -18 254 646 ; +C 48 ; WX 500 ; N zero ; B 24 -14 476 685 ; +C 49 ; WX 500 ; N one ; B 117 0 390 673 ; +C 50 ; WX 500 ; N two ; B 25 0 475 685 ; +C 51 ; WX 500 ; N three ; B 43 -14 435 685 ; +C 52 ; WX 500 ; N four ; B 15 0 469 685 ; +C 53 ; WX 500 ; N five ; B 32 -14 445 690 ; +C 54 ; WX 500 ; N six ; B 34 -14 468 685 ; +C 55 ; WX 500 ; N seven ; B 24 -16 448 673 ; +C 56 ; WX 500 ; N eight ; B 56 -14 445 685 ; +C 57 ; WX 500 ; N nine ; B 30 -18 459 685 ; +C 58 ; WX 278 ; N colon ; B 81 -17 193 460 ; +C 59 ; WX 278 ; N semicolon ; B 83 -152 221 460 ; +C 60 ; WX 549 ; N less ; B 26 0 523 522 ; +C 61 ; WX 549 ; N equal ; B 11 141 537 390 ; +C 62 ; WX 549 ; N greater ; B 26 0 523 522 ; +C 63 ; WX 444 ; N question ; B 70 -17 412 686 ; +C 64 ; WX 549 ; N congruent ; B 11 0 537 475 ; +C 65 ; WX 722 ; N Alpha ; B 4 0 684 673 ; +C 66 ; WX 667 ; N Beta ; B 29 0 592 673 ; +C 67 ; WX 722 ; N Chi ; B -9 0 704 673 ; +C 68 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C 69 ; WX 611 ; N Epsilon ; B 32 0 617 673 ; +C 70 ; WX 763 ; N Phi ; B 26 0 741 673 ; +C 71 ; WX 603 ; N Gamma ; B 24 0 609 673 ; +C 72 ; WX 722 ; N Eta ; B 39 0 729 673 ; +C 73 ; WX 333 ; N Iota ; B 32 0 316 673 ; +C 74 ; WX 631 ; N theta1 ; B 18 -18 623 689 ; +C 75 ; WX 722 ; N Kappa ; B 35 0 722 673 ; +C 76 ; WX 686 ; N Lambda ; B 6 0 680 688 ; +C 77 ; WX 889 ; N Mu ; B 28 0 887 673 ; +C 78 ; WX 722 ; N Nu ; B 29 -8 720 673 ; +C 79 ; WX 722 ; N Omicron ; B 41 -17 715 685 ; +C 80 ; WX 768 ; N Pi ; B 25 0 745 673 ; +C 81 ; WX 741 ; N Theta ; B 41 -17 715 685 ; +C 82 ; WX 556 ; N Rho ; B 28 0 563 673 ; +C 83 ; WX 592 ; N Sigma ; B 5 0 589 673 ; +C 84 ; WX 611 ; N Tau ; B 33 0 607 673 ; +C 85 ; WX 690 ; N Upsilon ; B -8 0 694 673 ; +C 86 ; WX 439 ; N sigma1 ; B 40 -233 436 500 ; +C 87 ; WX 768 ; N Omega ; B 34 0 736 688 ; +C 88 ; WX 645 ; N Xi ; B 40 0 599 673 ; +C 89 ; WX 795 ; N Psi ; B 15 0 781 684 ; +C 90 ; WX 611 ; N Zeta ; B 44 0 636 673 ; +C 91 ; WX 333 ; N bracketleft ; B 86 -155 299 674 ; +C 92 ; WX 863 ; N therefore ; B 163 0 701 487 ; +C 93 ; WX 333 ; N bracketright ; B 33 -155 246 674 ; +C 94 ; WX 658 ; N perpendicular ; B 15 0 652 674 ; +C 95 ; WX 500 ; N underscore ; B -2 -125 502 -75 ; +C 96 ; WX 500 ; N radicalex ; B 480 881 1090 917 ; +C 97 ; WX 631 ; N alpha ; B 41 -18 622 500 ; +C 98 ; WX 549 ; N beta ; B 61 -223 515 741 ; +C 99 ; WX 549 ; N chi ; B 12 -231 522 499 ; +C 100 ; WX 494 ; N delta ; B 40 -19 481 740 ; +C 101 ; WX 439 ; N epsilon ; B 22 -19 427 502 ; +C 102 ; WX 521 ; N phi ; B 28 -224 492 673 ; +C 103 ; WX 411 ; N gamma ; B 5 -225 484 499 ; +C 104 ; WX 603 ; N eta ; B 0 -202 527 514 ; +C 105 ; WX 329 ; N iota ; B 0 -17 301 503 ; +C 106 ; WX 603 ; N phi1 ; B 36 -224 587 499 ; +C 107 ; WX 549 ; N kappa ; B 33 0 558 501 ; +C 108 ; WX 549 ; N lambda ; B 24 -17 548 739 ; +C 109 ; WX 576 ; N mu ; B 33 -223 567 500 ; +C 110 ; WX 521 ; N nu ; B -9 -16 475 507 ; +C 111 ; WX 549 ; N omicron ; B 35 -19 501 499 ; +C 112 ; WX 549 ; N pi ; B 10 -19 530 487 ; +C 113 ; WX 521 ; N theta ; B 43 -17 485 690 ; +C 114 ; WX 549 ; N rho ; B 50 -230 490 499 ; +C 115 ; WX 603 ; N sigma ; B 30 -21 588 500 ; +C 116 ; WX 439 ; N tau ; B 10 -19 418 500 ; +C 117 ; WX 576 ; N upsilon ; B 7 -18 535 507 ; +C 118 ; WX 713 ; N omega1 ; B 12 -18 671 583 ; +C 119 ; WX 686 ; N omega ; B 42 -17 684 500 ; +C 120 ; WX 493 ; N xi ; B 27 -224 469 766 ; +C 121 ; WX 686 ; N psi ; B 12 -228 701 500 ; +C 122 ; WX 494 ; N zeta ; B 60 -225 467 756 ; +C 123 ; WX 480 ; N braceleft ; B 58 -183 397 673 ; +C 124 ; WX 200 ; N bar ; B 65 -293 135 707 ; +C 125 ; WX 480 ; N braceright ; B 79 -183 418 673 ; +C 126 ; WX 549 ; N similar ; B 17 203 529 307 ; +C 160 ; WX 750 ; N Euro ; B 20 -12 714 685 ; +C 161 ; WX 620 ; N Upsilon1 ; B -2 0 610 685 ; +C 162 ; WX 247 ; N minute ; B 27 459 228 735 ; +C 163 ; WX 549 ; N lessequal ; B 29 0 526 639 ; +C 164 ; WX 167 ; N fraction ; B -180 -12 340 677 ; +C 165 ; WX 713 ; N infinity ; B 26 124 688 404 ; +C 166 ; WX 500 ; N florin ; B 2 -193 494 686 ; +C 167 ; WX 753 ; N club ; B 86 -26 660 533 ; +C 168 ; WX 753 ; N diamond ; B 142 -36 600 550 ; +C 169 ; WX 753 ; N heart ; B 117 -33 631 532 ; +C 170 ; WX 753 ; N spade ; B 113 -36 629 548 ; +C 171 ; WX 1042 ; N arrowboth ; B 24 -15 1024 511 ; +C 172 ; WX 987 ; N arrowleft ; B 32 -15 942 511 ; +C 173 ; WX 603 ; N arrowup ; B 45 0 571 910 ; +C 174 ; WX 987 ; N arrowright ; B 49 -15 959 511 ; +C 175 ; WX 603 ; N arrowdown ; B 45 -22 571 888 ; +C 176 ; WX 400 ; N degree ; B 50 385 350 685 ; +C 177 ; WX 549 ; N plusminus ; B 10 0 539 645 ; +C 178 ; WX 411 ; N second ; B 20 459 413 737 ; +C 179 ; WX 549 ; N greaterequal ; B 29 0 526 639 ; +C 180 ; WX 549 ; N multiply ; B 17 8 533 524 ; +C 181 ; WX 713 ; N proportional ; B 27 123 639 404 ; +C 182 ; WX 494 ; N partialdiff ; B 26 -20 462 746 ; +C 183 ; WX 460 ; N bullet ; B 50 113 410 473 ; +C 184 ; WX 549 ; N divide ; B 10 71 536 456 ; +C 185 ; WX 549 ; N notequal ; B 15 -25 540 549 ; +C 186 ; WX 549 ; N equivalence ; B 14 82 538 443 ; +C 187 ; WX 549 ; N approxequal ; B 14 135 527 394 ; +C 188 ; WX 1000 ; N ellipsis ; B 111 -17 889 95 ; +C 189 ; WX 603 ; N arrowvertex ; B 280 -120 336 1010 ; +C 190 ; WX 1000 ; N arrowhorizex ; B -60 220 1050 276 ; +C 191 ; WX 658 ; N carriagereturn ; B 15 -16 602 629 ; +C 192 ; WX 823 ; N aleph ; B 175 -18 661 658 ; +C 193 ; WX 686 ; N Ifraktur ; B 10 -53 578 740 ; +C 194 ; WX 795 ; N Rfraktur ; B 26 -15 759 734 ; +C 195 ; WX 987 ; N weierstrass ; B 159 -211 870 573 ; +C 196 ; WX 768 ; N circlemultiply ; B 43 -17 733 673 ; +C 197 ; WX 768 ; N circleplus ; B 43 -15 733 675 ; +C 198 ; WX 823 ; N emptyset ; B 39 -24 781 719 ; +C 199 ; WX 768 ; N intersection ; B 40 0 732 509 ; +C 200 ; WX 768 ; N union ; B 40 -17 732 492 ; +C 201 ; WX 713 ; N propersuperset ; B 20 0 673 470 ; +C 202 ; WX 713 ; N reflexsuperset ; B 20 -125 673 470 ; +C 203 ; WX 713 ; N notsubset ; B 36 -70 690 540 ; +C 204 ; WX 713 ; N propersubset ; B 37 0 690 470 ; +C 205 ; WX 713 ; N reflexsubset ; B 37 -125 690 470 ; +C 206 ; WX 713 ; N element ; B 45 0 505 468 ; +C 207 ; WX 713 ; N notelement ; B 45 -58 505 555 ; +C 208 ; WX 768 ; N angle ; B 26 0 738 673 ; +C 209 ; WX 713 ; N gradient ; B 36 -19 681 718 ; +C 210 ; WX 790 ; N registerserif ; B 50 -17 740 673 ; +C 211 ; WX 790 ; N copyrightserif ; B 51 -15 741 675 ; +C 212 ; WX 890 ; N trademarkserif ; B 18 293 855 673 ; +C 213 ; WX 823 ; N product ; B 25 -101 803 751 ; +C 214 ; WX 549 ; N radical ; B 10 -38 515 917 ; +C 215 ; WX 250 ; N dotmath ; B 69 210 169 310 ; +C 216 ; WX 713 ; N logicalnot ; B 15 0 680 288 ; +C 217 ; WX 603 ; N logicaland ; B 23 0 583 454 ; +C 218 ; WX 603 ; N logicalor ; B 30 0 578 477 ; +C 219 ; WX 1042 ; N arrowdblboth ; B 27 -20 1023 510 ; +C 220 ; WX 987 ; N arrowdblleft ; B 30 -15 939 513 ; +C 221 ; WX 603 ; N arrowdblup ; B 39 2 567 911 ; +C 222 ; WX 987 ; N arrowdblright ; B 45 -20 954 508 ; +C 223 ; WX 603 ; N arrowdbldown ; B 44 -19 572 890 ; +C 224 ; WX 494 ; N lozenge ; B 18 0 466 745 ; +C 225 ; WX 329 ; N angleleft ; B 25 -198 306 746 ; +C 226 ; WX 790 ; N registersans ; B 50 -20 740 670 ; +C 227 ; WX 790 ; N copyrightsans ; B 49 -15 739 675 ; +C 228 ; WX 786 ; N trademarksans ; B 5 293 725 673 ; +C 229 ; WX 713 ; N summation ; B 14 -108 695 752 ; +C 230 ; WX 384 ; N parenlefttp ; B 24 -293 436 926 ; +C 231 ; WX 384 ; N parenleftex ; B 24 -85 108 925 ; +C 232 ; WX 384 ; N parenleftbt ; B 24 -293 436 926 ; +C 233 ; WX 384 ; N bracketlefttp ; B 0 -80 349 926 ; +C 234 ; WX 384 ; N bracketleftex ; B 0 -79 77 925 ; +C 235 ; WX 384 ; N bracketleftbt ; B 0 -80 349 926 ; +C 236 ; WX 494 ; N bracelefttp ; B 209 -85 445 925 ; +C 237 ; WX 494 ; N braceleftmid ; B 20 -85 284 935 ; +C 238 ; WX 494 ; N braceleftbt ; B 209 -75 445 935 ; +C 239 ; WX 494 ; N braceex ; B 209 -85 284 935 ; +C 241 ; WX 329 ; N angleright ; B 21 -198 302 746 ; +C 242 ; WX 274 ; N integral ; B 2 -107 291 916 ; +C 243 ; WX 686 ; N integraltp ; B 308 -88 675 920 ; +C 244 ; WX 686 ; N integralex ; B 308 -88 378 975 ; +C 245 ; WX 686 ; N integralbt ; B 11 -87 378 921 ; +C 246 ; WX 384 ; N parenrighttp ; B 54 -293 466 926 ; +C 247 ; WX 384 ; N parenrightex ; B 382 -85 466 925 ; +C 248 ; WX 384 ; N parenrightbt ; B 54 -293 466 926 ; +C 249 ; WX 384 ; N bracketrighttp ; B 22 -80 371 926 ; +C 250 ; WX 384 ; N bracketrightex ; B 294 -79 371 925 ; +C 251 ; WX 384 ; N bracketrightbt ; B 22 -80 371 926 ; +C 252 ; WX 494 ; N bracerighttp ; B 48 -85 284 925 ; +C 253 ; WX 494 ; N bracerightmid ; B 209 -85 473 935 ; +C 254 ; WX 494 ; N bracerightbt ; B 48 -75 284 935 ; +C -1 ; WX 790 ; N apple ; B 56 -3 733 808 ; +EndCharMetrics +EndFontMetrics addfile ./Core14_AFMs/Times-Bold.afm hunk ./Core14_AFMs/Times-Bold.afm 1 +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 12:52:56 1997 +Comment UniqueID 43065 +Comment VMusage 41636 52661 +FontName Times-Bold +FullName Times Bold +FamilyName Times +Weight Bold +ItalicAngle 0 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -168 -218 1000 935 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 676 +XHeight 461 +Ascender 683 +Descender -217 +StdHW 44 +StdVW 139 +StartCharMetrics 315 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 81 -13 251 691 ; +C 34 ; WX 555 ; N quotedbl ; B 83 404 472 691 ; +C 35 ; WX 500 ; N numbersign ; B 4 0 496 700 ; +C 36 ; WX 500 ; N dollar ; B 29 -99 472 750 ; +C 37 ; WX 1000 ; N percent ; B 124 -14 877 692 ; +C 38 ; WX 833 ; N ampersand ; B 62 -16 787 691 ; +C 39 ; WX 333 ; N quoteright ; B 79 356 263 691 ; +C 40 ; WX 333 ; N parenleft ; B 46 -168 306 694 ; +C 41 ; WX 333 ; N parenright ; B 27 -168 287 694 ; +C 42 ; WX 500 ; N asterisk ; B 56 255 447 691 ; +C 43 ; WX 570 ; N plus ; B 33 0 537 506 ; +C 44 ; WX 250 ; N comma ; B 39 -180 223 155 ; +C 45 ; WX 333 ; N hyphen ; B 44 171 287 287 ; +C 46 ; WX 250 ; N period ; B 41 -13 210 156 ; +C 47 ; WX 278 ; N slash ; B -24 -19 302 691 ; +C 48 ; WX 500 ; N zero ; B 24 -13 476 688 ; +C 49 ; WX 500 ; N one ; B 65 0 442 688 ; +C 50 ; WX 500 ; N two ; B 17 0 478 688 ; +C 51 ; WX 500 ; N three ; B 16 -14 468 688 ; +C 52 ; WX 500 ; N four ; B 19 0 475 688 ; +C 53 ; WX 500 ; N five ; B 22 -8 470 676 ; +C 54 ; WX 500 ; N six ; B 28 -13 475 688 ; +C 55 ; WX 500 ; N seven ; B 17 0 477 676 ; +C 56 ; WX 500 ; N eight ; B 28 -13 472 688 ; +C 57 ; WX 500 ; N nine ; B 26 -13 473 688 ; +C 58 ; WX 333 ; N colon ; B 82 -13 251 472 ; +C 59 ; WX 333 ; N semicolon ; B 82 -180 266 472 ; +C 60 ; WX 570 ; N less ; B 31 -8 539 514 ; +C 61 ; WX 570 ; N equal ; B 33 107 537 399 ; +C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ; +C 63 ; WX 500 ; N question ; B 57 -13 445 689 ; +C 64 ; WX 930 ; N at ; B 108 -19 822 691 ; +C 65 ; WX 722 ; N A ; B 9 0 689 690 ; +C 66 ; WX 667 ; N B ; B 16 0 619 676 ; +C 67 ; WX 722 ; N C ; B 49 -19 687 691 ; +C 68 ; WX 722 ; N D ; B 14 0 690 676 ; +C 69 ; WX 667 ; N E ; B 16 0 641 676 ; +C 70 ; WX 611 ; N F ; B 16 0 583 676 ; +C 71 ; WX 778 ; N G ; B 37 -19 755 691 ; +C 72 ; WX 778 ; N H ; B 21 0 759 676 ; +C 73 ; WX 389 ; N I ; B 20 0 370 676 ; +C 74 ; WX 500 ; N J ; B 3 -96 479 676 ; +C 75 ; WX 778 ; N K ; B 30 0 769 676 ; +C 76 ; WX 667 ; N L ; B 19 0 638 676 ; +C 77 ; WX 944 ; N M ; B 14 0 921 676 ; +C 78 ; WX 722 ; N N ; B 16 -18 701 676 ; +C 79 ; WX 778 ; N O ; B 35 -19 743 691 ; +C 80 ; WX 611 ; N P ; B 16 0 600 676 ; +C 81 ; WX 778 ; N Q ; B 35 -176 743 691 ; +C 82 ; WX 722 ; N R ; B 26 0 715 676 ; +C 83 ; WX 556 ; N S ; B 35 -19 513 692 ; +C 84 ; WX 667 ; N T ; B 31 0 636 676 ; +C 85 ; WX 722 ; N U ; B 16 -19 701 676 ; +C 86 ; WX 722 ; N V ; B 16 -18 701 676 ; +C 87 ; WX 1000 ; N W ; B 19 -15 981 676 ; +C 88 ; WX 722 ; N X ; B 16 0 699 676 ; +C 89 ; WX 722 ; N Y ; B 15 0 699 676 ; +C 90 ; WX 667 ; N Z ; B 28 0 634 676 ; +C 91 ; WX 333 ; N bracketleft ; B 67 -149 301 678 ; +C 92 ; WX 278 ; N backslash ; B -25 -19 303 691 ; +C 93 ; WX 333 ; N bracketright ; B 32 -149 266 678 ; +C 94 ; WX 581 ; N asciicircum ; B 73 311 509 676 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 333 ; N quoteleft ; B 70 356 254 691 ; +C 97 ; WX 500 ; N a ; B 25 -14 488 473 ; +C 98 ; WX 556 ; N b ; B 17 -14 521 676 ; +C 99 ; WX 444 ; N c ; B 25 -14 430 473 ; +C 100 ; WX 556 ; N d ; B 25 -14 534 676 ; +C 101 ; WX 444 ; N e ; B 25 -14 426 473 ; +C 102 ; WX 333 ; N f ; B 14 0 389 691 ; L i fi ; L l fl ; +C 103 ; WX 500 ; N g ; B 28 -206 483 473 ; +C 104 ; WX 556 ; N h ; B 16 0 534 676 ; +C 105 ; WX 278 ; N i ; B 16 0 255 691 ; +C 106 ; WX 333 ; N j ; B -57 -203 263 691 ; +C 107 ; WX 556 ; N k ; B 22 0 543 676 ; +C 108 ; WX 278 ; N l ; B 16 0 255 676 ; +C 109 ; WX 833 ; N m ; B 16 0 814 473 ; +C 110 ; WX 556 ; N n ; B 21 0 539 473 ; +C 111 ; WX 500 ; N o ; B 25 -14 476 473 ; +C 112 ; WX 556 ; N p ; B 19 -205 524 473 ; +C 113 ; WX 556 ; N q ; B 34 -205 536 473 ; +C 114 ; WX 444 ; N r ; B 29 0 434 473 ; +C 115 ; WX 389 ; N s ; B 25 -14 361 473 ; +C 116 ; WX 333 ; N t ; B 20 -12 332 630 ; +C 117 ; WX 556 ; N u ; B 16 -14 537 461 ; +C 118 ; WX 500 ; N v ; B 21 -14 485 461 ; +C 119 ; WX 722 ; N w ; B 23 -14 707 461 ; +C 120 ; WX 500 ; N x ; B 12 0 484 461 ; +C 121 ; WX 500 ; N y ; B 16 -205 480 461 ; +C 122 ; WX 444 ; N z ; B 21 0 420 461 ; +C 123 ; WX 394 ; N braceleft ; B 22 -175 340 698 ; +C 124 ; WX 220 ; N bar ; B 66 -218 154 782 ; +C 125 ; WX 394 ; N braceright ; B 54 -175 372 698 ; +C 126 ; WX 520 ; N asciitilde ; B 29 173 491 333 ; +C 161 ; WX 333 ; N exclamdown ; B 82 -203 252 501 ; +C 162 ; WX 500 ; N cent ; B 53 -140 458 588 ; +C 163 ; WX 500 ; N sterling ; B 21 -14 477 684 ; +C 164 ; WX 167 ; N fraction ; B -168 -12 329 688 ; +C 165 ; WX 500 ; N yen ; B -64 0 547 676 ; +C 166 ; WX 500 ; N florin ; B 0 -155 498 706 ; +C 167 ; WX 500 ; N section ; B 57 -132 443 691 ; +C 168 ; WX 500 ; N currency ; B -26 61 526 613 ; +C 169 ; WX 278 ; N quotesingle ; B 75 404 204 691 ; +C 170 ; WX 500 ; N quotedblleft ; B 32 356 486 691 ; +C 171 ; WX 500 ; N guillemotleft ; B 23 36 473 415 ; +C 172 ; WX 333 ; N guilsinglleft ; B 51 36 305 415 ; +C 173 ; WX 333 ; N guilsinglright ; B 28 36 282 415 ; +C 174 ; WX 556 ; N fi ; B 14 0 536 691 ; +C 175 ; WX 556 ; N fl ; B 14 0 536 691 ; +C 177 ; WX 500 ; N endash ; B 0 181 500 271 ; +C 178 ; WX 500 ; N dagger ; B 47 -134 453 691 ; +C 179 ; WX 500 ; N daggerdbl ; B 45 -132 456 691 ; +C 180 ; WX 250 ; N periodcentered ; B 41 248 210 417 ; +C 182 ; WX 540 ; N paragraph ; B 0 -186 519 676 ; +C 183 ; WX 350 ; N bullet ; B 35 198 315 478 ; +C 184 ; WX 333 ; N quotesinglbase ; B 79 -180 263 155 ; +C 185 ; WX 500 ; N quotedblbase ; B 14 -180 468 155 ; +C 186 ; WX 500 ; N quotedblright ; B 14 356 468 691 ; +C 187 ; WX 500 ; N guillemotright ; B 27 36 477 415 ; +C 188 ; WX 1000 ; N ellipsis ; B 82 -13 917 156 ; +C 189 ; WX 1000 ; N perthousand ; B 7 -29 995 706 ; +C 191 ; WX 500 ; N questiondown ; B 55 -201 443 501 ; +C 193 ; WX 333 ; N grave ; B 8 528 246 713 ; +C 194 ; WX 333 ; N acute ; B 86 528 324 713 ; +C 195 ; WX 333 ; N circumflex ; B -2 528 335 704 ; +C 196 ; WX 333 ; N tilde ; B -16 547 349 674 ; +C 197 ; WX 333 ; N macron ; B 1 565 331 637 ; +C 198 ; WX 333 ; N breve ; B 15 528 318 691 ; +C 199 ; WX 333 ; N dotaccent ; B 103 536 258 691 ; +C 200 ; WX 333 ; N dieresis ; B -2 537 335 667 ; +C 202 ; WX 333 ; N ring ; B 60 527 273 740 ; +C 203 ; WX 333 ; N cedilla ; B 68 -218 294 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B -13 528 425 713 ; +C 206 ; WX 333 ; N ogonek ; B 90 -193 319 24 ; +C 207 ; WX 333 ; N caron ; B -2 528 335 704 ; +C 208 ; WX 1000 ; N emdash ; B 0 181 1000 271 ; +C 225 ; WX 1000 ; N AE ; B 4 0 951 676 ; +C 227 ; WX 300 ; N ordfeminine ; B -1 397 301 688 ; +C 232 ; WX 667 ; N Lslash ; B 19 0 638 676 ; +C 233 ; WX 778 ; N Oslash ; B 35 -74 743 737 ; +C 234 ; WX 1000 ; N OE ; B 22 -5 981 684 ; +C 235 ; WX 330 ; N ordmasculine ; B 18 397 312 688 ; +C 241 ; WX 722 ; N ae ; B 33 -14 693 473 ; +C 245 ; WX 278 ; N dotlessi ; B 16 0 255 461 ; +C 248 ; WX 278 ; N lslash ; B -22 0 303 676 ; +C 249 ; WX 500 ; N oslash ; B 25 -92 476 549 ; +C 250 ; WX 722 ; N oe ; B 22 -14 696 473 ; +C 251 ; WX 556 ; N germandbls ; B 19 -12 517 691 ; +C -1 ; WX 389 ; N Idieresis ; B 20 0 370 877 ; +C -1 ; WX 444 ; N eacute ; B 25 -14 426 713 ; +C -1 ; WX 500 ; N abreve ; B 25 -14 488 691 ; +C -1 ; WX 556 ; N uhungarumlaut ; B 16 -14 557 713 ; +C -1 ; WX 444 ; N ecaron ; B 25 -14 426 704 ; +C -1 ; WX 722 ; N Ydieresis ; B 15 0 699 877 ; +C -1 ; WX 570 ; N divide ; B 33 -31 537 537 ; +C -1 ; WX 722 ; N Yacute ; B 15 0 699 923 ; +C -1 ; WX 722 ; N Acircumflex ; B 9 0 689 914 ; +C -1 ; WX 500 ; N aacute ; B 25 -14 488 713 ; +C -1 ; WX 722 ; N Ucircumflex ; B 16 -19 701 914 ; +C -1 ; WX 500 ; N yacute ; B 16 -205 480 713 ; +C -1 ; WX 389 ; N scommaaccent ; B 25 -218 361 473 ; +C -1 ; WX 444 ; N ecircumflex ; B 25 -14 426 704 ; +C -1 ; WX 722 ; N Uring ; B 16 -19 701 935 ; +C -1 ; WX 722 ; N Udieresis ; B 16 -19 701 877 ; +C -1 ; WX 500 ; N aogonek ; B 25 -193 504 473 ; +C -1 ; WX 722 ; N Uacute ; B 16 -19 701 923 ; +C -1 ; WX 556 ; N uogonek ; B 16 -193 539 461 ; +C -1 ; WX 667 ; N Edieresis ; B 16 0 641 877 ; +C -1 ; WX 722 ; N Dcroat ; B 6 0 690 676 ; +C -1 ; WX 250 ; N commaaccent ; B 47 -218 203 -50 ; +C -1 ; WX 747 ; N copyright ; B 26 -19 721 691 ; +C -1 ; WX 667 ; N Emacron ; B 16 0 641 847 ; +C -1 ; WX 444 ; N ccaron ; B 25 -14 430 704 ; +C -1 ; WX 500 ; N aring ; B 25 -14 488 740 ; +C -1 ; WX 722 ; N Ncommaaccent ; B 16 -188 701 676 ; +C -1 ; WX 278 ; N lacute ; B 16 0 297 923 ; +C -1 ; WX 500 ; N agrave ; B 25 -14 488 713 ; +C -1 ; WX 667 ; N Tcommaaccent ; B 31 -218 636 676 ; +C -1 ; WX 722 ; N Cacute ; B 49 -19 687 923 ; +C -1 ; WX 500 ; N atilde ; B 25 -14 488 674 ; +C -1 ; WX 667 ; N Edotaccent ; B 16 0 641 901 ; +C -1 ; WX 389 ; N scaron ; B 25 -14 363 704 ; +C -1 ; WX 389 ; N scedilla ; B 25 -218 361 473 ; +C -1 ; WX 278 ; N iacute ; B 16 0 289 713 ; +C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ; +C -1 ; WX 722 ; N Rcaron ; B 26 0 715 914 ; +C -1 ; WX 778 ; N Gcommaaccent ; B 37 -218 755 691 ; +C -1 ; WX 556 ; N ucircumflex ; B 16 -14 537 704 ; +C -1 ; WX 500 ; N acircumflex ; B 25 -14 488 704 ; +C -1 ; WX 722 ; N Amacron ; B 9 0 689 847 ; +C -1 ; WX 444 ; N rcaron ; B 29 0 434 704 ; +C -1 ; WX 444 ; N ccedilla ; B 25 -218 430 473 ; +C -1 ; WX 667 ; N Zdotaccent ; B 28 0 634 901 ; +C -1 ; WX 611 ; N Thorn ; B 16 0 600 676 ; +C -1 ; WX 778 ; N Omacron ; B 35 -19 743 847 ; +C -1 ; WX 722 ; N Racute ; B 26 0 715 923 ; +C -1 ; WX 556 ; N Sacute ; B 35 -19 513 923 ; +C -1 ; WX 672 ; N dcaron ; B 25 -14 681 682 ; +C -1 ; WX 722 ; N Umacron ; B 16 -19 701 847 ; +C -1 ; WX 556 ; N uring ; B 16 -14 537 740 ; +C -1 ; WX 300 ; N threesuperior ; B 3 268 297 688 ; +C -1 ; WX 778 ; N Ograve ; B 35 -19 743 923 ; +C -1 ; WX 722 ; N Agrave ; B 9 0 689 923 ; +C -1 ; WX 722 ; N Abreve ; B 9 0 689 901 ; +C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ; +C -1 ; WX 556 ; N uacute ; B 16 -14 537 713 ; +C -1 ; WX 667 ; N Tcaron ; B 31 0 636 914 ; +C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ; +C -1 ; WX 500 ; N ydieresis ; B 16 -205 480 667 ; +C -1 ; WX 722 ; N Nacute ; B 16 -18 701 923 ; +C -1 ; WX 278 ; N icircumflex ; B -37 0 300 704 ; +C -1 ; WX 667 ; N Ecircumflex ; B 16 0 641 914 ; +C -1 ; WX 500 ; N adieresis ; B 25 -14 488 667 ; +C -1 ; WX 444 ; N edieresis ; B 25 -14 426 667 ; +C -1 ; WX 444 ; N cacute ; B 25 -14 430 713 ; +C -1 ; WX 556 ; N nacute ; B 21 0 539 713 ; +C -1 ; WX 556 ; N umacron ; B 16 -14 537 637 ; +C -1 ; WX 722 ; N Ncaron ; B 16 -18 701 914 ; +C -1 ; WX 389 ; N Iacute ; B 20 0 370 923 ; +C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ; +C -1 ; WX 220 ; N brokenbar ; B 66 -143 154 707 ; +C -1 ; WX 747 ; N registered ; B 26 -19 721 691 ; +C -1 ; WX 778 ; N Gbreve ; B 37 -19 755 901 ; +C -1 ; WX 389 ; N Idotaccent ; B 20 0 370 901 ; +C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ; +C -1 ; WX 667 ; N Egrave ; B 16 0 641 923 ; +C -1 ; WX 444 ; N racute ; B 29 0 434 713 ; +C -1 ; WX 500 ; N omacron ; B 25 -14 476 637 ; +C -1 ; WX 667 ; N Zacute ; B 28 0 634 923 ; +C -1 ; WX 667 ; N Zcaron ; B 28 0 634 914 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ; +C -1 ; WX 722 ; N Eth ; B 6 0 690 676 ; +C -1 ; WX 722 ; N Ccedilla ; B 49 -218 687 691 ; +C -1 ; WX 278 ; N lcommaaccent ; B 16 -218 255 676 ; +C -1 ; WX 416 ; N tcaron ; B 20 -12 425 815 ; +C -1 ; WX 444 ; N eogonek ; B 25 -193 426 473 ; +C -1 ; WX 722 ; N Uogonek ; B 16 -193 701 676 ; +C -1 ; WX 722 ; N Aacute ; B 9 0 689 923 ; +C -1 ; WX 722 ; N Adieresis ; B 9 0 689 877 ; +C -1 ; WX 444 ; N egrave ; B 25 -14 426 713 ; +C -1 ; WX 444 ; N zacute ; B 21 0 420 713 ; +C -1 ; WX 278 ; N iogonek ; B 16 -193 274 691 ; +C -1 ; WX 778 ; N Oacute ; B 35 -19 743 923 ; +C -1 ; WX 500 ; N oacute ; B 25 -14 476 713 ; +C -1 ; WX 500 ; N amacron ; B 25 -14 488 637 ; +C -1 ; WX 389 ; N sacute ; B 25 -14 361 713 ; +C -1 ; WX 278 ; N idieresis ; B -37 0 300 667 ; +C -1 ; WX 778 ; N Ocircumflex ; B 35 -19 743 914 ; +C -1 ; WX 722 ; N Ugrave ; B 16 -19 701 923 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 556 ; N thorn ; B 19 -205 524 676 ; +C -1 ; WX 300 ; N twosuperior ; B 0 275 300 688 ; +C -1 ; WX 778 ; N Odieresis ; B 35 -19 743 877 ; +C -1 ; WX 556 ; N mu ; B 33 -206 536 461 ; +C -1 ; WX 278 ; N igrave ; B -27 0 255 713 ; +C -1 ; WX 500 ; N ohungarumlaut ; B 25 -14 529 713 ; +C -1 ; WX 667 ; N Eogonek ; B 16 -193 644 676 ; +C -1 ; WX 556 ; N dcroat ; B 25 -14 534 676 ; +C -1 ; WX 750 ; N threequarters ; B 23 -12 733 688 ; +C -1 ; WX 556 ; N Scedilla ; B 35 -218 513 692 ; +C -1 ; WX 394 ; N lcaron ; B 16 0 412 682 ; +C -1 ; WX 778 ; N Kcommaaccent ; B 30 -218 769 676 ; +C -1 ; WX 667 ; N Lacute ; B 19 0 638 923 ; +C -1 ; WX 1000 ; N trademark ; B 24 271 977 676 ; +C -1 ; WX 444 ; N edotaccent ; B 25 -14 426 691 ; +C -1 ; WX 389 ; N Igrave ; B 20 0 370 923 ; +C -1 ; WX 389 ; N Imacron ; B 20 0 370 847 ; +C -1 ; WX 667 ; N Lcaron ; B 19 0 652 682 ; +C -1 ; WX 750 ; N onehalf ; B -7 -12 775 688 ; +C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ; +C -1 ; WX 500 ; N ocircumflex ; B 25 -14 476 704 ; +C -1 ; WX 556 ; N ntilde ; B 21 0 539 674 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 16 -19 701 923 ; +C -1 ; WX 667 ; N Eacute ; B 16 0 641 923 ; +C -1 ; WX 444 ; N emacron ; B 25 -14 426 637 ; +C -1 ; WX 500 ; N gbreve ; B 28 -206 483 691 ; +C -1 ; WX 750 ; N onequarter ; B 28 -12 743 688 ; +C -1 ; WX 556 ; N Scaron ; B 35 -19 513 914 ; +C -1 ; WX 556 ; N Scommaaccent ; B 35 -218 513 692 ; +C -1 ; WX 778 ; N Ohungarumlaut ; B 35 -19 743 923 ; +C -1 ; WX 400 ; N degree ; B 57 402 343 688 ; +C -1 ; WX 500 ; N ograve ; B 25 -14 476 713 ; +C -1 ; WX 722 ; N Ccaron ; B 49 -19 687 914 ; +C -1 ; WX 556 ; N ugrave ; B 16 -14 537 713 ; +C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ; +C -1 ; WX 722 ; N Dcaron ; B 14 0 690 914 ; +C -1 ; WX 444 ; N rcommaaccent ; B 29 -218 434 473 ; +C -1 ; WX 722 ; N Ntilde ; B 16 -18 701 884 ; +C -1 ; WX 500 ; N otilde ; B 25 -14 476 674 ; +C -1 ; WX 722 ; N Rcommaaccent ; B 26 -218 715 676 ; +C -1 ; WX 667 ; N Lcommaaccent ; B 19 -218 638 676 ; +C -1 ; WX 722 ; N Atilde ; B 9 0 689 884 ; +C -1 ; WX 722 ; N Aogonek ; B 9 -193 699 690 ; +C -1 ; WX 722 ; N Aring ; B 9 0 689 935 ; +C -1 ; WX 778 ; N Otilde ; B 35 -19 743 884 ; +C -1 ; WX 444 ; N zdotaccent ; B 21 0 420 691 ; +C -1 ; WX 667 ; N Ecaron ; B 16 0 641 914 ; +C -1 ; WX 389 ; N Iogonek ; B 20 -193 370 676 ; +C -1 ; WX 556 ; N kcommaaccent ; B 22 -218 543 676 ; +C -1 ; WX 570 ; N minus ; B 33 209 537 297 ; +C -1 ; WX 389 ; N Icircumflex ; B 20 0 370 914 ; +C -1 ; WX 556 ; N ncaron ; B 21 0 539 704 ; +C -1 ; WX 333 ; N tcommaaccent ; B 20 -218 332 630 ; +C -1 ; WX 570 ; N logicalnot ; B 33 108 537 399 ; +C -1 ; WX 500 ; N odieresis ; B 25 -14 476 667 ; +C -1 ; WX 556 ; N udieresis ; B 16 -14 537 667 ; +C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ; +C -1 ; WX 500 ; N gcommaaccent ; B 28 -206 483 829 ; +C -1 ; WX 500 ; N eth ; B 25 -14 476 691 ; +C -1 ; WX 444 ; N zcaron ; B 21 0 420 704 ; +C -1 ; WX 556 ; N ncommaaccent ; B 21 -218 539 473 ; +C -1 ; WX 300 ; N onesuperior ; B 28 275 273 688 ; +C -1 ; WX 278 ; N imacron ; B -8 0 272 637 ; +C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2242 +KPX A C -55 +KPX A Cacute -55 +KPX A Ccaron -55 +KPX A Ccedilla -55 +KPX A G -55 +KPX A Gbreve -55 +KPX A Gcommaaccent -55 +KPX A O -45 +KPX A Oacute -45 +KPX A Ocircumflex -45 +KPX A Odieresis -45 +KPX A Ograve -45 +KPX A Ohungarumlaut -45 +KPX A Omacron -45 +KPX A Oslash -45 +KPX A Otilde -45 +KPX A Q -45 +KPX A T -95 +KPX A Tcaron -95 +KPX A Tcommaaccent -95 +KPX A U -50 +KPX A Uacute -50 +KPX A Ucircumflex -50 +KPX A Udieresis -50 +KPX A Ugrave -50 +KPX A Uhungarumlaut -50 +KPX A Umacron -50 +KPX A Uogonek -50 +KPX A Uring -50 +KPX A V -145 +KPX A W -130 +KPX A Y -100 +KPX A Yacute -100 +KPX A Ydieresis -100 +KPX A p -25 +KPX A quoteright -74 +KPX A u -50 +KPX A uacute -50 +KPX A ucircumflex -50 +KPX A udieresis -50 +KPX A ugrave -50 +KPX A uhungarumlaut -50 +KPX A umacron -50 +KPX A uogonek -50 +KPX A uring -50 +KPX A v -100 +KPX A w -90 +KPX A y -74 +KPX A yacute -74 +KPX A ydieresis -74 +KPX Aacute C -55 +KPX Aacute Cacute -55 +KPX Aacute Ccaron -55 +KPX Aacute Ccedilla -55 +KPX Aacute G -55 +KPX Aacute Gbreve -55 +KPX Aacute Gcommaaccent -55 +KPX Aacute O -45 +KPX Aacute Oacute -45 +KPX Aacute Ocircumflex -45 +KPX Aacute Odieresis -45 +KPX Aacute Ograve -45 +KPX Aacute Ohungarumlaut -45 +KPX Aacute Omacron -45 +KPX Aacute Oslash -45 +KPX Aacute Otilde -45 +KPX Aacute Q -45 +KPX Aacute T -95 +KPX Aacute Tcaron -95 +KPX Aacute Tcommaaccent -95 +KPX Aacute U -50 +KPX Aacute Uacute -50 +KPX Aacute Ucircumflex -50 +KPX Aacute Udieresis -50 +KPX Aacute Ugrave -50 +KPX Aacute Uhungarumlaut -50 +KPX Aacute Umacron -50 +KPX Aacute Uogonek -50 +KPX Aacute Uring -50 +KPX Aacute V -145 +KPX Aacute W -130 +KPX Aacute Y -100 +KPX Aacute Yacute -100 +KPX Aacute Ydieresis -100 +KPX Aacute p -25 +KPX Aacute quoteright -74 +KPX Aacute u -50 +KPX Aacute uacute -50 +KPX Aacute ucircumflex -50 +KPX Aacute udieresis -50 +KPX Aacute ugrave -50 +KPX Aacute uhungarumlaut -50 +KPX Aacute umacron -50 +KPX Aacute uogonek -50 +KPX Aacute uring -50 +KPX Aacute v -100 +KPX Aacute w -90 +KPX Aacute y -74 +KPX Aacute yacute -74 +KPX Aacute ydieresis -74 +KPX Abreve C -55 +KPX Abreve Cacute -55 +KPX Abreve Ccaron -55 +KPX Abreve Ccedilla -55 +KPX Abreve G -55 +KPX Abreve Gbreve -55 +KPX Abreve Gcommaaccent -55 +KPX Abreve O -45 +KPX Abreve Oacute -45 +KPX Abreve Ocircumflex -45 +KPX Abreve Odieresis -45 +KPX Abreve Ograve -45 +KPX Abreve Ohungarumlaut -45 +KPX Abreve Omacron -45 +KPX Abreve Oslash -45 +KPX Abreve Otilde -45 +KPX Abreve Q -45 +KPX Abreve T -95 +KPX Abreve Tcaron -95 +KPX Abreve Tcommaaccent -95 +KPX Abreve U -50 +KPX Abreve Uacute -50 +KPX Abreve Ucircumflex -50 +KPX Abreve Udieresis -50 +KPX Abreve Ugrave -50 +KPX Abreve Uhungarumlaut -50 +KPX Abreve Umacron -50 +KPX Abreve Uogonek -50 +KPX Abreve Uring -50 +KPX Abreve V -145 +KPX Abreve W -130 +KPX Abreve Y -100 +KPX Abreve Yacute -100 +KPX Abreve Ydieresis -100 +KPX Abreve p -25 +KPX Abreve quoteright -74 +KPX Abreve u -50 +KPX Abreve uacute -50 +KPX Abreve ucircumflex -50 +KPX Abreve udieresis -50 +KPX Abreve ugrave -50 +KPX Abreve uhungarumlaut -50 +KPX Abreve umacron -50 +KPX Abreve uogonek -50 +KPX Abreve uring -50 +KPX Abreve v -100 +KPX Abreve w -90 +KPX Abreve y -74 +KPX Abreve yacute -74 +KPX Abreve ydieresis -74 +KPX Acircumflex C -55 +KPX Acircumflex Cacute -55 +KPX Acircumflex Ccaron -55 +KPX Acircumflex Ccedilla -55 +KPX Acircumflex G -55 +KPX Acircumflex Gbreve -55 +KPX Acircumflex Gcommaaccent -55 +KPX Acircumflex O -45 +KPX Acircumflex Oacute -45 +KPX Acircumflex Ocircumflex -45 +KPX Acircumflex Odieresis -45 +KPX Acircumflex Ograve -45 +KPX Acircumflex Ohungarumlaut -45 +KPX Acircumflex Omacron -45 +KPX Acircumflex Oslash -45 +KPX Acircumflex Otilde -45 +KPX Acircumflex Q -45 +KPX Acircumflex T -95 +KPX Acircumflex Tcaron -95 +KPX Acircumflex Tcommaaccent -95 +KPX Acircumflex U -50 +KPX Acircumflex Uacute -50 +KPX Acircumflex Ucircumflex -50 +KPX Acircumflex Udieresis -50 +KPX Acircumflex Ugrave -50 +KPX Acircumflex Uhungarumlaut -50 +KPX Acircumflex Umacron -50 +KPX Acircumflex Uogonek -50 +KPX Acircumflex Uring -50 +KPX Acircumflex V -145 +KPX Acircumflex W -130 +KPX Acircumflex Y -100 +KPX Acircumflex Yacute -100 +KPX Acircumflex Ydieresis -100 +KPX Acircumflex p -25 +KPX Acircumflex quoteright -74 +KPX Acircumflex u -50 +KPX Acircumflex uacute -50 +KPX Acircumflex ucircumflex -50 +KPX Acircumflex udieresis -50 +KPX Acircumflex ugrave -50 +KPX Acircumflex uhungarumlaut -50 +KPX Acircumflex umacron -50 +KPX Acircumflex uogonek -50 +KPX Acircumflex uring -50 +KPX Acircumflex v -100 +KPX Acircumflex w -90 +KPX Acircumflex y -74 +KPX Acircumflex yacute -74 +KPX Acircumflex ydieresis -74 +KPX Adieresis C -55 +KPX Adieresis Cacute -55 +KPX Adieresis Ccaron -55 +KPX Adieresis Ccedilla -55 +KPX Adieresis G -55 +KPX Adieresis Gbreve -55 +KPX Adieresis Gcommaaccent -55 +KPX Adieresis O -45 +KPX Adieresis Oacute -45 +KPX Adieresis Ocircumflex -45 +KPX Adieresis Odieresis -45 +KPX Adieresis Ograve -45 +KPX Adieresis Ohungarumlaut -45 +KPX Adieresis Omacron -45 +KPX Adieresis Oslash -45 +KPX Adieresis Otilde -45 +KPX Adieresis Q -45 +KPX Adieresis T -95 +KPX Adieresis Tcaron -95 +KPX Adieresis Tcommaaccent -95 +KPX Adieresis U -50 +KPX Adieresis Uacute -50 +KPX Adieresis Ucircumflex -50 +KPX Adieresis Udieresis -50 +KPX Adieresis Ugrave -50 +KPX Adieresis Uhungarumlaut -50 +KPX Adieresis Umacron -50 +KPX Adieresis Uogonek -50 +KPX Adieresis Uring -50 +KPX Adieresis V -145 +KPX Adieresis W -130 +KPX Adieresis Y -100 +KPX Adieresis Yacute -100 +KPX Adieresis Ydieresis -100 +KPX Adieresis p -25 +KPX Adieresis quoteright -74 +KPX Adieresis u -50 +KPX Adieresis uacute -50 +KPX Adieresis ucircumflex -50 +KPX Adieresis udieresis -50 +KPX Adieresis ugrave -50 +KPX Adieresis uhungarumlaut -50 +KPX Adieresis umacron -50 +KPX Adieresis uogonek -50 +KPX Adieresis uring -50 +KPX Adieresis v -100 +KPX Adieresis w -90 +KPX Adieresis y -74 +KPX Adieresis yacute -74 +KPX Adieresis ydieresis -74 +KPX Agrave C -55 +KPX Agrave Cacute -55 +KPX Agrave Ccaron -55 +KPX Agrave Ccedilla -55 +KPX Agrave G -55 +KPX Agrave Gbreve -55 +KPX Agrave Gcommaaccent -55 +KPX Agrave O -45 +KPX Agrave Oacute -45 +KPX Agrave Ocircumflex -45 +KPX Agrave Odieresis -45 +KPX Agrave Ograve -45 +KPX Agrave Ohungarumlaut -45 +KPX Agrave Omacron -45 +KPX Agrave Oslash -45 +KPX Agrave Otilde -45 +KPX Agrave Q -45 +KPX Agrave T -95 +KPX Agrave Tcaron -95 +KPX Agrave Tcommaaccent -95 +KPX Agrave U -50 +KPX Agrave Uacute -50 +KPX Agrave Ucircumflex -50 +KPX Agrave Udieresis -50 +KPX Agrave Ugrave -50 +KPX Agrave Uhungarumlaut -50 +KPX Agrave Umacron -50 +KPX Agrave Uogonek -50 +KPX Agrave Uring -50 +KPX Agrave V -145 +KPX Agrave W -130 +KPX Agrave Y -100 +KPX Agrave Yacute -100 +KPX Agrave Ydieresis -100 +KPX Agrave p -25 +KPX Agrave quoteright -74 +KPX Agrave u -50 +KPX Agrave uacute -50 +KPX Agrave ucircumflex -50 +KPX Agrave udieresis -50 +KPX Agrave ugrave -50 +KPX Agrave uhungarumlaut -50 +KPX Agrave umacron -50 +KPX Agrave uogonek -50 +KPX Agrave uring -50 +KPX Agrave v -100 +KPX Agrave w -90 +KPX Agrave y -74 +KPX Agrave yacute -74 +KPX Agrave ydieresis -74 +KPX Amacron C -55 +KPX Amacron Cacute -55 +KPX Amacron Ccaron -55 +KPX Amacron Ccedilla -55 +KPX Amacron G -55 +KPX Amacron Gbreve -55 +KPX Amacron Gcommaaccent -55 +KPX Amacron O -45 +KPX Amacron Oacute -45 +KPX Amacron Ocircumflex -45 +KPX Amacron Odieresis -45 +KPX Amacron Ograve -45 +KPX Amacron Ohungarumlaut -45 +KPX Amacron Omacron -45 +KPX Amacron Oslash -45 +KPX Amacron Otilde -45 +KPX Amacron Q -45 +KPX Amacron T -95 +KPX Amacron Tcaron -95 +KPX Amacron Tcommaaccent -95 +KPX Amacron U -50 +KPX Amacron Uacute -50 +KPX Amacron Ucircumflex -50 +KPX Amacron Udieresis -50 +KPX Amacron Ugrave -50 +KPX Amacron Uhungarumlaut -50 +KPX Amacron Umacron -50 +KPX Amacron Uogonek -50 +KPX Amacron Uring -50 +KPX Amacron V -145 +KPX Amacron W -130 +KPX Amacron Y -100 +KPX Amacron Yacute -100 +KPX Amacron Ydieresis -100 +KPX Amacron p -25 +KPX Amacron quoteright -74 +KPX Amacron u -50 +KPX Amacron uacute -50 +KPX Amacron ucircumflex -50 +KPX Amacron udieresis -50 +KPX Amacron ugrave -50 +KPX Amacron uhungarumlaut -50 +KPX Amacron umacron -50 +KPX Amacron uogonek -50 +KPX Amacron uring -50 +KPX Amacron v -100 +KPX Amacron w -90 +KPX Amacron y -74 +KPX Amacron yacute -74 +KPX Amacron ydieresis -74 +KPX Aogonek C -55 +KPX Aogonek Cacute -55 +KPX Aogonek Ccaron -55 +KPX Aogonek Ccedilla -55 +KPX Aogonek G -55 +KPX Aogonek Gbreve -55 +KPX Aogonek Gcommaaccent -55 +KPX Aogonek O -45 +KPX Aogonek Oacute -45 +KPX Aogonek Ocircumflex -45 +KPX Aogonek Odieresis -45 +KPX Aogonek Ograve -45 +KPX Aogonek Ohungarumlaut -45 +KPX Aogonek Omacron -45 +KPX Aogonek Oslash -45 +KPX Aogonek Otilde -45 +KPX Aogonek Q -45 +KPX Aogonek T -95 +KPX Aogonek Tcaron -95 +KPX Aogonek Tcommaaccent -95 +KPX Aogonek U -50 +KPX Aogonek Uacute -50 +KPX Aogonek Ucircumflex -50 +KPX Aogonek Udieresis -50 +KPX Aogonek Ugrave -50 +KPX Aogonek Uhungarumlaut -50 +KPX Aogonek Umacron -50 +KPX Aogonek Uogonek -50 +KPX Aogonek Uring -50 +KPX Aogonek V -145 +KPX Aogonek W -130 +KPX Aogonek Y -100 +KPX Aogonek Yacute -100 +KPX Aogonek Ydieresis -100 +KPX Aogonek p -25 +KPX Aogonek quoteright -74 +KPX Aogonek u -50 +KPX Aogonek uacute -50 +KPX Aogonek ucircumflex -50 +KPX Aogonek udieresis -50 +KPX Aogonek ugrave -50 +KPX Aogonek uhungarumlaut -50 +KPX Aogonek umacron -50 +KPX Aogonek uogonek -50 +KPX Aogonek uring -50 +KPX Aogonek v -100 +KPX Aogonek w -90 +KPX Aogonek y -34 +KPX Aogonek yacute -34 +KPX Aogonek ydieresis -34 +KPX Aring C -55 +KPX Aring Cacute -55 +KPX Aring Ccaron -55 +KPX Aring Ccedilla -55 +KPX Aring G -55 +KPX Aring Gbreve -55 +KPX Aring Gcommaaccent -55 +KPX Aring O -45 +KPX Aring Oacute -45 +KPX Aring Ocircumflex -45 +KPX Aring Odieresis -45 +KPX Aring Ograve -45 +KPX Aring Ohungarumlaut -45 +KPX Aring Omacron -45 +KPX Aring Oslash -45 +KPX Aring Otilde -45 +KPX Aring Q -45 +KPX Aring T -95 +KPX Aring Tcaron -95 +KPX Aring Tcommaaccent -95 +KPX Aring U -50 +KPX Aring Uacute -50 +KPX Aring Ucircumflex -50 +KPX Aring Udieresis -50 +KPX Aring Ugrave -50 +KPX Aring Uhungarumlaut -50 +KPX Aring Umacron -50 +KPX Aring Uogonek -50 +KPX Aring Uring -50 +KPX Aring V -145 +KPX Aring W -130 +KPX Aring Y -100 +KPX Aring Yacute -100 +KPX Aring Ydieresis -100 +KPX Aring p -25 +KPX Aring quoteright -74 +KPX Aring u -50 +KPX Aring uacute -50 +KPX Aring ucircumflex -50 +KPX Aring udieresis -50 +KPX Aring ugrave -50 +KPX Aring uhungarumlaut -50 +KPX Aring umacron -50 +KPX Aring uogonek -50 +KPX Aring uring -50 +KPX Aring v -100 +KPX Aring w -90 +KPX Aring y -74 +KPX Aring yacute -74 +KPX Aring ydieresis -74 +KPX Atilde C -55 +KPX Atilde Cacute -55 +KPX Atilde Ccaron -55 +KPX Atilde Ccedilla -55 +KPX Atilde G -55 +KPX Atilde Gbreve -55 +KPX Atilde Gcommaaccent -55 +KPX Atilde O -45 +KPX Atilde Oacute -45 +KPX Atilde Ocircumflex -45 +KPX Atilde Odieresis -45 +KPX Atilde Ograve -45 +KPX Atilde Ohungarumlaut -45 +KPX Atilde Omacron -45 +KPX Atilde Oslash -45 +KPX Atilde Otilde -45 +KPX Atilde Q -45 +KPX Atilde T -95 +KPX Atilde Tcaron -95 +KPX Atilde Tcommaaccent -95 +KPX Atilde U -50 +KPX Atilde Uacute -50 +KPX Atilde Ucircumflex -50 +KPX Atilde Udieresis -50 +KPX Atilde Ugrave -50 +KPX Atilde Uhungarumlaut -50 +KPX Atilde Umacron -50 +KPX Atilde Uogonek -50 +KPX Atilde Uring -50 +KPX Atilde V -145 +KPX Atilde W -130 +KPX Atilde Y -100 +KPX Atilde Yacute -100 +KPX Atilde Ydieresis -100 +KPX Atilde p -25 +KPX Atilde quoteright -74 +KPX Atilde u -50 +KPX Atilde uacute -50 +KPX Atilde ucircumflex -50 +KPX Atilde udieresis -50 +KPX Atilde ugrave -50 +KPX Atilde uhungarumlaut -50 +KPX Atilde umacron -50 +KPX Atilde uogonek -50 +KPX Atilde uring -50 +KPX Atilde v -100 +KPX Atilde w -90 +KPX Atilde y -74 +KPX Atilde yacute -74 +KPX Atilde ydieresis -74 +KPX B A -30 +KPX B Aacute -30 +KPX B Abreve -30 +KPX B Acircumflex -30 +KPX B Adieresis -30 +KPX B Agrave -30 +KPX B Amacron -30 +KPX B Aogonek -30 +KPX B Aring -30 +KPX B Atilde -30 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX D A -35 +KPX D Aacute -35 +KPX D Abreve -35 +KPX D Acircumflex -35 +KPX D Adieresis -35 +KPX D Agrave -35 +KPX D Amacron -35 +KPX D Aogonek -35 +KPX D Aring -35 +KPX D Atilde -35 +KPX D V -40 +KPX D W -40 +KPX D Y -40 +KPX D Yacute -40 +KPX D Ydieresis -40 +KPX D period -20 +KPX Dcaron A -35 +KPX Dcaron Aacute -35 +KPX Dcaron Abreve -35 +KPX Dcaron Acircumflex -35 +KPX Dcaron Adieresis -35 +KPX Dcaron Agrave -35 +KPX Dcaron Amacron -35 +KPX Dcaron Aogonek -35 +KPX Dcaron Aring -35 +KPX Dcaron Atilde -35 +KPX Dcaron V -40 +KPX Dcaron W -40 +KPX Dcaron Y -40 +KPX Dcaron Yacute -40 +KPX Dcaron Ydieresis -40 +KPX Dcaron period -20 +KPX Dcroat A -35 +KPX Dcroat Aacute -35 +KPX Dcroat Abreve -35 +KPX Dcroat Acircumflex -35 +KPX Dcroat Adieresis -35 +KPX Dcroat Agrave -35 +KPX Dcroat Amacron -35 +KPX Dcroat Aogonek -35 +KPX Dcroat Aring -35 +KPX Dcroat Atilde -35 +KPX Dcroat V -40 +KPX Dcroat W -40 +KPX Dcroat Y -40 +KPX Dcroat Yacute -40 +KPX Dcroat Ydieresis -40 +KPX Dcroat period -20 +KPX F A -90 +KPX F Aacute -90 +KPX F Abreve -90 +KPX F Acircumflex -90 +KPX F Adieresis -90 +KPX F Agrave -90 +KPX F Amacron -90 +KPX F Aogonek -90 +KPX F Aring -90 +KPX F Atilde -90 +KPX F a -25 +KPX F aacute -25 +KPX F abreve -25 +KPX F acircumflex -25 +KPX F adieresis -25 +KPX F agrave -25 +KPX F amacron -25 +KPX F aogonek -25 +KPX F aring -25 +KPX F atilde -25 +KPX F comma -92 +KPX F e -25 +KPX F eacute -25 +KPX F ecaron -25 +KPX F ecircumflex -25 +KPX F edieresis -25 +KPX F edotaccent -25 +KPX F egrave -25 +KPX F emacron -25 +KPX F eogonek -25 +KPX F o -25 +KPX F oacute -25 +KPX F ocircumflex -25 +KPX F odieresis -25 +KPX F ograve -25 +KPX F ohungarumlaut -25 +KPX F omacron -25 +KPX F oslash -25 +KPX F otilde -25 +KPX F period -110 +KPX J A -30 +KPX J Aacute -30 +KPX J Abreve -30 +KPX J Acircumflex -30 +KPX J Adieresis -30 +KPX J Agrave -30 +KPX J Amacron -30 +KPX J Aogonek -30 +KPX J Aring -30 +KPX J Atilde -30 +KPX J a -15 +KPX J aacute -15 +KPX J abreve -15 +KPX J acircumflex -15 +KPX J adieresis -15 +KPX J agrave -15 +KPX J amacron -15 +KPX J aogonek -15 +KPX J aring -15 +KPX J atilde -15 +KPX J e -15 +KPX J eacute -15 +KPX J ecaron -15 +KPX J ecircumflex -15 +KPX J edieresis -15 +KPX J edotaccent -15 +KPX J egrave -15 +KPX J emacron -15 +KPX J eogonek -15 +KPX J o -15 +KPX J oacute -15 +KPX J ocircumflex -15 +KPX J odieresis -15 +KPX J ograve -15 +KPX J ohungarumlaut -15 +KPX J omacron -15 +KPX J oslash -15 +KPX J otilde -15 +KPX J period -20 +KPX J u -15 +KPX J uacute -15 +KPX J ucircumflex -15 +KPX J udieresis -15 +KPX J ugrave -15 +KPX J uhungarumlaut -15 +KPX J umacron -15 +KPX J uogonek -15 +KPX J uring -15 +KPX K O -30 +KPX K Oacute -30 +KPX K Ocircumflex -30 +KPX K Odieresis -30 +KPX K Ograve -30 +KPX K Ohungarumlaut -30 +KPX K Omacron -30 +KPX K Oslash -30 +KPX K Otilde -30 +KPX K e -25 +KPX K eacute -25 +KPX K ecaron -25 +KPX K ecircumflex -25 +KPX K edieresis -25 +KPX K edotaccent -25 +KPX K egrave -25 +KPX K emacron -25 +KPX K eogonek -25 +KPX K o -25 +KPX K oacute -25 +KPX K ocircumflex -25 +KPX K odieresis -25 +KPX K ograve -25 +KPX K ohungarumlaut -25 +KPX K omacron -25 +KPX K oslash -25 +KPX K otilde -25 +KPX K u -15 +KPX K uacute -15 +KPX K ucircumflex -15 +KPX K udieresis -15 +KPX K ugrave -15 +KPX K uhungarumlaut -15 +KPX K umacron -15 +KPX K uogonek -15 +KPX K uring -15 +KPX K y -45 +KPX K yacute -45 +KPX K ydieresis -45 +KPX Kcommaaccent O -30 +KPX Kcommaaccent Oacute -30 +KPX Kcommaaccent Ocircumflex -30 +KPX Kcommaaccent Odieresis -30 +KPX Kcommaaccent Ograve -30 +KPX Kcommaaccent Ohungarumlaut -30 +KPX Kcommaaccent Omacron -30 +KPX Kcommaaccent Oslash -30 +KPX Kcommaaccent Otilde -30 +KPX Kcommaaccent e -25 +KPX Kcommaaccent eacute -25 +KPX Kcommaaccent ecaron -25 +KPX Kcommaaccent ecircumflex -25 +KPX Kcommaaccent edieresis -25 +KPX Kcommaaccent edotaccent -25 +KPX Kcommaaccent egrave -25 +KPX Kcommaaccent emacron -25 +KPX Kcommaaccent eogonek -25 +KPX Kcommaaccent o -25 +KPX Kcommaaccent oacute -25 +KPX Kcommaaccent ocircumflex -25 +KPX Kcommaaccent odieresis -25 +KPX Kcommaaccent ograve -25 +KPX Kcommaaccent ohungarumlaut -25 +KPX Kcommaaccent omacron -25 +KPX Kcommaaccent oslash -25 +KPX Kcommaaccent otilde -25 +KPX Kcommaaccent u -15 +KPX Kcommaaccent uacute -15 +KPX Kcommaaccent ucircumflex -15 +KPX Kcommaaccent udieresis -15 +KPX Kcommaaccent ugrave -15 +KPX Kcommaaccent uhungarumlaut -15 +KPX Kcommaaccent umacron -15 +KPX Kcommaaccent uogonek -15 +KPX Kcommaaccent uring -15 +KPX Kcommaaccent y -45 +KPX Kcommaaccent yacute -45 +KPX Kcommaaccent ydieresis -45 +KPX L T -92 +KPX L Tcaron -92 +KPX L Tcommaaccent -92 +KPX L V -92 +KPX L W -92 +KPX L Y -92 +KPX L Yacute -92 +KPX L Ydieresis -92 +KPX L quotedblright -20 +KPX L quoteright -110 +KPX L y -55 +KPX L yacute -55 +KPX L ydieresis -55 +KPX Lacute T -92 +KPX Lacute Tcaron -92 +KPX Lacute Tcommaaccent -92 +KPX Lacute V -92 +KPX Lacute W -92 +KPX Lacute Y -92 +KPX Lacute Yacute -92 +KPX Lacute Ydieresis -92 +KPX Lacute quotedblright -20 +KPX Lacute quoteright -110 +KPX Lacute y -55 +KPX Lacute yacute -55 +KPX Lacute ydieresis -55 +KPX Lcommaaccent T -92 +KPX Lcommaaccent Tcaron -92 +KPX Lcommaaccent Tcommaaccent -92 +KPX Lcommaaccent V -92 +KPX Lcommaaccent W -92 +KPX Lcommaaccent Y -92 +KPX Lcommaaccent Yacute -92 +KPX Lcommaaccent Ydieresis -92 +KPX Lcommaaccent quotedblright -20 +KPX Lcommaaccent quoteright -110 +KPX Lcommaaccent y -55 +KPX Lcommaaccent yacute -55 +KPX Lcommaaccent ydieresis -55 +KPX Lslash T -92 +KPX Lslash Tcaron -92 +KPX Lslash Tcommaaccent -92 +KPX Lslash V -92 +KPX Lslash W -92 +KPX Lslash Y -92 +KPX Lslash Yacute -92 +KPX Lslash Ydieresis -92 +KPX Lslash quotedblright -20 +KPX Lslash quoteright -110 +KPX Lslash y -55 +KPX Lslash yacute -55 +KPX Lslash ydieresis -55 +KPX N A -20 +KPX N Aacute -20 +KPX N Abreve -20 +KPX N Acircumflex -20 +KPX N Adieresis -20 +KPX N Agrave -20 +KPX N Amacron -20 +KPX N Aogonek -20 +KPX N Aring -20 +KPX N Atilde -20 +KPX Nacute A -20 +KPX Nacute Aacute -20 +KPX Nacute Abreve -20 +KPX Nacute Acircumflex -20 +KPX Nacute Adieresis -20 +KPX Nacute Agrave -20 +KPX Nacute Amacron -20 +KPX Nacute Aogonek -20 +KPX Nacute Aring -20 +KPX Nacute Atilde -20 +KPX Ncaron A -20 +KPX Ncaron Aacute -20 +KPX Ncaron Abreve -20 +KPX Ncaron Acircumflex -20 +KPX Ncaron Adieresis -20 +KPX Ncaron Agrave -20 +KPX Ncaron Amacron -20 +KPX Ncaron Aogonek -20 +KPX Ncaron Aring -20 +KPX Ncaron Atilde -20 +KPX Ncommaaccent A -20 +KPX Ncommaaccent Aacute -20 +KPX Ncommaaccent Abreve -20 +KPX Ncommaaccent Acircumflex -20 +KPX Ncommaaccent Adieresis -20 +KPX Ncommaaccent Agrave -20 +KPX Ncommaaccent Amacron -20 +KPX Ncommaaccent Aogonek -20 +KPX Ncommaaccent Aring -20 +KPX Ncommaaccent Atilde -20 +KPX Ntilde A -20 +KPX Ntilde Aacute -20 +KPX Ntilde Abreve -20 +KPX Ntilde Acircumflex -20 +KPX Ntilde Adieresis -20 +KPX Ntilde Agrave -20 +KPX Ntilde Amacron -20 +KPX Ntilde Aogonek -20 +KPX Ntilde Aring -20 +KPX Ntilde Atilde -20 +KPX O A -40 +KPX O Aacute -40 +KPX O Abreve -40 +KPX O Acircumflex -40 +KPX O Adieresis -40 +KPX O Agrave -40 +KPX O Amacron -40 +KPX O Aogonek -40 +KPX O Aring -40 +KPX O Atilde -40 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -50 +KPX O X -40 +KPX O Y -50 +KPX O Yacute -50 +KPX O Ydieresis -50 +KPX Oacute A -40 +KPX Oacute Aacute -40 +KPX Oacute Abreve -40 +KPX Oacute Acircumflex -40 +KPX Oacute Adieresis -40 +KPX Oacute Agrave -40 +KPX Oacute Amacron -40 +KPX Oacute Aogonek -40 +KPX Oacute Aring -40 +KPX Oacute Atilde -40 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -50 +KPX Oacute X -40 +KPX Oacute Y -50 +KPX Oacute Yacute -50 +KPX Oacute Ydieresis -50 +KPX Ocircumflex A -40 +KPX Ocircumflex Aacute -40 +KPX Ocircumflex Abreve -40 +KPX Ocircumflex Acircumflex -40 +KPX Ocircumflex Adieresis -40 +KPX Ocircumflex Agrave -40 +KPX Ocircumflex Amacron -40 +KPX Ocircumflex Aogonek -40 +KPX Ocircumflex Aring -40 +KPX Ocircumflex Atilde -40 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -50 +KPX Ocircumflex X -40 +KPX Ocircumflex Y -50 +KPX Ocircumflex Yacute -50 +KPX Ocircumflex Ydieresis -50 +KPX Odieresis A -40 +KPX Odieresis Aacute -40 +KPX Odieresis Abreve -40 +KPX Odieresis Acircumflex -40 +KPX Odieresis Adieresis -40 +KPX Odieresis Agrave -40 +KPX Odieresis Amacron -40 +KPX Odieresis Aogonek -40 +KPX Odieresis Aring -40 +KPX Odieresis Atilde -40 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -50 +KPX Odieresis X -40 +KPX Odieresis Y -50 +KPX Odieresis Yacute -50 +KPX Odieresis Ydieresis -50 +KPX Ograve A -40 +KPX Ograve Aacute -40 +KPX Ograve Abreve -40 +KPX Ograve Acircumflex -40 +KPX Ograve Adieresis -40 +KPX Ograve Agrave -40 +KPX Ograve Amacron -40 +KPX Ograve Aogonek -40 +KPX Ograve Aring -40 +KPX Ograve Atilde -40 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -50 +KPX Ograve X -40 +KPX Ograve Y -50 +KPX Ograve Yacute -50 +KPX Ograve Ydieresis -50 +KPX Ohungarumlaut A -40 +KPX Ohungarumlaut Aacute -40 +KPX Ohungarumlaut Abreve -40 +KPX Ohungarumlaut Acircumflex -40 +KPX Ohungarumlaut Adieresis -40 +KPX Ohungarumlaut Agrave -40 +KPX Ohungarumlaut Amacron -40 +KPX Ohungarumlaut Aogonek -40 +KPX Ohungarumlaut Aring -40 +KPX Ohungarumlaut Atilde -40 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -50 +KPX Ohungarumlaut X -40 +KPX Ohungarumlaut Y -50 +KPX Ohungarumlaut Yacute -50 +KPX Ohungarumlaut Ydieresis -50 +KPX Omacron A -40 +KPX Omacron Aacute -40 +KPX Omacron Abreve -40 +KPX Omacron Acircumflex -40 +KPX Omacron Adieresis -40 +KPX Omacron Agrave -40 +KPX Omacron Amacron -40 +KPX Omacron Aogonek -40 +KPX Omacron Aring -40 +KPX Omacron Atilde -40 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -50 +KPX Omacron X -40 +KPX Omacron Y -50 +KPX Omacron Yacute -50 +KPX Omacron Ydieresis -50 +KPX Oslash A -40 +KPX Oslash Aacute -40 +KPX Oslash Abreve -40 +KPX Oslash Acircumflex -40 +KPX Oslash Adieresis -40 +KPX Oslash Agrave -40 +KPX Oslash Amacron -40 +KPX Oslash Aogonek -40 +KPX Oslash Aring -40 +KPX Oslash Atilde -40 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -50 +KPX Oslash X -40 +KPX Oslash Y -50 +KPX Oslash Yacute -50 +KPX Oslash Ydieresis -50 +KPX Otilde A -40 +KPX Otilde Aacute -40 +KPX Otilde Abreve -40 +KPX Otilde Acircumflex -40 +KPX Otilde Adieresis -40 +KPX Otilde Agrave -40 +KPX Otilde Amacron -40 +KPX Otilde Aogonek -40 +KPX Otilde Aring -40 +KPX Otilde Atilde -40 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -50 +KPX Otilde X -40 +KPX Otilde Y -50 +KPX Otilde Yacute -50 +KPX Otilde Ydieresis -50 +KPX P A -74 +KPX P Aacute -74 +KPX P Abreve -74 +KPX P Acircumflex -74 +KPX P Adieresis -74 +KPX P Agrave -74 +KPX P Amacron -74 +KPX P Aogonek -74 +KPX P Aring -74 +KPX P Atilde -74 +KPX P a -10 +KPX P aacute -10 +KPX P abreve -10 +KPX P acircumflex -10 +KPX P adieresis -10 +KPX P agrave -10 +KPX P amacron -10 +KPX P aogonek -10 +KPX P aring -10 +KPX P atilde -10 +KPX P comma -92 +KPX P e -20 +KPX P eacute -20 +KPX P ecaron -20 +KPX P ecircumflex -20 +KPX P edieresis -20 +KPX P edotaccent -20 +KPX P egrave -20 +KPX P emacron -20 +KPX P eogonek -20 +KPX P o -20 +KPX P oacute -20 +KPX P ocircumflex -20 +KPX P odieresis -20 +KPX P ograve -20 +KPX P ohungarumlaut -20 +KPX P omacron -20 +KPX P oslash -20 +KPX P otilde -20 +KPX P period -110 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX Q period -20 +KPX R O -30 +KPX R Oacute -30 +KPX R Ocircumflex -30 +KPX R Odieresis -30 +KPX R Ograve -30 +KPX R Ohungarumlaut -30 +KPX R Omacron -30 +KPX R Oslash -30 +KPX R Otilde -30 +KPX R T -40 +KPX R Tcaron -40 +KPX R Tcommaaccent -40 +KPX R U -30 +KPX R Uacute -30 +KPX R Ucircumflex -30 +KPX R Udieresis -30 +KPX R Ugrave -30 +KPX R Uhungarumlaut -30 +KPX R Umacron -30 +KPX R Uogonek -30 +KPX R Uring -30 +KPX R V -55 +KPX R W -35 +KPX R Y -35 +KPX R Yacute -35 +KPX R Ydieresis -35 +KPX Racute O -30 +KPX Racute Oacute -30 +KPX Racute Ocircumflex -30 +KPX Racute Odieresis -30 +KPX Racute Ograve -30 +KPX Racute Ohungarumlaut -30 +KPX Racute Omacron -30 +KPX Racute Oslash -30 +KPX Racute Otilde -30 +KPX Racute T -40 +KPX Racute Tcaron -40 +KPX Racute Tcommaaccent -40 +KPX Racute U -30 +KPX Racute Uacute -30 +KPX Racute Ucircumflex -30 +KPX Racute Udieresis -30 +KPX Racute Ugrave -30 +KPX Racute Uhungarumlaut -30 +KPX Racute Umacron -30 +KPX Racute Uogonek -30 +KPX Racute Uring -30 +KPX Racute V -55 +KPX Racute W -35 +KPX Racute Y -35 +KPX Racute Yacute -35 +KPX Racute Ydieresis -35 +KPX Rcaron O -30 +KPX Rcaron Oacute -30 +KPX Rcaron Ocircumflex -30 +KPX Rcaron Odieresis -30 +KPX Rcaron Ograve -30 +KPX Rcaron Ohungarumlaut -30 +KPX Rcaron Omacron -30 +KPX Rcaron Oslash -30 +KPX Rcaron Otilde -30 +KPX Rcaron T -40 +KPX Rcaron Tcaron -40 +KPX Rcaron Tcommaaccent -40 +KPX Rcaron U -30 +KPX Rcaron Uacute -30 +KPX Rcaron Ucircumflex -30 +KPX Rcaron Udieresis -30 +KPX Rcaron Ugrave -30 +KPX Rcaron Uhungarumlaut -30 +KPX Rcaron Umacron -30 +KPX Rcaron Uogonek -30 +KPX Rcaron Uring -30 +KPX Rcaron V -55 +KPX Rcaron W -35 +KPX Rcaron Y -35 +KPX Rcaron Yacute -35 +KPX Rcaron Ydieresis -35 +KPX Rcommaaccent O -30 +KPX Rcommaaccent Oacute -30 +KPX Rcommaaccent Ocircumflex -30 +KPX Rcommaaccent Odieresis -30 +KPX Rcommaaccent Ograve -30 +KPX Rcommaaccent Ohungarumlaut -30 +KPX Rcommaaccent Omacron -30 +KPX Rcommaaccent Oslash -30 +KPX Rcommaaccent Otilde -30 +KPX Rcommaaccent T -40 +KPX Rcommaaccent Tcaron -40 +KPX Rcommaaccent Tcommaaccent -40 +KPX Rcommaaccent U -30 +KPX Rcommaaccent Uacute -30 +KPX Rcommaaccent Ucircumflex -30 +KPX Rcommaaccent Udieresis -30 +KPX Rcommaaccent Ugrave -30 +KPX Rcommaaccent Uhungarumlaut -30 +KPX Rcommaaccent Umacron -30 +KPX Rcommaaccent Uogonek -30 +KPX Rcommaaccent Uring -30 +KPX Rcommaaccent V -55 +KPX Rcommaaccent W -35 +KPX Rcommaaccent Y -35 +KPX Rcommaaccent Yacute -35 +KPX Rcommaaccent Ydieresis -35 +KPX T A -90 +KPX T Aacute -90 +KPX T Abreve -90 +KPX T Acircumflex -90 +KPX T Adieresis -90 +KPX T Agrave -90 +KPX T Amacron -90 +KPX T Aogonek -90 +KPX T Aring -90 +KPX T Atilde -90 +KPX T O -18 +KPX T Oacute -18 +KPX T Ocircumflex -18 +KPX T Odieresis -18 +KPX T Ograve -18 +KPX T Ohungarumlaut -18 +KPX T Omacron -18 +KPX T Oslash -18 +KPX T Otilde -18 +KPX T a -92 +KPX T aacute -92 +KPX T abreve -52 +KPX T acircumflex -52 +KPX T adieresis -52 +KPX T agrave -52 +KPX T amacron -52 +KPX T aogonek -92 +KPX T aring -92 +KPX T atilde -52 +KPX T colon -74 +KPX T comma -74 +KPX T e -92 +KPX T eacute -92 +KPX T ecaron -92 +KPX T ecircumflex -92 +KPX T edieresis -52 +KPX T edotaccent -92 +KPX T egrave -52 +KPX T emacron -52 +KPX T eogonek -92 +KPX T hyphen -92 +KPX T i -18 +KPX T iacute -18 +KPX T iogonek -18 +KPX T o -92 +KPX T oacute -92 +KPX T ocircumflex -92 +KPX T odieresis -92 +KPX T ograve -92 +KPX T ohungarumlaut -92 +KPX T omacron -92 +KPX T oslash -92 +KPX T otilde -92 +KPX T period -90 +KPX T r -74 +KPX T racute -74 +KPX T rcaron -74 +KPX T rcommaaccent -74 +KPX T semicolon -74 +KPX T u -92 +KPX T uacute -92 +KPX T ucircumflex -92 +KPX T udieresis -92 +KPX T ugrave -92 +KPX T uhungarumlaut -92 +KPX T umacron -92 +KPX T uogonek -92 +KPX T uring -92 +KPX T w -74 +KPX T y -34 +KPX T yacute -34 +KPX T ydieresis -34 +KPX Tcaron A -90 +KPX Tcaron Aacute -90 +KPX Tcaron Abreve -90 +KPX Tcaron Acircumflex -90 +KPX Tcaron Adieresis -90 +KPX Tcaron Agrave -90 +KPX Tcaron Amacron -90 +KPX Tcaron Aogonek -90 +KPX Tcaron Aring -90 +KPX Tcaron Atilde -90 +KPX Tcaron O -18 +KPX Tcaron Oacute -18 +KPX Tcaron Ocircumflex -18 +KPX Tcaron Odieresis -18 +KPX Tcaron Ograve -18 +KPX Tcaron Ohungarumlaut -18 +KPX Tcaron Omacron -18 +KPX Tcaron Oslash -18 +KPX Tcaron Otilde -18 +KPX Tcaron a -92 +KPX Tcaron aacute -92 +KPX Tcaron abreve -52 +KPX Tcaron acircumflex -52 +KPX Tcaron adieresis -52 +KPX Tcaron agrave -52 +KPX Tcaron amacron -52 +KPX Tcaron aogonek -92 +KPX Tcaron aring -92 +KPX Tcaron atilde -52 +KPX Tcaron colon -74 +KPX Tcaron comma -74 +KPX Tcaron e -92 +KPX Tcaron eacute -92 +KPX Tcaron ecaron -92 +KPX Tcaron ecircumflex -92 +KPX Tcaron edieresis -52 +KPX Tcaron edotaccent -92 +KPX Tcaron egrave -52 +KPX Tcaron emacron -52 +KPX Tcaron eogonek -92 +KPX Tcaron hyphen -92 +KPX Tcaron i -18 +KPX Tcaron iacute -18 +KPX Tcaron iogonek -18 +KPX Tcaron o -92 +KPX Tcaron oacute -92 +KPX Tcaron ocircumflex -92 +KPX Tcaron odieresis -92 +KPX Tcaron ograve -92 +KPX Tcaron ohungarumlaut -92 +KPX Tcaron omacron -92 +KPX Tcaron oslash -92 +KPX Tcaron otilde -92 +KPX Tcaron period -90 +KPX Tcaron r -74 +KPX Tcaron racute -74 +KPX Tcaron rcaron -74 +KPX Tcaron rcommaaccent -74 +KPX Tcaron semicolon -74 +KPX Tcaron u -92 +KPX Tcaron uacute -92 +KPX Tcaron ucircumflex -92 +KPX Tcaron udieresis -92 +KPX Tcaron ugrave -92 +KPX Tcaron uhungarumlaut -92 +KPX Tcaron umacron -92 +KPX Tcaron uogonek -92 +KPX Tcaron uring -92 +KPX Tcaron w -74 +KPX Tcaron y -34 +KPX Tcaron yacute -34 +KPX Tcaron ydieresis -34 +KPX Tcommaaccent A -90 +KPX Tcommaaccent Aacute -90 +KPX Tcommaaccent Abreve -90 +KPX Tcommaaccent Acircumflex -90 +KPX Tcommaaccent Adieresis -90 +KPX Tcommaaccent Agrave -90 +KPX Tcommaaccent Amacron -90 +KPX Tcommaaccent Aogonek -90 +KPX Tcommaaccent Aring -90 +KPX Tcommaaccent Atilde -90 +KPX Tcommaaccent O -18 +KPX Tcommaaccent Oacute -18 +KPX Tcommaaccent Ocircumflex -18 +KPX Tcommaaccent Odieresis -18 +KPX Tcommaaccent Ograve -18 +KPX Tcommaaccent Ohungarumlaut -18 +KPX Tcommaaccent Omacron -18 +KPX Tcommaaccent Oslash -18 +KPX Tcommaaccent Otilde -18 +KPX Tcommaaccent a -92 +KPX Tcommaaccent aacute -92 +KPX Tcommaaccent abreve -52 +KPX Tcommaaccent acircumflex -52 +KPX Tcommaaccent adieresis -52 +KPX Tcommaaccent agrave -52 +KPX Tcommaaccent amacron -52 +KPX Tcommaaccent aogonek -92 +KPX Tcommaaccent aring -92 +KPX Tcommaaccent atilde -52 +KPX Tcommaaccent colon -74 +KPX Tcommaaccent comma -74 +KPX Tcommaaccent e -92 +KPX Tcommaaccent eacute -92 +KPX Tcommaaccent ecaron -92 +KPX Tcommaaccent ecircumflex -92 +KPX Tcommaaccent edieresis -52 +KPX Tcommaaccent edotaccent -92 +KPX Tcommaaccent egrave -52 +KPX Tcommaaccent emacron -52 +KPX Tcommaaccent eogonek -92 +KPX Tcommaaccent hyphen -92 +KPX Tcommaaccent i -18 +KPX Tcommaaccent iacute -18 +KPX Tcommaaccent iogonek -18 +KPX Tcommaaccent o -92 +KPX Tcommaaccent oacute -92 +KPX Tcommaaccent ocircumflex -92 +KPX Tcommaaccent odieresis -92 +KPX Tcommaaccent ograve -92 +KPX Tcommaaccent ohungarumlaut -92 +KPX Tcommaaccent omacron -92 +KPX Tcommaaccent oslash -92 +KPX Tcommaaccent otilde -92 +KPX Tcommaaccent period -90 +KPX Tcommaaccent r -74 +KPX Tcommaaccent racute -74 +KPX Tcommaaccent rcaron -74 +KPX Tcommaaccent rcommaaccent -74 +KPX Tcommaaccent semicolon -74 +KPX Tcommaaccent u -92 +KPX Tcommaaccent uacute -92 +KPX Tcommaaccent ucircumflex -92 +KPX Tcommaaccent udieresis -92 +KPX Tcommaaccent ugrave -92 +KPX Tcommaaccent uhungarumlaut -92 +KPX Tcommaaccent umacron -92 +KPX Tcommaaccent uogonek -92 +KPX Tcommaaccent uring -92 +KPX Tcommaaccent w -74 +KPX Tcommaaccent y -34 +KPX Tcommaaccent yacute -34 +KPX Tcommaaccent ydieresis -34 +KPX U A -60 +KPX U Aacute -60 +KPX U Abreve -60 +KPX U Acircumflex -60 +KPX U Adieresis -60 +KPX U Agrave -60 +KPX U Amacron -60 +KPX U Aogonek -60 +KPX U Aring -60 +KPX U Atilde -60 +KPX U comma -50 +KPX U period -50 +KPX Uacute A -60 +KPX Uacute Aacute -60 +KPX Uacute Abreve -60 +KPX Uacute Acircumflex -60 +KPX Uacute Adieresis -60 +KPX Uacute Agrave -60 +KPX Uacute Amacron -60 +KPX Uacute Aogonek -60 +KPX Uacute Aring -60 +KPX Uacute Atilde -60 +KPX Uacute comma -50 +KPX Uacute period -50 +KPX Ucircumflex A -60 +KPX Ucircumflex Aacute -60 +KPX Ucircumflex Abreve -60 +KPX Ucircumflex Acircumflex -60 +KPX Ucircumflex Adieresis -60 +KPX Ucircumflex Agrave -60 +KPX Ucircumflex Amacron -60 +KPX Ucircumflex Aogonek -60 +KPX Ucircumflex Aring -60 +KPX Ucircumflex Atilde -60 +KPX Ucircumflex comma -50 +KPX Ucircumflex period -50 +KPX Udieresis A -60 +KPX Udieresis Aacute -60 +KPX Udieresis Abreve -60 +KPX Udieresis Acircumflex -60 +KPX Udieresis Adieresis -60 +KPX Udieresis Agrave -60 +KPX Udieresis Amacron -60 +KPX Udieresis Aogonek -60 +KPX Udieresis Aring -60 +KPX Udieresis Atilde -60 +KPX Udieresis comma -50 +KPX Udieresis period -50 +KPX Ugrave A -60 +KPX Ugrave Aacute -60 +KPX Ugrave Abreve -60 +KPX Ugrave Acircumflex -60 +KPX Ugrave Adieresis -60 +KPX Ugrave Agrave -60 +KPX Ugrave Amacron -60 +KPX Ugrave Aogonek -60 +KPX Ugrave Aring -60 +KPX Ugrave Atilde -60 +KPX Ugrave comma -50 +KPX Ugrave period -50 +KPX Uhungarumlaut A -60 +KPX Uhungarumlaut Aacute -60 +KPX Uhungarumlaut Abreve -60 +KPX Uhungarumlaut Acircumflex -60 +KPX Uhungarumlaut Adieresis -60 +KPX Uhungarumlaut Agrave -60 +KPX Uhungarumlaut Amacron -60 +KPX Uhungarumlaut Aogonek -60 +KPX Uhungarumlaut Aring -60 +KPX Uhungarumlaut Atilde -60 +KPX Uhungarumlaut comma -50 +KPX Uhungarumlaut period -50 +KPX Umacron A -60 +KPX Umacron Aacute -60 +KPX Umacron Abreve -60 +KPX Umacron Acircumflex -60 +KPX Umacron Adieresis -60 +KPX Umacron Agrave -60 +KPX Umacron Amacron -60 +KPX Umacron Aogonek -60 +KPX Umacron Aring -60 +KPX Umacron Atilde -60 +KPX Umacron comma -50 +KPX Umacron period -50 +KPX Uogonek A -60 +KPX Uogonek Aacute -60 +KPX Uogonek Abreve -60 +KPX Uogonek Acircumflex -60 +KPX Uogonek Adieresis -60 +KPX Uogonek Agrave -60 +KPX Uogonek Amacron -60 +KPX Uogonek Aogonek -60 +KPX Uogonek Aring -60 +KPX Uogonek Atilde -60 +KPX Uogonek comma -50 +KPX Uogonek period -50 +KPX Uring A -60 +KPX Uring Aacute -60 +KPX Uring Abreve -60 +KPX Uring Acircumflex -60 +KPX Uring Adieresis -60 +KPX Uring Agrave -60 +KPX Uring Amacron -60 +KPX Uring Aogonek -60 +KPX Uring Aring -60 +KPX Uring Atilde -60 +KPX Uring comma -50 +KPX Uring period -50 +KPX V A -135 +KPX V Aacute -135 +KPX V Abreve -135 +KPX V Acircumflex -135 +KPX V Adieresis -135 +KPX V Agrave -135 +KPX V Amacron -135 +KPX V Aogonek -135 +KPX V Aring -135 +KPX V Atilde -135 +KPX V G -30 +KPX V Gbreve -30 +KPX V Gcommaaccent -30 +KPX V O -45 +KPX V Oacute -45 +KPX V Ocircumflex -45 +KPX V Odieresis -45 +KPX V Ograve -45 +KPX V Ohungarumlaut -45 +KPX V Omacron -45 +KPX V Oslash -45 +KPX V Otilde -45 +KPX V a -92 +KPX V aacute -92 +KPX V abreve -92 +KPX V acircumflex -92 +KPX V adieresis -92 +KPX V agrave -92 +KPX V amacron -92 +KPX V aogonek -92 +KPX V aring -92 +KPX V atilde -92 +KPX V colon -92 +KPX V comma -129 +KPX V e -100 +KPX V eacute -100 +KPX V ecaron -100 +KPX V ecircumflex -100 +KPX V edieresis -100 +KPX V edotaccent -100 +KPX V egrave -100 +KPX V emacron -100 +KPX V eogonek -100 +KPX V hyphen -74 +KPX V i -37 +KPX V iacute -37 +KPX V icircumflex -37 +KPX V idieresis -37 +KPX V igrave -37 +KPX V imacron -37 +KPX V iogonek -37 +KPX V o -100 +KPX V oacute -100 +KPX V ocircumflex -100 +KPX V odieresis -100 +KPX V ograve -100 +KPX V ohungarumlaut -100 +KPX V omacron -100 +KPX V oslash -100 +KPX V otilde -100 +KPX V period -145 +KPX V semicolon -92 +KPX V u -92 +KPX V uacute -92 +KPX V ucircumflex -92 +KPX V udieresis -92 +KPX V ugrave -92 +KPX V uhungarumlaut -92 +KPX V umacron -92 +KPX V uogonek -92 +KPX V uring -92 +KPX W A -120 +KPX W Aacute -120 +KPX W Abreve -120 +KPX W Acircumflex -120 +KPX W Adieresis -120 +KPX W Agrave -120 +KPX W Amacron -120 +KPX W Aogonek -120 +KPX W Aring -120 +KPX W Atilde -120 +KPX W O -10 +KPX W Oacute -10 +KPX W Ocircumflex -10 +KPX W Odieresis -10 +KPX W Ograve -10 +KPX W Ohungarumlaut -10 +KPX W Omacron -10 +KPX W Oslash -10 +KPX W Otilde -10 +KPX W a -65 +KPX W aacute -65 +KPX W abreve -65 +KPX W acircumflex -65 +KPX W adieresis -65 +KPX W agrave -65 +KPX W amacron -65 +KPX W aogonek -65 +KPX W aring -65 +KPX W atilde -65 +KPX W colon -55 +KPX W comma -92 +KPX W e -65 +KPX W eacute -65 +KPX W ecaron -65 +KPX W ecircumflex -65 +KPX W edieresis -65 +KPX W edotaccent -65 +KPX W egrave -65 +KPX W emacron -65 +KPX W eogonek -65 +KPX W hyphen -37 +KPX W i -18 +KPX W iacute -18 +KPX W iogonek -18 +KPX W o -75 +KPX W oacute -75 +KPX W ocircumflex -75 +KPX W odieresis -75 +KPX W ograve -75 +KPX W ohungarumlaut -75 +KPX W omacron -75 +KPX W oslash -75 +KPX W otilde -75 +KPX W period -92 +KPX W semicolon -55 +KPX W u -50 +KPX W uacute -50 +KPX W ucircumflex -50 +KPX W udieresis -50 +KPX W ugrave -50 +KPX W uhungarumlaut -50 +KPX W umacron -50 +KPX W uogonek -50 +KPX W uring -50 +KPX W y -60 +KPX W yacute -60 +KPX W ydieresis -60 +KPX Y A -110 +KPX Y Aacute -110 +KPX Y Abreve -110 +KPX Y Acircumflex -110 +KPX Y Adieresis -110 +KPX Y Agrave -110 +KPX Y Amacron -110 +KPX Y Aogonek -110 +KPX Y Aring -110 +KPX Y Atilde -110 +KPX Y O -35 +KPX Y Oacute -35 +KPX Y Ocircumflex -35 +KPX Y Odieresis -35 +KPX Y Ograve -35 +KPX Y Ohungarumlaut -35 +KPX Y Omacron -35 +KPX Y Oslash -35 +KPX Y Otilde -35 +KPX Y a -85 +KPX Y aacute -85 +KPX Y abreve -85 +KPX Y acircumflex -85 +KPX Y adieresis -85 +KPX Y agrave -85 +KPX Y amacron -85 +KPX Y aogonek -85 +KPX Y aring -85 +KPX Y atilde -85 +KPX Y colon -92 +KPX Y comma -92 +KPX Y e -111 +KPX Y eacute -111 +KPX Y ecaron -111 +KPX Y ecircumflex -111 +KPX Y edieresis -71 +KPX Y edotaccent -111 +KPX Y egrave -71 +KPX Y emacron -71 +KPX Y eogonek -111 +KPX Y hyphen -92 +KPX Y i -37 +KPX Y iacute -37 +KPX Y iogonek -37 +KPX Y o -111 +KPX Y oacute -111 +KPX Y ocircumflex -111 +KPX Y odieresis -111 +KPX Y ograve -111 +KPX Y ohungarumlaut -111 +KPX Y omacron -111 +KPX Y oslash -111 +KPX Y otilde -111 +KPX Y period -92 +KPX Y semicolon -92 +KPX Y u -92 +KPX Y uacute -92 +KPX Y ucircumflex -92 +KPX Y udieresis -92 +KPX Y ugrave -92 +KPX Y uhungarumlaut -92 +KPX Y umacron -92 +KPX Y uogonek -92 +KPX Y uring -92 +KPX Yacute A -110 +KPX Yacute Aacute -110 +KPX Yacute Abreve -110 +KPX Yacute Acircumflex -110 +KPX Yacute Adieresis -110 +KPX Yacute Agrave -110 +KPX Yacute Amacron -110 +KPX Yacute Aogonek -110 +KPX Yacute Aring -110 +KPX Yacute Atilde -110 +KPX Yacute O -35 +KPX Yacute Oacute -35 +KPX Yacute Ocircumflex -35 +KPX Yacute Odieresis -35 +KPX Yacute Ograve -35 +KPX Yacute Ohungarumlaut -35 +KPX Yacute Omacron -35 +KPX Yacute Oslash -35 +KPX Yacute Otilde -35 +KPX Yacute a -85 +KPX Yacute aacute -85 +KPX Yacute abreve -85 +KPX Yacute acircumflex -85 +KPX Yacute adieresis -85 +KPX Yacute agrave -85 +KPX Yacute amacron -85 +KPX Yacute aogonek -85 +KPX Yacute aring -85 +KPX Yacute atilde -85 +KPX Yacute colon -92 +KPX Yacute comma -92 +KPX Yacute e -111 +KPX Yacute eacute -111 +KPX Yacute ecaron -111 +KPX Yacute ecircumflex -111 +KPX Yacute edieresis -71 +KPX Yacute edotaccent -111 +KPX Yacute egrave -71 +KPX Yacute emacron -71 +KPX Yacute eogonek -111 +KPX Yacute hyphen -92 +KPX Yacute i -37 +KPX Yacute iacute -37 +KPX Yacute iogonek -37 +KPX Yacute o -111 +KPX Yacute oacute -111 +KPX Yacute ocircumflex -111 +KPX Yacute odieresis -111 +KPX Yacute ograve -111 +KPX Yacute ohungarumlaut -111 +KPX Yacute omacron -111 +KPX Yacute oslash -111 +KPX Yacute otilde -111 +KPX Yacute period -92 +KPX Yacute semicolon -92 +KPX Yacute u -92 +KPX Yacute uacute -92 +KPX Yacute ucircumflex -92 +KPX Yacute udieresis -92 +KPX Yacute ugrave -92 +KPX Yacute uhungarumlaut -92 +KPX Yacute umacron -92 +KPX Yacute uogonek -92 +KPX Yacute uring -92 +KPX Ydieresis A -110 +KPX Ydieresis Aacute -110 +KPX Ydieresis Abreve -110 +KPX Ydieresis Acircumflex -110 +KPX Ydieresis Adieresis -110 +KPX Ydieresis Agrave -110 +KPX Ydieresis Amacron -110 +KPX Ydieresis Aogonek -110 +KPX Ydieresis Aring -110 +KPX Ydieresis Atilde -110 +KPX Ydieresis O -35 +KPX Ydieresis Oacute -35 +KPX Ydieresis Ocircumflex -35 +KPX Ydieresis Odieresis -35 +KPX Ydieresis Ograve -35 +KPX Ydieresis Ohungarumlaut -35 +KPX Ydieresis Omacron -35 +KPX Ydieresis Oslash -35 +KPX Ydieresis Otilde -35 +KPX Ydieresis a -85 +KPX Ydieresis aacute -85 +KPX Ydieresis abreve -85 +KPX Ydieresis acircumflex -85 +KPX Ydieresis adieresis -85 +KPX Ydieresis agrave -85 +KPX Ydieresis amacron -85 +KPX Ydieresis aogonek -85 +KPX Ydieresis aring -85 +KPX Ydieresis atilde -85 +KPX Ydieresis colon -92 +KPX Ydieresis comma -92 +KPX Ydieresis e -111 +KPX Ydieresis eacute -111 +KPX Ydieresis ecaron -111 +KPX Ydieresis ecircumflex -111 +KPX Ydieresis edieresis -71 +KPX Ydieresis edotaccent -111 +KPX Ydieresis egrave -71 +KPX Ydieresis emacron -71 +KPX Ydieresis eogonek -111 +KPX Ydieresis hyphen -92 +KPX Ydieresis i -37 +KPX Ydieresis iacute -37 +KPX Ydieresis iogonek -37 +KPX Ydieresis o -111 +KPX Ydieresis oacute -111 +KPX Ydieresis ocircumflex -111 +KPX Ydieresis odieresis -111 +KPX Ydieresis ograve -111 +KPX Ydieresis ohungarumlaut -111 +KPX Ydieresis omacron -111 +KPX Ydieresis oslash -111 +KPX Ydieresis otilde -111 +KPX Ydieresis period -92 +KPX Ydieresis semicolon -92 +KPX Ydieresis u -92 +KPX Ydieresis uacute -92 +KPX Ydieresis ucircumflex -92 +KPX Ydieresis udieresis -92 +KPX Ydieresis ugrave -92 +KPX Ydieresis uhungarumlaut -92 +KPX Ydieresis umacron -92 +KPX Ydieresis uogonek -92 +KPX Ydieresis uring -92 +KPX a v -25 +KPX aacute v -25 +KPX abreve v -25 +KPX acircumflex v -25 +KPX adieresis v -25 +KPX agrave v -25 +KPX amacron v -25 +KPX aogonek v -25 +KPX aring v -25 +KPX atilde v -25 +KPX b b -10 +KPX b period -40 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX b v -15 +KPX comma quotedblright -45 +KPX comma quoteright -55 +KPX d w -15 +KPX dcroat w -15 +KPX e v -15 +KPX eacute v -15 +KPX ecaron v -15 +KPX ecircumflex v -15 +KPX edieresis v -15 +KPX edotaccent v -15 +KPX egrave v -15 +KPX emacron v -15 +KPX eogonek v -15 +KPX f comma -15 +KPX f dotlessi -35 +KPX f i -25 +KPX f o -25 +KPX f oacute -25 +KPX f ocircumflex -25 +KPX f odieresis -25 +KPX f ograve -25 +KPX f ohungarumlaut -25 +KPX f omacron -25 +KPX f oslash -25 +KPX f otilde -25 +KPX f period -15 +KPX f quotedblright 50 +KPX f quoteright 55 +KPX g period -15 +KPX gbreve period -15 +KPX gcommaaccent period -15 +KPX h y -15 +KPX h yacute -15 +KPX h ydieresis -15 +KPX i v -10 +KPX iacute v -10 +KPX icircumflex v -10 +KPX idieresis v -10 +KPX igrave v -10 +KPX imacron v -10 +KPX iogonek v -10 +KPX k e -10 +KPX k eacute -10 +KPX k ecaron -10 +KPX k ecircumflex -10 +KPX k edieresis -10 +KPX k edotaccent -10 +KPX k egrave -10 +KPX k emacron -10 +KPX k eogonek -10 +KPX k o -15 +KPX k oacute -15 +KPX k ocircumflex -15 +KPX k odieresis -15 +KPX k ograve -15 +KPX k ohungarumlaut -15 +KPX k omacron -15 +KPX k oslash -15 +KPX k otilde -15 +KPX k y -15 +KPX k yacute -15 +KPX k ydieresis -15 +KPX kcommaaccent e -10 +KPX kcommaaccent eacute -10 +KPX kcommaaccent ecaron -10 +KPX kcommaaccent ecircumflex -10 +KPX kcommaaccent edieresis -10 +KPX kcommaaccent edotaccent -10 +KPX kcommaaccent egrave -10 +KPX kcommaaccent emacron -10 +KPX kcommaaccent eogonek -10 +KPX kcommaaccent o -15 +KPX kcommaaccent oacute -15 +KPX kcommaaccent ocircumflex -15 +KPX kcommaaccent odieresis -15 +KPX kcommaaccent ograve -15 +KPX kcommaaccent ohungarumlaut -15 +KPX kcommaaccent omacron -15 +KPX kcommaaccent oslash -15 +KPX kcommaaccent otilde -15 +KPX kcommaaccent y -15 +KPX kcommaaccent yacute -15 +KPX kcommaaccent ydieresis -15 +KPX n v -40 +KPX nacute v -40 +KPX ncaron v -40 +KPX ncommaaccent v -40 +KPX ntilde v -40 +KPX o v -10 +KPX o w -10 +KPX oacute v -10 +KPX oacute w -10 +KPX ocircumflex v -10 +KPX ocircumflex w -10 +KPX odieresis v -10 +KPX odieresis w -10 +KPX ograve v -10 +KPX ograve w -10 +KPX ohungarumlaut v -10 +KPX ohungarumlaut w -10 +KPX omacron v -10 +KPX omacron w -10 +KPX oslash v -10 +KPX oslash w -10 +KPX otilde v -10 +KPX otilde w -10 +KPX period quotedblright -55 +KPX period quoteright -55 +KPX quotedblleft A -10 +KPX quotedblleft Aacute -10 +KPX quotedblleft Abreve -10 +KPX quotedblleft Acircumflex -10 +KPX quotedblleft Adieresis -10 +KPX quotedblleft Agrave -10 +KPX quotedblleft Amacron -10 +KPX quotedblleft Aogonek -10 +KPX quotedblleft Aring -10 +KPX quotedblleft Atilde -10 +KPX quoteleft A -10 +KPX quoteleft Aacute -10 +KPX quoteleft Abreve -10 +KPX quoteleft Acircumflex -10 +KPX quoteleft Adieresis -10 +KPX quoteleft Agrave -10 +KPX quoteleft Amacron -10 +KPX quoteleft Aogonek -10 +KPX quoteleft Aring -10 +KPX quoteleft Atilde -10 +KPX quoteleft quoteleft -63 +KPX quoteright d -20 +KPX quoteright dcroat -20 +KPX quoteright quoteright -63 +KPX quoteright r -20 +KPX quoteright racute -20 +KPX quoteright rcaron -20 +KPX quoteright rcommaaccent -20 +KPX quoteright s -37 +KPX quoteright sacute -37 +KPX quoteright scaron -37 +KPX quoteright scedilla -37 +KPX quoteright scommaaccent -37 +KPX quoteright space -74 +KPX quoteright v -20 +KPX r c -18 +KPX r cacute -18 +KPX r ccaron -18 +KPX r ccedilla -18 +KPX r comma -92 +KPX r e -18 +KPX r eacute -18 +KPX r ecaron -18 +KPX r ecircumflex -18 +KPX r edieresis -18 +KPX r edotaccent -18 +KPX r egrave -18 +KPX r emacron -18 +KPX r eogonek -18 +KPX r g -10 +KPX r gbreve -10 +KPX r gcommaaccent -10 +KPX r hyphen -37 +KPX r n -15 +KPX r nacute -15 +KPX r ncaron -15 +KPX r ncommaaccent -15 +KPX r ntilde -15 +KPX r o -18 +KPX r oacute -18 +KPX r ocircumflex -18 +KPX r odieresis -18 +KPX r ograve -18 +KPX r ohungarumlaut -18 +KPX r omacron -18 +KPX r oslash -18 +KPX r otilde -18 +KPX r p -10 +KPX r period -100 +KPX r q -18 +KPX r v -10 +KPX racute c -18 +KPX racute cacute -18 +KPX racute ccaron -18 +KPX racute ccedilla -18 +KPX racute comma -92 +KPX racute e -18 +KPX racute eacute -18 +KPX racute ecaron -18 +KPX racute ecircumflex -18 +KPX racute edieresis -18 +KPX racute edotaccent -18 +KPX racute egrave -18 +KPX racute emacron -18 +KPX racute eogonek -18 +KPX racute g -10 +KPX racute gbreve -10 +KPX racute gcommaaccent -10 +KPX racute hyphen -37 +KPX racute n -15 +KPX racute nacute -15 +KPX racute ncaron -15 +KPX racute ncommaaccent -15 +KPX racute ntilde -15 +KPX racute o -18 +KPX racute oacute -18 +KPX racute ocircumflex -18 +KPX racute odieresis -18 +KPX racute ograve -18 +KPX racute ohungarumlaut -18 +KPX racute omacron -18 +KPX racute oslash -18 +KPX racute otilde -18 +KPX racute p -10 +KPX racute period -100 +KPX racute q -18 +KPX racute v -10 +KPX rcaron c -18 +KPX rcaron cacute -18 +KPX rcaron ccaron -18 +KPX rcaron ccedilla -18 +KPX rcaron comma -92 +KPX rcaron e -18 +KPX rcaron eacute -18 +KPX rcaron ecaron -18 +KPX rcaron ecircumflex -18 +KPX rcaron edieresis -18 +KPX rcaron edotaccent -18 +KPX rcaron egrave -18 +KPX rcaron emacron -18 +KPX rcaron eogonek -18 +KPX rcaron g -10 +KPX rcaron gbreve -10 +KPX rcaron gcommaaccent -10 +KPX rcaron hyphen -37 +KPX rcaron n -15 +KPX rcaron nacute -15 +KPX rcaron ncaron -15 +KPX rcaron ncommaaccent -15 +KPX rcaron ntilde -15 +KPX rcaron o -18 +KPX rcaron oacute -18 +KPX rcaron ocircumflex -18 +KPX rcaron odieresis -18 +KPX rcaron ograve -18 +KPX rcaron ohungarumlaut -18 +KPX rcaron omacron -18 +KPX rcaron oslash -18 +KPX rcaron otilde -18 +KPX rcaron p -10 +KPX rcaron period -100 +KPX rcaron q -18 +KPX rcaron v -10 +KPX rcommaaccent c -18 +KPX rcommaaccent cacute -18 +KPX rcommaaccent ccaron -18 +KPX rcommaaccent ccedilla -18 +KPX rcommaaccent comma -92 +KPX rcommaaccent e -18 +KPX rcommaaccent eacute -18 +KPX rcommaaccent ecaron -18 +KPX rcommaaccent ecircumflex -18 +KPX rcommaaccent edieresis -18 +KPX rcommaaccent edotaccent -18 +KPX rcommaaccent egrave -18 +KPX rcommaaccent emacron -18 +KPX rcommaaccent eogonek -18 +KPX rcommaaccent g -10 +KPX rcommaaccent gbreve -10 +KPX rcommaaccent gcommaaccent -10 +KPX rcommaaccent hyphen -37 +KPX rcommaaccent n -15 +KPX rcommaaccent nacute -15 +KPX rcommaaccent ncaron -15 +KPX rcommaaccent ncommaaccent -15 +KPX rcommaaccent ntilde -15 +KPX rcommaaccent o -18 +KPX rcommaaccent oacute -18 +KPX rcommaaccent ocircumflex -18 +KPX rcommaaccent odieresis -18 +KPX rcommaaccent ograve -18 +KPX rcommaaccent ohungarumlaut -18 +KPX rcommaaccent omacron -18 +KPX rcommaaccent oslash -18 +KPX rcommaaccent otilde -18 +KPX rcommaaccent p -10 +KPX rcommaaccent period -100 +KPX rcommaaccent q -18 +KPX rcommaaccent v -10 +KPX space A -55 +KPX space Aacute -55 +KPX space Abreve -55 +KPX space Acircumflex -55 +KPX space Adieresis -55 +KPX space Agrave -55 +KPX space Amacron -55 +KPX space Aogonek -55 +KPX space Aring -55 +KPX space Atilde -55 +KPX space T -30 +KPX space Tcaron -30 +KPX space Tcommaaccent -30 +KPX space V -45 +KPX space W -30 +KPX space Y -55 +KPX space Yacute -55 +KPX space Ydieresis -55 +KPX v a -10 +KPX v aacute -10 +KPX v abreve -10 +KPX v acircumflex -10 +KPX v adieresis -10 +KPX v agrave -10 +KPX v amacron -10 +KPX v aogonek -10 +KPX v aring -10 +KPX v atilde -10 +KPX v comma -55 +KPX v e -10 +KPX v eacute -10 +KPX v ecaron -10 +KPX v ecircumflex -10 +KPX v edieresis -10 +KPX v edotaccent -10 +KPX v egrave -10 +KPX v emacron -10 +KPX v eogonek -10 +KPX v o -10 +KPX v oacute -10 +KPX v ocircumflex -10 +KPX v odieresis -10 +KPX v ograve -10 +KPX v ohungarumlaut -10 +KPX v omacron -10 +KPX v oslash -10 +KPX v otilde -10 +KPX v period -70 +KPX w comma -55 +KPX w o -10 +KPX w oacute -10 +KPX w ocircumflex -10 +KPX w odieresis -10 +KPX w ograve -10 +KPX w ohungarumlaut -10 +KPX w omacron -10 +KPX w oslash -10 +KPX w otilde -10 +KPX w period -70 +KPX y comma -55 +KPX y e -10 +KPX y eacute -10 +KPX y ecaron -10 +KPX y ecircumflex -10 +KPX y edieresis -10 +KPX y edotaccent -10 +KPX y egrave -10 +KPX y emacron -10 +KPX y eogonek -10 +KPX y o -25 +KPX y oacute -25 +KPX y ocircumflex -25 +KPX y odieresis -25 +KPX y ograve -25 +KPX y ohungarumlaut -25 +KPX y omacron -25 +KPX y oslash -25 +KPX y otilde -25 +KPX y period -70 +KPX yacute comma -55 +KPX yacute e -10 +KPX yacute eacute -10 +KPX yacute ecaron -10 +KPX yacute ecircumflex -10 +KPX yacute edieresis -10 +KPX yacute edotaccent -10 +KPX yacute egrave -10 +KPX yacute emacron -10 +KPX yacute eogonek -10 +KPX yacute o -25 +KPX yacute oacute -25 +KPX yacute ocircumflex -25 +KPX yacute odieresis -25 +KPX yacute ograve -25 +KPX yacute ohungarumlaut -25 +KPX yacute omacron -25 +KPX yacute oslash -25 +KPX yacute otilde -25 +KPX yacute period -70 +KPX ydieresis comma -55 +KPX ydieresis e -10 +KPX ydieresis eacute -10 +KPX ydieresis ecaron -10 +KPX ydieresis ecircumflex -10 +KPX ydieresis edieresis -10 +KPX ydieresis edotaccent -10 +KPX ydieresis egrave -10 +KPX ydieresis emacron -10 +KPX ydieresis eogonek -10 +KPX ydieresis o -25 +KPX ydieresis oacute -25 +KPX ydieresis ocircumflex -25 +KPX ydieresis odieresis -25 +KPX ydieresis ograve -25 +KPX ydieresis ohungarumlaut -25 +KPX ydieresis omacron -25 +KPX ydieresis oslash -25 +KPX ydieresis otilde -25 +KPX ydieresis period -70 +EndKernPairs +EndKernData +EndFontMetrics addfile ./Core14_AFMs/Times-BoldItalic.afm hunk ./Core14_AFMs/Times-BoldItalic.afm 1 +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 13:04:06 1997 +Comment UniqueID 43066 +Comment VMusage 45874 56899 +FontName Times-BoldItalic +FullName Times Bold Italic +FamilyName Times +Weight Bold +ItalicAngle -15 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -200 -218 996 921 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 669 +XHeight 462 +Ascender 683 +Descender -217 +StdHW 42 +StdVW 121 +StartCharMetrics 315 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 389 ; N exclam ; B 67 -13 370 684 ; +C 34 ; WX 555 ; N quotedbl ; B 136 398 536 685 ; +C 35 ; WX 500 ; N numbersign ; B -33 0 533 700 ; +C 36 ; WX 500 ; N dollar ; B -20 -100 497 733 ; +C 37 ; WX 833 ; N percent ; B 39 -10 793 692 ; +C 38 ; WX 778 ; N ampersand ; B 5 -19 699 682 ; +C 39 ; WX 333 ; N quoteright ; B 98 369 302 685 ; +C 40 ; WX 333 ; N parenleft ; B 28 -179 344 685 ; +C 41 ; WX 333 ; N parenright ; B -44 -179 271 685 ; +C 42 ; WX 500 ; N asterisk ; B 65 249 456 685 ; +C 43 ; WX 570 ; N plus ; B 33 0 537 506 ; +C 44 ; WX 250 ; N comma ; B -60 -182 144 134 ; +C 45 ; WX 333 ; N hyphen ; B 2 166 271 282 ; +C 46 ; WX 250 ; N period ; B -9 -13 139 135 ; +C 47 ; WX 278 ; N slash ; B -64 -18 342 685 ; +C 48 ; WX 500 ; N zero ; B 17 -14 477 683 ; +C 49 ; WX 500 ; N one ; B 5 0 419 683 ; +C 50 ; WX 500 ; N two ; B -27 0 446 683 ; +C 51 ; WX 500 ; N three ; B -15 -13 450 683 ; +C 52 ; WX 500 ; N four ; B -15 0 503 683 ; +C 53 ; WX 500 ; N five ; B -11 -13 487 669 ; +C 54 ; WX 500 ; N six ; B 23 -15 509 679 ; +C 55 ; WX 500 ; N seven ; B 52 0 525 669 ; +C 56 ; WX 500 ; N eight ; B 3 -13 476 683 ; +C 57 ; WX 500 ; N nine ; B -12 -10 475 683 ; +C 58 ; WX 333 ; N colon ; B 23 -13 264 459 ; +C 59 ; WX 333 ; N semicolon ; B -25 -183 264 459 ; +C 60 ; WX 570 ; N less ; B 31 -8 539 514 ; +C 61 ; WX 570 ; N equal ; B 33 107 537 399 ; +C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ; +C 63 ; WX 500 ; N question ; B 79 -13 470 684 ; +C 64 ; WX 832 ; N at ; B 63 -18 770 685 ; +C 65 ; WX 667 ; N A ; B -67 0 593 683 ; +C 66 ; WX 667 ; N B ; B -24 0 624 669 ; +C 67 ; WX 667 ; N C ; B 32 -18 677 685 ; +C 68 ; WX 722 ; N D ; B -46 0 685 669 ; +C 69 ; WX 667 ; N E ; B -27 0 653 669 ; +C 70 ; WX 667 ; N F ; B -13 0 660 669 ; +C 71 ; WX 722 ; N G ; B 21 -18 706 685 ; +C 72 ; WX 778 ; N H ; B -24 0 799 669 ; +C 73 ; WX 389 ; N I ; B -32 0 406 669 ; +C 74 ; WX 500 ; N J ; B -46 -99 524 669 ; +C 75 ; WX 667 ; N K ; B -21 0 702 669 ; +C 76 ; WX 611 ; N L ; B -22 0 590 669 ; +C 77 ; WX 889 ; N M ; B -29 -12 917 669 ; +C 78 ; WX 722 ; N N ; B -27 -15 748 669 ; +C 79 ; WX 722 ; N O ; B 27 -18 691 685 ; +C 80 ; WX 611 ; N P ; B -27 0 613 669 ; +C 81 ; WX 722 ; N Q ; B 27 -208 691 685 ; +C 82 ; WX 667 ; N R ; B -29 0 623 669 ; +C 83 ; WX 556 ; N S ; B 2 -18 526 685 ; +C 84 ; WX 611 ; N T ; B 50 0 650 669 ; +C 85 ; WX 722 ; N U ; B 67 -18 744 669 ; +C 86 ; WX 667 ; N V ; B 65 -18 715 669 ; +C 87 ; WX 889 ; N W ; B 65 -18 940 669 ; +C 88 ; WX 667 ; N X ; B -24 0 694 669 ; +C 89 ; WX 611 ; N Y ; B 73 0 659 669 ; +C 90 ; WX 611 ; N Z ; B -11 0 590 669 ; +C 91 ; WX 333 ; N bracketleft ; B -37 -159 362 674 ; +C 92 ; WX 278 ; N backslash ; B -1 -18 279 685 ; +C 93 ; WX 333 ; N bracketright ; B -56 -157 343 674 ; +C 94 ; WX 570 ; N asciicircum ; B 67 304 503 669 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 333 ; N quoteleft ; B 128 369 332 685 ; +C 97 ; WX 500 ; N a ; B -21 -14 455 462 ; +C 98 ; WX 500 ; N b ; B -14 -13 444 699 ; +C 99 ; WX 444 ; N c ; B -5 -13 392 462 ; +C 100 ; WX 500 ; N d ; B -21 -13 517 699 ; +C 101 ; WX 444 ; N e ; B 5 -13 398 462 ; +C 102 ; WX 333 ; N f ; B -169 -205 446 698 ; L i fi ; L l fl ; +C 103 ; WX 500 ; N g ; B -52 -203 478 462 ; +C 104 ; WX 556 ; N h ; B -13 -9 498 699 ; +C 105 ; WX 278 ; N i ; B 2 -9 263 684 ; +C 106 ; WX 278 ; N j ; B -189 -207 279 684 ; +C 107 ; WX 500 ; N k ; B -23 -8 483 699 ; +C 108 ; WX 278 ; N l ; B 2 -9 290 699 ; +C 109 ; WX 778 ; N m ; B -14 -9 722 462 ; +C 110 ; WX 556 ; N n ; B -6 -9 493 462 ; +C 111 ; WX 500 ; N o ; B -3 -13 441 462 ; +C 112 ; WX 500 ; N p ; B -120 -205 446 462 ; +C 113 ; WX 500 ; N q ; B 1 -205 471 462 ; +C 114 ; WX 389 ; N r ; B -21 0 389 462 ; +C 115 ; WX 389 ; N s ; B -19 -13 333 462 ; +C 116 ; WX 278 ; N t ; B -11 -9 281 594 ; +C 117 ; WX 556 ; N u ; B 15 -9 492 462 ; +C 118 ; WX 444 ; N v ; B 16 -13 401 462 ; +C 119 ; WX 667 ; N w ; B 16 -13 614 462 ; +C 120 ; WX 500 ; N x ; B -46 -13 469 462 ; +C 121 ; WX 444 ; N y ; B -94 -205 392 462 ; +C 122 ; WX 389 ; N z ; B -43 -78 368 449 ; +C 123 ; WX 348 ; N braceleft ; B 5 -187 436 686 ; +C 124 ; WX 220 ; N bar ; B 66 -218 154 782 ; +C 125 ; WX 348 ; N braceright ; B -129 -187 302 686 ; +C 126 ; WX 570 ; N asciitilde ; B 54 173 516 333 ; +C 161 ; WX 389 ; N exclamdown ; B 19 -205 322 492 ; +C 162 ; WX 500 ; N cent ; B 42 -143 439 576 ; +C 163 ; WX 500 ; N sterling ; B -32 -12 510 683 ; +C 164 ; WX 167 ; N fraction ; B -169 -14 324 683 ; +C 165 ; WX 500 ; N yen ; B 33 0 628 669 ; +C 166 ; WX 500 ; N florin ; B -87 -156 537 707 ; +C 167 ; WX 500 ; N section ; B 36 -143 459 685 ; +C 168 ; WX 500 ; N currency ; B -26 34 526 586 ; +C 169 ; WX 278 ; N quotesingle ; B 128 398 268 685 ; +C 170 ; WX 500 ; N quotedblleft ; B 53 369 513 685 ; +C 171 ; WX 500 ; N guillemotleft ; B 12 32 468 415 ; +C 172 ; WX 333 ; N guilsinglleft ; B 32 32 303 415 ; +C 173 ; WX 333 ; N guilsinglright ; B 10 32 281 415 ; +C 174 ; WX 556 ; N fi ; B -188 -205 514 703 ; +C 175 ; WX 556 ; N fl ; B -186 -205 553 704 ; +C 177 ; WX 500 ; N endash ; B -40 178 477 269 ; +C 178 ; WX 500 ; N dagger ; B 91 -145 494 685 ; +C 179 ; WX 500 ; N daggerdbl ; B 10 -139 493 685 ; +C 180 ; WX 250 ; N periodcentered ; B 51 257 199 405 ; +C 182 ; WX 500 ; N paragraph ; B -57 -193 562 669 ; +C 183 ; WX 350 ; N bullet ; B 0 175 350 525 ; +C 184 ; WX 333 ; N quotesinglbase ; B -5 -182 199 134 ; +C 185 ; WX 500 ; N quotedblbase ; B -57 -182 403 134 ; +C 186 ; WX 500 ; N quotedblright ; B 53 369 513 685 ; +C 187 ; WX 500 ; N guillemotright ; B 12 32 468 415 ; +C 188 ; WX 1000 ; N ellipsis ; B 40 -13 852 135 ; +C 189 ; WX 1000 ; N perthousand ; B 7 -29 996 706 ; +C 191 ; WX 500 ; N questiondown ; B 30 -205 421 492 ; +C 193 ; WX 333 ; N grave ; B 85 516 297 697 ; +C 194 ; WX 333 ; N acute ; B 139 516 379 697 ; +C 195 ; WX 333 ; N circumflex ; B 40 516 367 690 ; +C 196 ; WX 333 ; N tilde ; B 48 536 407 655 ; +C 197 ; WX 333 ; N macron ; B 51 553 393 623 ; +C 198 ; WX 333 ; N breve ; B 71 516 387 678 ; +C 199 ; WX 333 ; N dotaccent ; B 163 550 298 684 ; +C 200 ; WX 333 ; N dieresis ; B 55 550 402 684 ; +C 202 ; WX 333 ; N ring ; B 127 516 340 729 ; +C 203 ; WX 333 ; N cedilla ; B -80 -218 156 5 ; +C 205 ; WX 333 ; N hungarumlaut ; B 69 516 498 697 ; +C 206 ; WX 333 ; N ogonek ; B 15 -183 244 34 ; +C 207 ; WX 333 ; N caron ; B 79 516 411 690 ; +C 208 ; WX 1000 ; N emdash ; B -40 178 977 269 ; +C 225 ; WX 944 ; N AE ; B -64 0 918 669 ; +C 227 ; WX 266 ; N ordfeminine ; B 16 399 330 685 ; +C 232 ; WX 611 ; N Lslash ; B -22 0 590 669 ; +C 233 ; WX 722 ; N Oslash ; B 27 -125 691 764 ; +C 234 ; WX 944 ; N OE ; B 23 -8 946 677 ; +C 235 ; WX 300 ; N ordmasculine ; B 56 400 347 685 ; +C 241 ; WX 722 ; N ae ; B -5 -13 673 462 ; +C 245 ; WX 278 ; N dotlessi ; B 2 -9 238 462 ; +C 248 ; WX 278 ; N lslash ; B -7 -9 307 699 ; +C 249 ; WX 500 ; N oslash ; B -3 -119 441 560 ; +C 250 ; WX 722 ; N oe ; B 6 -13 674 462 ; +C 251 ; WX 500 ; N germandbls ; B -200 -200 473 705 ; +C -1 ; WX 389 ; N Idieresis ; B -32 0 450 862 ; +C -1 ; WX 444 ; N eacute ; B 5 -13 435 697 ; +C -1 ; WX 500 ; N abreve ; B -21 -14 471 678 ; +C -1 ; WX 556 ; N uhungarumlaut ; B 15 -9 610 697 ; +C -1 ; WX 444 ; N ecaron ; B 5 -13 467 690 ; +C -1 ; WX 611 ; N Ydieresis ; B 73 0 659 862 ; +C -1 ; WX 570 ; N divide ; B 33 -29 537 535 ; +C -1 ; WX 611 ; N Yacute ; B 73 0 659 904 ; +C -1 ; WX 667 ; N Acircumflex ; B -67 0 593 897 ; +C -1 ; WX 500 ; N aacute ; B -21 -14 463 697 ; +C -1 ; WX 722 ; N Ucircumflex ; B 67 -18 744 897 ; +C -1 ; WX 444 ; N yacute ; B -94 -205 435 697 ; +C -1 ; WX 389 ; N scommaaccent ; B -19 -218 333 462 ; +C -1 ; WX 444 ; N ecircumflex ; B 5 -13 423 690 ; +C -1 ; WX 722 ; N Uring ; B 67 -18 744 921 ; +C -1 ; WX 722 ; N Udieresis ; B 67 -18 744 862 ; +C -1 ; WX 500 ; N aogonek ; B -21 -183 455 462 ; +C -1 ; WX 722 ; N Uacute ; B 67 -18 744 904 ; +C -1 ; WX 556 ; N uogonek ; B 15 -183 492 462 ; +C -1 ; WX 667 ; N Edieresis ; B -27 0 653 862 ; +C -1 ; WX 722 ; N Dcroat ; B -31 0 700 669 ; +C -1 ; WX 250 ; N commaaccent ; B -36 -218 131 -50 ; +C -1 ; WX 747 ; N copyright ; B 30 -18 718 685 ; +C -1 ; WX 667 ; N Emacron ; B -27 0 653 830 ; +C -1 ; WX 444 ; N ccaron ; B -5 -13 467 690 ; +C -1 ; WX 500 ; N aring ; B -21 -14 455 729 ; +C -1 ; WX 722 ; N Ncommaaccent ; B -27 -218 748 669 ; +C -1 ; WX 278 ; N lacute ; B 2 -9 392 904 ; +C -1 ; WX 500 ; N agrave ; B -21 -14 455 697 ; +C -1 ; WX 611 ; N Tcommaaccent ; B 50 -218 650 669 ; +C -1 ; WX 667 ; N Cacute ; B 32 -18 677 904 ; +C -1 ; WX 500 ; N atilde ; B -21 -14 491 655 ; +C -1 ; WX 667 ; N Edotaccent ; B -27 0 653 862 ; +C -1 ; WX 389 ; N scaron ; B -19 -13 424 690 ; +C -1 ; WX 389 ; N scedilla ; B -19 -218 333 462 ; +C -1 ; WX 278 ; N iacute ; B 2 -9 352 697 ; +C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ; +C -1 ; WX 667 ; N Rcaron ; B -29 0 623 897 ; +C -1 ; WX 722 ; N Gcommaaccent ; B 21 -218 706 685 ; +C -1 ; WX 556 ; N ucircumflex ; B 15 -9 492 690 ; +C -1 ; WX 500 ; N acircumflex ; B -21 -14 455 690 ; +C -1 ; WX 667 ; N Amacron ; B -67 0 593 830 ; +C -1 ; WX 389 ; N rcaron ; B -21 0 424 690 ; +C -1 ; WX 444 ; N ccedilla ; B -5 -218 392 462 ; +C -1 ; WX 611 ; N Zdotaccent ; B -11 0 590 862 ; +C -1 ; WX 611 ; N Thorn ; B -27 0 573 669 ; +C -1 ; WX 722 ; N Omacron ; B 27 -18 691 830 ; +C -1 ; WX 667 ; N Racute ; B -29 0 623 904 ; +C -1 ; WX 556 ; N Sacute ; B 2 -18 531 904 ; +C -1 ; WX 608 ; N dcaron ; B -21 -13 675 708 ; +C -1 ; WX 722 ; N Umacron ; B 67 -18 744 830 ; +C -1 ; WX 556 ; N uring ; B 15 -9 492 729 ; +C -1 ; WX 300 ; N threesuperior ; B 17 265 321 683 ; +C -1 ; WX 722 ; N Ograve ; B 27 -18 691 904 ; +C -1 ; WX 667 ; N Agrave ; B -67 0 593 904 ; +C -1 ; WX 667 ; N Abreve ; B -67 0 593 885 ; +C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ; +C -1 ; WX 556 ; N uacute ; B 15 -9 492 697 ; +C -1 ; WX 611 ; N Tcaron ; B 50 0 650 897 ; +C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ; +C -1 ; WX 444 ; N ydieresis ; B -94 -205 443 655 ; +C -1 ; WX 722 ; N Nacute ; B -27 -15 748 904 ; +C -1 ; WX 278 ; N icircumflex ; B -3 -9 324 690 ; +C -1 ; WX 667 ; N Ecircumflex ; B -27 0 653 897 ; +C -1 ; WX 500 ; N adieresis ; B -21 -14 476 655 ; +C -1 ; WX 444 ; N edieresis ; B 5 -13 448 655 ; +C -1 ; WX 444 ; N cacute ; B -5 -13 435 697 ; +C -1 ; WX 556 ; N nacute ; B -6 -9 493 697 ; +C -1 ; WX 556 ; N umacron ; B 15 -9 492 623 ; +C -1 ; WX 722 ; N Ncaron ; B -27 -15 748 897 ; +C -1 ; WX 389 ; N Iacute ; B -32 0 432 904 ; +C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ; +C -1 ; WX 220 ; N brokenbar ; B 66 -143 154 707 ; +C -1 ; WX 747 ; N registered ; B 30 -18 718 685 ; +C -1 ; WX 722 ; N Gbreve ; B 21 -18 706 885 ; +C -1 ; WX 389 ; N Idotaccent ; B -32 0 406 862 ; +C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ; +C -1 ; WX 667 ; N Egrave ; B -27 0 653 904 ; +C -1 ; WX 389 ; N racute ; B -21 0 407 697 ; +C -1 ; WX 500 ; N omacron ; B -3 -13 462 623 ; +C -1 ; WX 611 ; N Zacute ; B -11 0 590 904 ; +C -1 ; WX 611 ; N Zcaron ; B -11 0 590 897 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ; +C -1 ; WX 722 ; N Eth ; B -31 0 700 669 ; +C -1 ; WX 667 ; N Ccedilla ; B 32 -218 677 685 ; +C -1 ; WX 278 ; N lcommaaccent ; B -42 -218 290 699 ; +C -1 ; WX 366 ; N tcaron ; B -11 -9 434 754 ; +C -1 ; WX 444 ; N eogonek ; B 5 -183 398 462 ; +C -1 ; WX 722 ; N Uogonek ; B 67 -183 744 669 ; +C -1 ; WX 667 ; N Aacute ; B -67 0 593 904 ; +C -1 ; WX 667 ; N Adieresis ; B -67 0 593 862 ; +C -1 ; WX 444 ; N egrave ; B 5 -13 398 697 ; +C -1 ; WX 389 ; N zacute ; B -43 -78 407 697 ; +C -1 ; WX 278 ; N iogonek ; B -20 -183 263 684 ; +C -1 ; WX 722 ; N Oacute ; B 27 -18 691 904 ; +C -1 ; WX 500 ; N oacute ; B -3 -13 463 697 ; +C -1 ; WX 500 ; N amacron ; B -21 -14 467 623 ; +C -1 ; WX 389 ; N sacute ; B -19 -13 407 697 ; +C -1 ; WX 278 ; N idieresis ; B 2 -9 364 655 ; +C -1 ; WX 722 ; N Ocircumflex ; B 27 -18 691 897 ; +C -1 ; WX 722 ; N Ugrave ; B 67 -18 744 904 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 500 ; N thorn ; B -120 -205 446 699 ; +C -1 ; WX 300 ; N twosuperior ; B 2 274 313 683 ; +C -1 ; WX 722 ; N Odieresis ; B 27 -18 691 862 ; +C -1 ; WX 576 ; N mu ; B -60 -207 516 449 ; +C -1 ; WX 278 ; N igrave ; B 2 -9 259 697 ; +C -1 ; WX 500 ; N ohungarumlaut ; B -3 -13 582 697 ; +C -1 ; WX 667 ; N Eogonek ; B -27 -183 653 669 ; +C -1 ; WX 500 ; N dcroat ; B -21 -13 552 699 ; +C -1 ; WX 750 ; N threequarters ; B 7 -14 726 683 ; +C -1 ; WX 556 ; N Scedilla ; B 2 -218 526 685 ; +C -1 ; WX 382 ; N lcaron ; B 2 -9 448 708 ; +C -1 ; WX 667 ; N Kcommaaccent ; B -21 -218 702 669 ; +C -1 ; WX 611 ; N Lacute ; B -22 0 590 904 ; +C -1 ; WX 1000 ; N trademark ; B 32 263 968 669 ; +C -1 ; WX 444 ; N edotaccent ; B 5 -13 398 655 ; +C -1 ; WX 389 ; N Igrave ; B -32 0 406 904 ; +C -1 ; WX 389 ; N Imacron ; B -32 0 461 830 ; +C -1 ; WX 611 ; N Lcaron ; B -22 0 671 718 ; +C -1 ; WX 750 ; N onehalf ; B -9 -14 723 683 ; +C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ; +C -1 ; WX 500 ; N ocircumflex ; B -3 -13 451 690 ; +C -1 ; WX 556 ; N ntilde ; B -6 -9 504 655 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 67 -18 744 904 ; +C -1 ; WX 667 ; N Eacute ; B -27 0 653 904 ; +C -1 ; WX 444 ; N emacron ; B 5 -13 439 623 ; +C -1 ; WX 500 ; N gbreve ; B -52 -203 478 678 ; +C -1 ; WX 750 ; N onequarter ; B 7 -14 721 683 ; +C -1 ; WX 556 ; N Scaron ; B 2 -18 553 897 ; +C -1 ; WX 556 ; N Scommaaccent ; B 2 -218 526 685 ; +C -1 ; WX 722 ; N Ohungarumlaut ; B 27 -18 723 904 ; +C -1 ; WX 400 ; N degree ; B 83 397 369 683 ; +C -1 ; WX 500 ; N ograve ; B -3 -13 441 697 ; +C -1 ; WX 667 ; N Ccaron ; B 32 -18 677 897 ; +C -1 ; WX 556 ; N ugrave ; B 15 -9 492 697 ; +C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ; +C -1 ; WX 722 ; N Dcaron ; B -46 0 685 897 ; +C -1 ; WX 389 ; N rcommaaccent ; B -67 -218 389 462 ; +C -1 ; WX 722 ; N Ntilde ; B -27 -15 748 862 ; +C -1 ; WX 500 ; N otilde ; B -3 -13 491 655 ; +C -1 ; WX 667 ; N Rcommaaccent ; B -29 -218 623 669 ; +C -1 ; WX 611 ; N Lcommaaccent ; B -22 -218 590 669 ; +C -1 ; WX 667 ; N Atilde ; B -67 0 593 862 ; +C -1 ; WX 667 ; N Aogonek ; B -67 -183 604 683 ; +C -1 ; WX 667 ; N Aring ; B -67 0 593 921 ; +C -1 ; WX 722 ; N Otilde ; B 27 -18 691 862 ; +C -1 ; WX 389 ; N zdotaccent ; B -43 -78 368 655 ; +C -1 ; WX 667 ; N Ecaron ; B -27 0 653 897 ; +C -1 ; WX 389 ; N Iogonek ; B -32 -183 406 669 ; +C -1 ; WX 500 ; N kcommaaccent ; B -23 -218 483 699 ; +C -1 ; WX 606 ; N minus ; B 51 209 555 297 ; +C -1 ; WX 389 ; N Icircumflex ; B -32 0 450 897 ; +C -1 ; WX 556 ; N ncaron ; B -6 -9 523 690 ; +C -1 ; WX 278 ; N tcommaaccent ; B -62 -218 281 594 ; +C -1 ; WX 606 ; N logicalnot ; B 51 108 555 399 ; +C -1 ; WX 500 ; N odieresis ; B -3 -13 471 655 ; +C -1 ; WX 556 ; N udieresis ; B 15 -9 499 655 ; +C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ; +C -1 ; WX 500 ; N gcommaaccent ; B -52 -203 478 767 ; +C -1 ; WX 500 ; N eth ; B -3 -13 454 699 ; +C -1 ; WX 389 ; N zcaron ; B -43 -78 424 690 ; +C -1 ; WX 556 ; N ncommaaccent ; B -6 -218 493 462 ; +C -1 ; WX 300 ; N onesuperior ; B 30 274 301 683 ; +C -1 ; WX 278 ; N imacron ; B 2 -9 294 623 ; +C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2038 +KPX A C -65 +KPX A Cacute -65 +KPX A Ccaron -65 +KPX A Ccedilla -65 +KPX A G -60 +KPX A Gbreve -60 +KPX A Gcommaaccent -60 +KPX A O -50 +KPX A Oacute -50 +KPX A Ocircumflex -50 +KPX A Odieresis -50 +KPX A Ograve -50 +KPX A Ohungarumlaut -50 +KPX A Omacron -50 +KPX A Oslash -50 +KPX A Otilde -50 +KPX A Q -55 +KPX A T -55 +KPX A Tcaron -55 +KPX A Tcommaaccent -55 +KPX A U -50 +KPX A Uacute -50 +KPX A Ucircumflex -50 +KPX A Udieresis -50 +KPX A Ugrave -50 +KPX A Uhungarumlaut -50 +KPX A Umacron -50 +KPX A Uogonek -50 +KPX A Uring -50 +KPX A V -95 +KPX A W -100 +KPX A Y -70 +KPX A Yacute -70 +KPX A Ydieresis -70 +KPX A quoteright -74 +KPX A u -30 +KPX A uacute -30 +KPX A ucircumflex -30 +KPX A udieresis -30 +KPX A ugrave -30 +KPX A uhungarumlaut -30 +KPX A umacron -30 +KPX A uogonek -30 +KPX A uring -30 +KPX A v -74 +KPX A w -74 +KPX A y -74 +KPX A yacute -74 +KPX A ydieresis -74 +KPX Aacute C -65 +KPX Aacute Cacute -65 +KPX Aacute Ccaron -65 +KPX Aacute Ccedilla -65 +KPX Aacute G -60 +KPX Aacute Gbreve -60 +KPX Aacute Gcommaaccent -60 +KPX Aacute O -50 +KPX Aacute Oacute -50 +KPX Aacute Ocircumflex -50 +KPX Aacute Odieresis -50 +KPX Aacute Ograve -50 +KPX Aacute Ohungarumlaut -50 +KPX Aacute Omacron -50 +KPX Aacute Oslash -50 +KPX Aacute Otilde -50 +KPX Aacute Q -55 +KPX Aacute T -55 +KPX Aacute Tcaron -55 +KPX Aacute Tcommaaccent -55 +KPX Aacute U -50 +KPX Aacute Uacute -50 +KPX Aacute Ucircumflex -50 +KPX Aacute Udieresis -50 +KPX Aacute Ugrave -50 +KPX Aacute Uhungarumlaut -50 +KPX Aacute Umacron -50 +KPX Aacute Uogonek -50 +KPX Aacute Uring -50 +KPX Aacute V -95 +KPX Aacute W -100 +KPX Aacute Y -70 +KPX Aacute Yacute -70 +KPX Aacute Ydieresis -70 +KPX Aacute quoteright -74 +KPX Aacute u -30 +KPX Aacute uacute -30 +KPX Aacute ucircumflex -30 +KPX Aacute udieresis -30 +KPX Aacute ugrave -30 +KPX Aacute uhungarumlaut -30 +KPX Aacute umacron -30 +KPX Aacute uogonek -30 +KPX Aacute uring -30 +KPX Aacute v -74 +KPX Aacute w -74 +KPX Aacute y -74 +KPX Aacute yacute -74 +KPX Aacute ydieresis -74 +KPX Abreve C -65 +KPX Abreve Cacute -65 +KPX Abreve Ccaron -65 +KPX Abreve Ccedilla -65 +KPX Abreve G -60 +KPX Abreve Gbreve -60 +KPX Abreve Gcommaaccent -60 +KPX Abreve O -50 +KPX Abreve Oacute -50 +KPX Abreve Ocircumflex -50 +KPX Abreve Odieresis -50 +KPX Abreve Ograve -50 +KPX Abreve Ohungarumlaut -50 +KPX Abreve Omacron -50 +KPX Abreve Oslash -50 +KPX Abreve Otilde -50 +KPX Abreve Q -55 +KPX Abreve T -55 +KPX Abreve Tcaron -55 +KPX Abreve Tcommaaccent -55 +KPX Abreve U -50 +KPX Abreve Uacute -50 +KPX Abreve Ucircumflex -50 +KPX Abreve Udieresis -50 +KPX Abreve Ugrave -50 +KPX Abreve Uhungarumlaut -50 +KPX Abreve Umacron -50 +KPX Abreve Uogonek -50 +KPX Abreve Uring -50 +KPX Abreve V -95 +KPX Abreve W -100 +KPX Abreve Y -70 +KPX Abreve Yacute -70 +KPX Abreve Ydieresis -70 +KPX Abreve quoteright -74 +KPX Abreve u -30 +KPX Abreve uacute -30 +KPX Abreve ucircumflex -30 +KPX Abreve udieresis -30 +KPX Abreve ugrave -30 +KPX Abreve uhungarumlaut -30 +KPX Abreve umacron -30 +KPX Abreve uogonek -30 +KPX Abreve uring -30 +KPX Abreve v -74 +KPX Abreve w -74 +KPX Abreve y -74 +KPX Abreve yacute -74 +KPX Abreve ydieresis -74 +KPX Acircumflex C -65 +KPX Acircumflex Cacute -65 +KPX Acircumflex Ccaron -65 +KPX Acircumflex Ccedilla -65 +KPX Acircumflex G -60 +KPX Acircumflex Gbreve -60 +KPX Acircumflex Gcommaaccent -60 +KPX Acircumflex O -50 +KPX Acircumflex Oacute -50 +KPX Acircumflex Ocircumflex -50 +KPX Acircumflex Odieresis -50 +KPX Acircumflex Ograve -50 +KPX Acircumflex Ohungarumlaut -50 +KPX Acircumflex Omacron -50 +KPX Acircumflex Oslash -50 +KPX Acircumflex Otilde -50 +KPX Acircumflex Q -55 +KPX Acircumflex T -55 +KPX Acircumflex Tcaron -55 +KPX Acircumflex Tcommaaccent -55 +KPX Acircumflex U -50 +KPX Acircumflex Uacute -50 +KPX Acircumflex Ucircumflex -50 +KPX Acircumflex Udieresis -50 +KPX Acircumflex Ugrave -50 +KPX Acircumflex Uhungarumlaut -50 +KPX Acircumflex Umacron -50 +KPX Acircumflex Uogonek -50 +KPX Acircumflex Uring -50 +KPX Acircumflex V -95 +KPX Acircumflex W -100 +KPX Acircumflex Y -70 +KPX Acircumflex Yacute -70 +KPX Acircumflex Ydieresis -70 +KPX Acircumflex quoteright -74 +KPX Acircumflex u -30 +KPX Acircumflex uacute -30 +KPX Acircumflex ucircumflex -30 +KPX Acircumflex udieresis -30 +KPX Acircumflex ugrave -30 +KPX Acircumflex uhungarumlaut -30 +KPX Acircumflex umacron -30 +KPX Acircumflex uogonek -30 +KPX Acircumflex uring -30 +KPX Acircumflex v -74 +KPX Acircumflex w -74 +KPX Acircumflex y -74 +KPX Acircumflex yacute -74 +KPX Acircumflex ydieresis -74 +KPX Adieresis C -65 +KPX Adieresis Cacute -65 +KPX Adieresis Ccaron -65 +KPX Adieresis Ccedilla -65 +KPX Adieresis G -60 +KPX Adieresis Gbreve -60 +KPX Adieresis Gcommaaccent -60 +KPX Adieresis O -50 +KPX Adieresis Oacute -50 +KPX Adieresis Ocircumflex -50 +KPX Adieresis Odieresis -50 +KPX Adieresis Ograve -50 +KPX Adieresis Ohungarumlaut -50 +KPX Adieresis Omacron -50 +KPX Adieresis Oslash -50 +KPX Adieresis Otilde -50 +KPX Adieresis Q -55 +KPX Adieresis T -55 +KPX Adieresis Tcaron -55 +KPX Adieresis Tcommaaccent -55 +KPX Adieresis U -50 +KPX Adieresis Uacute -50 +KPX Adieresis Ucircumflex -50 +KPX Adieresis Udieresis -50 +KPX Adieresis Ugrave -50 +KPX Adieresis Uhungarumlaut -50 +KPX Adieresis Umacron -50 +KPX Adieresis Uogonek -50 +KPX Adieresis Uring -50 +KPX Adieresis V -95 +KPX Adieresis W -100 +KPX Adieresis Y -70 +KPX Adieresis Yacute -70 +KPX Adieresis Ydieresis -70 +KPX Adieresis quoteright -74 +KPX Adieresis u -30 +KPX Adieresis uacute -30 +KPX Adieresis ucircumflex -30 +KPX Adieresis udieresis -30 +KPX Adieresis ugrave -30 +KPX Adieresis uhungarumlaut -30 +KPX Adieresis umacron -30 +KPX Adieresis uogonek -30 +KPX Adieresis uring -30 +KPX Adieresis v -74 +KPX Adieresis w -74 +KPX Adieresis y -74 +KPX Adieresis yacute -74 +KPX Adieresis ydieresis -74 +KPX Agrave C -65 +KPX Agrave Cacute -65 +KPX Agrave Ccaron -65 +KPX Agrave Ccedilla -65 +KPX Agrave G -60 +KPX Agrave Gbreve -60 +KPX Agrave Gcommaaccent -60 +KPX Agrave O -50 +KPX Agrave Oacute -50 +KPX Agrave Ocircumflex -50 +KPX Agrave Odieresis -50 +KPX Agrave Ograve -50 +KPX Agrave Ohungarumlaut -50 +KPX Agrave Omacron -50 +KPX Agrave Oslash -50 +KPX Agrave Otilde -50 +KPX Agrave Q -55 +KPX Agrave T -55 +KPX Agrave Tcaron -55 +KPX Agrave Tcommaaccent -55 +KPX Agrave U -50 +KPX Agrave Uacute -50 +KPX Agrave Ucircumflex -50 +KPX Agrave Udieresis -50 +KPX Agrave Ugrave -50 +KPX Agrave Uhungarumlaut -50 +KPX Agrave Umacron -50 +KPX Agrave Uogonek -50 +KPX Agrave Uring -50 +KPX Agrave V -95 +KPX Agrave W -100 +KPX Agrave Y -70 +KPX Agrave Yacute -70 +KPX Agrave Ydieresis -70 +KPX Agrave quoteright -74 +KPX Agrave u -30 +KPX Agrave uacute -30 +KPX Agrave ucircumflex -30 +KPX Agrave udieresis -30 +KPX Agrave ugrave -30 +KPX Agrave uhungarumlaut -30 +KPX Agrave umacron -30 +KPX Agrave uogonek -30 +KPX Agrave uring -30 +KPX Agrave v -74 +KPX Agrave w -74 +KPX Agrave y -74 +KPX Agrave yacute -74 +KPX Agrave ydieresis -74 +KPX Amacron C -65 +KPX Amacron Cacute -65 +KPX Amacron Ccaron -65 +KPX Amacron Ccedilla -65 +KPX Amacron G -60 +KPX Amacron Gbreve -60 +KPX Amacron Gcommaaccent -60 +KPX Amacron O -50 +KPX Amacron Oacute -50 +KPX Amacron Ocircumflex -50 +KPX Amacron Odieresis -50 +KPX Amacron Ograve -50 +KPX Amacron Ohungarumlaut -50 +KPX Amacron Omacron -50 +KPX Amacron Oslash -50 +KPX Amacron Otilde -50 +KPX Amacron Q -55 +KPX Amacron T -55 +KPX Amacron Tcaron -55 +KPX Amacron Tcommaaccent -55 +KPX Amacron U -50 +KPX Amacron Uacute -50 +KPX Amacron Ucircumflex -50 +KPX Amacron Udieresis -50 +KPX Amacron Ugrave -50 +KPX Amacron Uhungarumlaut -50 +KPX Amacron Umacron -50 +KPX Amacron Uogonek -50 +KPX Amacron Uring -50 +KPX Amacron V -95 +KPX Amacron W -100 +KPX Amacron Y -70 +KPX Amacron Yacute -70 +KPX Amacron Ydieresis -70 +KPX Amacron quoteright -74 +KPX Amacron u -30 +KPX Amacron uacute -30 +KPX Amacron ucircumflex -30 +KPX Amacron udieresis -30 +KPX Amacron ugrave -30 +KPX Amacron uhungarumlaut -30 +KPX Amacron umacron -30 +KPX Amacron uogonek -30 +KPX Amacron uring -30 +KPX Amacron v -74 +KPX Amacron w -74 +KPX Amacron y -74 +KPX Amacron yacute -74 +KPX Amacron ydieresis -74 +KPX Aogonek C -65 +KPX Aogonek Cacute -65 +KPX Aogonek Ccaron -65 +KPX Aogonek Ccedilla -65 +KPX Aogonek G -60 +KPX Aogonek Gbreve -60 +KPX Aogonek Gcommaaccent -60 +KPX Aogonek O -50 +KPX Aogonek Oacute -50 +KPX Aogonek Ocircumflex -50 +KPX Aogonek Odieresis -50 +KPX Aogonek Ograve -50 +KPX Aogonek Ohungarumlaut -50 +KPX Aogonek Omacron -50 +KPX Aogonek Oslash -50 +KPX Aogonek Otilde -50 +KPX Aogonek Q -55 +KPX Aogonek T -55 +KPX Aogonek Tcaron -55 +KPX Aogonek Tcommaaccent -55 +KPX Aogonek U -50 +KPX Aogonek Uacute -50 +KPX Aogonek Ucircumflex -50 +KPX Aogonek Udieresis -50 +KPX Aogonek Ugrave -50 +KPX Aogonek Uhungarumlaut -50 +KPX Aogonek Umacron -50 +KPX Aogonek Uogonek -50 +KPX Aogonek Uring -50 +KPX Aogonek V -95 +KPX Aogonek W -100 +KPX Aogonek Y -70 +KPX Aogonek Yacute -70 +KPX Aogonek Ydieresis -70 +KPX Aogonek quoteright -74 +KPX Aogonek u -30 +KPX Aogonek uacute -30 +KPX Aogonek ucircumflex -30 +KPX Aogonek udieresis -30 +KPX Aogonek ugrave -30 +KPX Aogonek uhungarumlaut -30 +KPX Aogonek umacron -30 +KPX Aogonek uogonek -30 +KPX Aogonek uring -30 +KPX Aogonek v -74 +KPX Aogonek w -74 +KPX Aogonek y -34 +KPX Aogonek yacute -34 +KPX Aogonek ydieresis -34 +KPX Aring C -65 +KPX Aring Cacute -65 +KPX Aring Ccaron -65 +KPX Aring Ccedilla -65 +KPX Aring G -60 +KPX Aring Gbreve -60 +KPX Aring Gcommaaccent -60 +KPX Aring O -50 +KPX Aring Oacute -50 +KPX Aring Ocircumflex -50 +KPX Aring Odieresis -50 +KPX Aring Ograve -50 +KPX Aring Ohungarumlaut -50 +KPX Aring Omacron -50 +KPX Aring Oslash -50 +KPX Aring Otilde -50 +KPX Aring Q -55 +KPX Aring T -55 +KPX Aring Tcaron -55 +KPX Aring Tcommaaccent -55 +KPX Aring U -50 +KPX Aring Uacute -50 +KPX Aring Ucircumflex -50 +KPX Aring Udieresis -50 +KPX Aring Ugrave -50 +KPX Aring Uhungarumlaut -50 +KPX Aring Umacron -50 +KPX Aring Uogonek -50 +KPX Aring Uring -50 +KPX Aring V -95 +KPX Aring W -100 +KPX Aring Y -70 +KPX Aring Yacute -70 +KPX Aring Ydieresis -70 +KPX Aring quoteright -74 +KPX Aring u -30 +KPX Aring uacute -30 +KPX Aring ucircumflex -30 +KPX Aring udieresis -30 +KPX Aring ugrave -30 +KPX Aring uhungarumlaut -30 +KPX Aring umacron -30 +KPX Aring uogonek -30 +KPX Aring uring -30 +KPX Aring v -74 +KPX Aring w -74 +KPX Aring y -74 +KPX Aring yacute -74 +KPX Aring ydieresis -74 +KPX Atilde C -65 +KPX Atilde Cacute -65 +KPX Atilde Ccaron -65 +KPX Atilde Ccedilla -65 +KPX Atilde G -60 +KPX Atilde Gbreve -60 +KPX Atilde Gcommaaccent -60 +KPX Atilde O -50 +KPX Atilde Oacute -50 +KPX Atilde Ocircumflex -50 +KPX Atilde Odieresis -50 +KPX Atilde Ograve -50 +KPX Atilde Ohungarumlaut -50 +KPX Atilde Omacron -50 +KPX Atilde Oslash -50 +KPX Atilde Otilde -50 +KPX Atilde Q -55 +KPX Atilde T -55 +KPX Atilde Tcaron -55 +KPX Atilde Tcommaaccent -55 +KPX Atilde U -50 +KPX Atilde Uacute -50 +KPX Atilde Ucircumflex -50 +KPX Atilde Udieresis -50 +KPX Atilde Ugrave -50 +KPX Atilde Uhungarumlaut -50 +KPX Atilde Umacron -50 +KPX Atilde Uogonek -50 +KPX Atilde Uring -50 +KPX Atilde V -95 +KPX Atilde W -100 +KPX Atilde Y -70 +KPX Atilde Yacute -70 +KPX Atilde Ydieresis -70 +KPX Atilde quoteright -74 +KPX Atilde u -30 +KPX Atilde uacute -30 +KPX Atilde ucircumflex -30 +KPX Atilde udieresis -30 +KPX Atilde ugrave -30 +KPX Atilde uhungarumlaut -30 +KPX Atilde umacron -30 +KPX Atilde uogonek -30 +KPX Atilde uring -30 +KPX Atilde v -74 +KPX Atilde w -74 +KPX Atilde y -74 +KPX Atilde yacute -74 +KPX Atilde ydieresis -74 +KPX B A -25 +KPX B Aacute -25 +KPX B Abreve -25 +KPX B Acircumflex -25 +KPX B Adieresis -25 +KPX B Agrave -25 +KPX B Amacron -25 +KPX B Aogonek -25 +KPX B Aring -25 +KPX B Atilde -25 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX D A -25 +KPX D Aacute -25 +KPX D Abreve -25 +KPX D Acircumflex -25 +KPX D Adieresis -25 +KPX D Agrave -25 +KPX D Amacron -25 +KPX D Aogonek -25 +KPX D Aring -25 +KPX D Atilde -25 +KPX D V -50 +KPX D W -40 +KPX D Y -50 +KPX D Yacute -50 +KPX D Ydieresis -50 +KPX Dcaron A -25 +KPX Dcaron Aacute -25 +KPX Dcaron Abreve -25 +KPX Dcaron Acircumflex -25 +KPX Dcaron Adieresis -25 +KPX Dcaron Agrave -25 +KPX Dcaron Amacron -25 +KPX Dcaron Aogonek -25 +KPX Dcaron Aring -25 +KPX Dcaron Atilde -25 +KPX Dcaron V -50 +KPX Dcaron W -40 +KPX Dcaron Y -50 +KPX Dcaron Yacute -50 +KPX Dcaron Ydieresis -50 +KPX Dcroat A -25 +KPX Dcroat Aacute -25 +KPX Dcroat Abreve -25 +KPX Dcroat Acircumflex -25 +KPX Dcroat Adieresis -25 +KPX Dcroat Agrave -25 +KPX Dcroat Amacron -25 +KPX Dcroat Aogonek -25 +KPX Dcroat Aring -25 +KPX Dcroat Atilde -25 +KPX Dcroat V -50 +KPX Dcroat W -40 +KPX Dcroat Y -50 +KPX Dcroat Yacute -50 +KPX Dcroat Ydieresis -50 +KPX F A -100 +KPX F Aacute -100 +KPX F Abreve -100 +KPX F Acircumflex -100 +KPX F Adieresis -100 +KPX F Agrave -100 +KPX F Amacron -100 +KPX F Aogonek -100 +KPX F Aring -100 +KPX F Atilde -100 +KPX F a -95 +KPX F aacute -95 +KPX F abreve -95 +KPX F acircumflex -95 +KPX F adieresis -95 +KPX F agrave -95 +KPX F amacron -95 +KPX F aogonek -95 +KPX F aring -95 +KPX F atilde -95 +KPX F comma -129 +KPX F e -100 +KPX F eacute -100 +KPX F ecaron -100 +KPX F ecircumflex -100 +KPX F edieresis -100 +KPX F edotaccent -100 +KPX F egrave -100 +KPX F emacron -100 +KPX F eogonek -100 +KPX F i -40 +KPX F iacute -40 +KPX F icircumflex -40 +KPX F idieresis -40 +KPX F igrave -40 +KPX F imacron -40 +KPX F iogonek -40 +KPX F o -70 +KPX F oacute -70 +KPX F ocircumflex -70 +KPX F odieresis -70 +KPX F ograve -70 +KPX F ohungarumlaut -70 +KPX F omacron -70 +KPX F oslash -70 +KPX F otilde -70 +KPX F period -129 +KPX F r -50 +KPX F racute -50 +KPX F rcaron -50 +KPX F rcommaaccent -50 +KPX J A -25 +KPX J Aacute -25 +KPX J Abreve -25 +KPX J Acircumflex -25 +KPX J Adieresis -25 +KPX J Agrave -25 +KPX J Amacron -25 +KPX J Aogonek -25 +KPX J Aring -25 +KPX J Atilde -25 +KPX J a -40 +KPX J aacute -40 +KPX J abreve -40 +KPX J acircumflex -40 +KPX J adieresis -40 +KPX J agrave -40 +KPX J amacron -40 +KPX J aogonek -40 +KPX J aring -40 +KPX J atilde -40 +KPX J comma -10 +KPX J e -40 +KPX J eacute -40 +KPX J ecaron -40 +KPX J ecircumflex -40 +KPX J edieresis -40 +KPX J edotaccent -40 +KPX J egrave -40 +KPX J emacron -40 +KPX J eogonek -40 +KPX J o -40 +KPX J oacute -40 +KPX J ocircumflex -40 +KPX J odieresis -40 +KPX J ograve -40 +KPX J ohungarumlaut -40 +KPX J omacron -40 +KPX J oslash -40 +KPX J otilde -40 +KPX J period -10 +KPX J u -40 +KPX J uacute -40 +KPX J ucircumflex -40 +KPX J udieresis -40 +KPX J ugrave -40 +KPX J uhungarumlaut -40 +KPX J umacron -40 +KPX J uogonek -40 +KPX J uring -40 +KPX K O -30 +KPX K Oacute -30 +KPX K Ocircumflex -30 +KPX K Odieresis -30 +KPX K Ograve -30 +KPX K Ohungarumlaut -30 +KPX K Omacron -30 +KPX K Oslash -30 +KPX K Otilde -30 +KPX K e -25 +KPX K eacute -25 +KPX K ecaron -25 +KPX K ecircumflex -25 +KPX K edieresis -25 +KPX K edotaccent -25 +KPX K egrave -25 +KPX K emacron -25 +KPX K eogonek -25 +KPX K o -25 +KPX K oacute -25 +KPX K ocircumflex -25 +KPX K odieresis -25 +KPX K ograve -25 +KPX K ohungarumlaut -25 +KPX K omacron -25 +KPX K oslash -25 +KPX K otilde -25 +KPX K u -20 +KPX K uacute -20 +KPX K ucircumflex -20 +KPX K udieresis -20 +KPX K ugrave -20 +KPX K uhungarumlaut -20 +KPX K umacron -20 +KPX K uogonek -20 +KPX K uring -20 +KPX K y -20 +KPX K yacute -20 +KPX K ydieresis -20 +KPX Kcommaaccent O -30 +KPX Kcommaaccent Oacute -30 +KPX Kcommaaccent Ocircumflex -30 +KPX Kcommaaccent Odieresis -30 +KPX Kcommaaccent Ograve -30 +KPX Kcommaaccent Ohungarumlaut -30 +KPX Kcommaaccent Omacron -30 +KPX Kcommaaccent Oslash -30 +KPX Kcommaaccent Otilde -30 +KPX Kcommaaccent e -25 +KPX Kcommaaccent eacute -25 +KPX Kcommaaccent ecaron -25 +KPX Kcommaaccent ecircumflex -25 +KPX Kcommaaccent edieresis -25 +KPX Kcommaaccent edotaccent -25 +KPX Kcommaaccent egrave -25 +KPX Kcommaaccent emacron -25 +KPX Kcommaaccent eogonek -25 +KPX Kcommaaccent o -25 +KPX Kcommaaccent oacute -25 +KPX Kcommaaccent ocircumflex -25 +KPX Kcommaaccent odieresis -25 +KPX Kcommaaccent ograve -25 +KPX Kcommaaccent ohungarumlaut -25 +KPX Kcommaaccent omacron -25 +KPX Kcommaaccent oslash -25 +KPX Kcommaaccent otilde -25 +KPX Kcommaaccent u -20 +KPX Kcommaaccent uacute -20 +KPX Kcommaaccent ucircumflex -20 +KPX Kcommaaccent udieresis -20 +KPX Kcommaaccent ugrave -20 +KPX Kcommaaccent uhungarumlaut -20 +KPX Kcommaaccent umacron -20 +KPX Kcommaaccent uogonek -20 +KPX Kcommaaccent uring -20 +KPX Kcommaaccent y -20 +KPX Kcommaaccent yacute -20 +KPX Kcommaaccent ydieresis -20 +KPX L T -18 +KPX L Tcaron -18 +KPX L Tcommaaccent -18 +KPX L V -37 +KPX L W -37 +KPX L Y -37 +KPX L Yacute -37 +KPX L Ydieresis -37 +KPX L quoteright -55 +KPX L y -37 +KPX L yacute -37 +KPX L ydieresis -37 +KPX Lacute T -18 +KPX Lacute Tcaron -18 +KPX Lacute Tcommaaccent -18 +KPX Lacute V -37 +KPX Lacute W -37 +KPX Lacute Y -37 +KPX Lacute Yacute -37 +KPX Lacute Ydieresis -37 +KPX Lacute quoteright -55 +KPX Lacute y -37 +KPX Lacute yacute -37 +KPX Lacute ydieresis -37 +KPX Lcommaaccent T -18 +KPX Lcommaaccent Tcaron -18 +KPX Lcommaaccent Tcommaaccent -18 +KPX Lcommaaccent V -37 +KPX Lcommaaccent W -37 +KPX Lcommaaccent Y -37 +KPX Lcommaaccent Yacute -37 +KPX Lcommaaccent Ydieresis -37 +KPX Lcommaaccent quoteright -55 +KPX Lcommaaccent y -37 +KPX Lcommaaccent yacute -37 +KPX Lcommaaccent ydieresis -37 +KPX Lslash T -18 +KPX Lslash Tcaron -18 +KPX Lslash Tcommaaccent -18 +KPX Lslash V -37 +KPX Lslash W -37 +KPX Lslash Y -37 +KPX Lslash Yacute -37 +KPX Lslash Ydieresis -37 +KPX Lslash quoteright -55 +KPX Lslash y -37 +KPX Lslash yacute -37 +KPX Lslash ydieresis -37 +KPX N A -30 +KPX N Aacute -30 +KPX N Abreve -30 +KPX N Acircumflex -30 +KPX N Adieresis -30 +KPX N Agrave -30 +KPX N Amacron -30 +KPX N Aogonek -30 +KPX N Aring -30 +KPX N Atilde -30 +KPX Nacute A -30 +KPX Nacute Aacute -30 +KPX Nacute Abreve -30 +KPX Nacute Acircumflex -30 +KPX Nacute Adieresis -30 +KPX Nacute Agrave -30 +KPX Nacute Amacron -30 +KPX Nacute Aogonek -30 +KPX Nacute Aring -30 +KPX Nacute Atilde -30 +KPX Ncaron A -30 +KPX Ncaron Aacute -30 +KPX Ncaron Abreve -30 +KPX Ncaron Acircumflex -30 +KPX Ncaron Adieresis -30 +KPX Ncaron Agrave -30 +KPX Ncaron Amacron -30 +KPX Ncaron Aogonek -30 +KPX Ncaron Aring -30 +KPX Ncaron Atilde -30 +KPX Ncommaaccent A -30 +KPX Ncommaaccent Aacute -30 +KPX Ncommaaccent Abreve -30 +KPX Ncommaaccent Acircumflex -30 +KPX Ncommaaccent Adieresis -30 +KPX Ncommaaccent Agrave -30 +KPX Ncommaaccent Amacron -30 +KPX Ncommaaccent Aogonek -30 +KPX Ncommaaccent Aring -30 +KPX Ncommaaccent Atilde -30 +KPX Ntilde A -30 +KPX Ntilde Aacute -30 +KPX Ntilde Abreve -30 +KPX Ntilde Acircumflex -30 +KPX Ntilde Adieresis -30 +KPX Ntilde Agrave -30 +KPX Ntilde Amacron -30 +KPX Ntilde Aogonek -30 +KPX Ntilde Aring -30 +KPX Ntilde Atilde -30 +KPX O A -40 +KPX O Aacute -40 +KPX O Abreve -40 +KPX O Acircumflex -40 +KPX O Adieresis -40 +KPX O Agrave -40 +KPX O Amacron -40 +KPX O Aogonek -40 +KPX O Aring -40 +KPX O Atilde -40 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -50 +KPX O X -40 +KPX O Y -50 +KPX O Yacute -50 +KPX O Ydieresis -50 +KPX Oacute A -40 +KPX Oacute Aacute -40 +KPX Oacute Abreve -40 +KPX Oacute Acircumflex -40 +KPX Oacute Adieresis -40 +KPX Oacute Agrave -40 +KPX Oacute Amacron -40 +KPX Oacute Aogonek -40 +KPX Oacute Aring -40 +KPX Oacute Atilde -40 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -50 +KPX Oacute X -40 +KPX Oacute Y -50 +KPX Oacute Yacute -50 +KPX Oacute Ydieresis -50 +KPX Ocircumflex A -40 +KPX Ocircumflex Aacute -40 +KPX Ocircumflex Abreve -40 +KPX Ocircumflex Acircumflex -40 +KPX Ocircumflex Adieresis -40 +KPX Ocircumflex Agrave -40 +KPX Ocircumflex Amacron -40 +KPX Ocircumflex Aogonek -40 +KPX Ocircumflex Aring -40 +KPX Ocircumflex Atilde -40 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -50 +KPX Ocircumflex X -40 +KPX Ocircumflex Y -50 +KPX Ocircumflex Yacute -50 +KPX Ocircumflex Ydieresis -50 +KPX Odieresis A -40 +KPX Odieresis Aacute -40 +KPX Odieresis Abreve -40 +KPX Odieresis Acircumflex -40 +KPX Odieresis Adieresis -40 +KPX Odieresis Agrave -40 +KPX Odieresis Amacron -40 +KPX Odieresis Aogonek -40 +KPX Odieresis Aring -40 +KPX Odieresis Atilde -40 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -50 +KPX Odieresis X -40 +KPX Odieresis Y -50 +KPX Odieresis Yacute -50 +KPX Odieresis Ydieresis -50 +KPX Ograve A -40 +KPX Ograve Aacute -40 +KPX Ograve Abreve -40 +KPX Ograve Acircumflex -40 +KPX Ograve Adieresis -40 +KPX Ograve Agrave -40 +KPX Ograve Amacron -40 +KPX Ograve Aogonek -40 +KPX Ograve Aring -40 +KPX Ograve Atilde -40 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -50 +KPX Ograve X -40 +KPX Ograve Y -50 +KPX Ograve Yacute -50 +KPX Ograve Ydieresis -50 +KPX Ohungarumlaut A -40 +KPX Ohungarumlaut Aacute -40 +KPX Ohungarumlaut Abreve -40 +KPX Ohungarumlaut Acircumflex -40 +KPX Ohungarumlaut Adieresis -40 +KPX Ohungarumlaut Agrave -40 +KPX Ohungarumlaut Amacron -40 +KPX Ohungarumlaut Aogonek -40 +KPX Ohungarumlaut Aring -40 +KPX Ohungarumlaut Atilde -40 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -50 +KPX Ohungarumlaut X -40 +KPX Ohungarumlaut Y -50 +KPX Ohungarumlaut Yacute -50 +KPX Ohungarumlaut Ydieresis -50 +KPX Omacron A -40 +KPX Omacron Aacute -40 +KPX Omacron Abreve -40 +KPX Omacron Acircumflex -40 +KPX Omacron Adieresis -40 +KPX Omacron Agrave -40 +KPX Omacron Amacron -40 +KPX Omacron Aogonek -40 +KPX Omacron Aring -40 +KPX Omacron Atilde -40 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -50 +KPX Omacron X -40 +KPX Omacron Y -50 +KPX Omacron Yacute -50 +KPX Omacron Ydieresis -50 +KPX Oslash A -40 +KPX Oslash Aacute -40 +KPX Oslash Abreve -40 +KPX Oslash Acircumflex -40 +KPX Oslash Adieresis -40 +KPX Oslash Agrave -40 +KPX Oslash Amacron -40 +KPX Oslash Aogonek -40 +KPX Oslash Aring -40 +KPX Oslash Atilde -40 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -50 +KPX Oslash X -40 +KPX Oslash Y -50 +KPX Oslash Yacute -50 +KPX Oslash Ydieresis -50 +KPX Otilde A -40 +KPX Otilde Aacute -40 +KPX Otilde Abreve -40 +KPX Otilde Acircumflex -40 +KPX Otilde Adieresis -40 +KPX Otilde Agrave -40 +KPX Otilde Amacron -40 +KPX Otilde Aogonek -40 +KPX Otilde Aring -40 +KPX Otilde Atilde -40 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -50 +KPX Otilde X -40 +KPX Otilde Y -50 +KPX Otilde Yacute -50 +KPX Otilde Ydieresis -50 +KPX P A -85 +KPX P Aacute -85 +KPX P Abreve -85 +KPX P Acircumflex -85 +KPX P Adieresis -85 +KPX P Agrave -85 +KPX P Amacron -85 +KPX P Aogonek -85 +KPX P Aring -85 +KPX P Atilde -85 +KPX P a -40 +KPX P aacute -40 +KPX P abreve -40 +KPX P acircumflex -40 +KPX P adieresis -40 +KPX P agrave -40 +KPX P amacron -40 +KPX P aogonek -40 +KPX P aring -40 +KPX P atilde -40 +KPX P comma -129 +KPX P e -50 +KPX P eacute -50 +KPX P ecaron -50 +KPX P ecircumflex -50 +KPX P edieresis -50 +KPX P edotaccent -50 +KPX P egrave -50 +KPX P emacron -50 +KPX P eogonek -50 +KPX P o -55 +KPX P oacute -55 +KPX P ocircumflex -55 +KPX P odieresis -55 +KPX P ograve -55 +KPX P ohungarumlaut -55 +KPX P omacron -55 +KPX P oslash -55 +KPX P otilde -55 +KPX P period -129 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX R O -40 +KPX R Oacute -40 +KPX R Ocircumflex -40 +KPX R Odieresis -40 +KPX R Ograve -40 +KPX R Ohungarumlaut -40 +KPX R Omacron -40 +KPX R Oslash -40 +KPX R Otilde -40 +KPX R T -30 +KPX R Tcaron -30 +KPX R Tcommaaccent -30 +KPX R U -40 +KPX R Uacute -40 +KPX R Ucircumflex -40 +KPX R Udieresis -40 +KPX R Ugrave -40 +KPX R Uhungarumlaut -40 +KPX R Umacron -40 +KPX R Uogonek -40 +KPX R Uring -40 +KPX R V -18 +KPX R W -18 +KPX R Y -18 +KPX R Yacute -18 +KPX R Ydieresis -18 +KPX Racute O -40 +KPX Racute Oacute -40 +KPX Racute Ocircumflex -40 +KPX Racute Odieresis -40 +KPX Racute Ograve -40 +KPX Racute Ohungarumlaut -40 +KPX Racute Omacron -40 +KPX Racute Oslash -40 +KPX Racute Otilde -40 +KPX Racute T -30 +KPX Racute Tcaron -30 +KPX Racute Tcommaaccent -30 +KPX Racute U -40 +KPX Racute Uacute -40 +KPX Racute Ucircumflex -40 +KPX Racute Udieresis -40 +KPX Racute Ugrave -40 +KPX Racute Uhungarumlaut -40 +KPX Racute Umacron -40 +KPX Racute Uogonek -40 +KPX Racute Uring -40 +KPX Racute V -18 +KPX Racute W -18 +KPX Racute Y -18 +KPX Racute Yacute -18 +KPX Racute Ydieresis -18 +KPX Rcaron O -40 +KPX Rcaron Oacute -40 +KPX Rcaron Ocircumflex -40 +KPX Rcaron Odieresis -40 +KPX Rcaron Ograve -40 +KPX Rcaron Ohungarumlaut -40 +KPX Rcaron Omacron -40 +KPX Rcaron Oslash -40 +KPX Rcaron Otilde -40 +KPX Rcaron T -30 +KPX Rcaron Tcaron -30 +KPX Rcaron Tcommaaccent -30 +KPX Rcaron U -40 +KPX Rcaron Uacute -40 +KPX Rcaron Ucircumflex -40 +KPX Rcaron Udieresis -40 +KPX Rcaron Ugrave -40 +KPX Rcaron Uhungarumlaut -40 +KPX Rcaron Umacron -40 +KPX Rcaron Uogonek -40 +KPX Rcaron Uring -40 +KPX Rcaron V -18 +KPX Rcaron W -18 +KPX Rcaron Y -18 +KPX Rcaron Yacute -18 +KPX Rcaron Ydieresis -18 +KPX Rcommaaccent O -40 +KPX Rcommaaccent Oacute -40 +KPX Rcommaaccent Ocircumflex -40 +KPX Rcommaaccent Odieresis -40 +KPX Rcommaaccent Ograve -40 +KPX Rcommaaccent Ohungarumlaut -40 +KPX Rcommaaccent Omacron -40 +KPX Rcommaaccent Oslash -40 +KPX Rcommaaccent Otilde -40 +KPX Rcommaaccent T -30 +KPX Rcommaaccent Tcaron -30 +KPX Rcommaaccent Tcommaaccent -30 +KPX Rcommaaccent U -40 +KPX Rcommaaccent Uacute -40 +KPX Rcommaaccent Ucircumflex -40 +KPX Rcommaaccent Udieresis -40 +KPX Rcommaaccent Ugrave -40 +KPX Rcommaaccent Uhungarumlaut -40 +KPX Rcommaaccent Umacron -40 +KPX Rcommaaccent Uogonek -40 +KPX Rcommaaccent Uring -40 +KPX Rcommaaccent V -18 +KPX Rcommaaccent W -18 +KPX Rcommaaccent Y -18 +KPX Rcommaaccent Yacute -18 +KPX Rcommaaccent Ydieresis -18 +KPX T A -55 +KPX T Aacute -55 +KPX T Abreve -55 +KPX T Acircumflex -55 +KPX T Adieresis -55 +KPX T Agrave -55 +KPX T Amacron -55 +KPX T Aogonek -55 +KPX T Aring -55 +KPX T Atilde -55 +KPX T O -18 +KPX T Oacute -18 +KPX T Ocircumflex -18 +KPX T Odieresis -18 +KPX T Ograve -18 +KPX T Ohungarumlaut -18 +KPX T Omacron -18 +KPX T Oslash -18 +KPX T Otilde -18 +KPX T a -92 +KPX T aacute -92 +KPX T abreve -92 +KPX T acircumflex -92 +KPX T adieresis -92 +KPX T agrave -92 +KPX T amacron -92 +KPX T aogonek -92 +KPX T aring -92 +KPX T atilde -92 +KPX T colon -74 +KPX T comma -92 +KPX T e -92 +KPX T eacute -92 +KPX T ecaron -92 +KPX T ecircumflex -92 +KPX T edieresis -52 +KPX T edotaccent -92 +KPX T egrave -52 +KPX T emacron -52 +KPX T eogonek -92 +KPX T hyphen -92 +KPX T i -37 +KPX T iacute -37 +KPX T iogonek -37 +KPX T o -95 +KPX T oacute -95 +KPX T ocircumflex -95 +KPX T odieresis -95 +KPX T ograve -95 +KPX T ohungarumlaut -95 +KPX T omacron -95 +KPX T oslash -95 +KPX T otilde -95 +KPX T period -92 +KPX T r -37 +KPX T racute -37 +KPX T rcaron -37 +KPX T rcommaaccent -37 +KPX T semicolon -74 +KPX T u -37 +KPX T uacute -37 +KPX T ucircumflex -37 +KPX T udieresis -37 +KPX T ugrave -37 +KPX T uhungarumlaut -37 +KPX T umacron -37 +KPX T uogonek -37 +KPX T uring -37 +KPX T w -37 +KPX T y -37 +KPX T yacute -37 +KPX T ydieresis -37 +KPX Tcaron A -55 +KPX Tcaron Aacute -55 +KPX Tcaron Abreve -55 +KPX Tcaron Acircumflex -55 +KPX Tcaron Adieresis -55 +KPX Tcaron Agrave -55 +KPX Tcaron Amacron -55 +KPX Tcaron Aogonek -55 +KPX Tcaron Aring -55 +KPX Tcaron Atilde -55 +KPX Tcaron O -18 +KPX Tcaron Oacute -18 +KPX Tcaron Ocircumflex -18 +KPX Tcaron Odieresis -18 +KPX Tcaron Ograve -18 +KPX Tcaron Ohungarumlaut -18 +KPX Tcaron Omacron -18 +KPX Tcaron Oslash -18 +KPX Tcaron Otilde -18 +KPX Tcaron a -92 +KPX Tcaron aacute -92 +KPX Tcaron abreve -92 +KPX Tcaron acircumflex -92 +KPX Tcaron adieresis -92 +KPX Tcaron agrave -92 +KPX Tcaron amacron -92 +KPX Tcaron aogonek -92 +KPX Tcaron aring -92 +KPX Tcaron atilde -92 +KPX Tcaron colon -74 +KPX Tcaron comma -92 +KPX Tcaron e -92 +KPX Tcaron eacute -92 +KPX Tcaron ecaron -92 +KPX Tcaron ecircumflex -92 +KPX Tcaron edieresis -52 +KPX Tcaron edotaccent -92 +KPX Tcaron egrave -52 +KPX Tcaron emacron -52 +KPX Tcaron eogonek -92 +KPX Tcaron hyphen -92 +KPX Tcaron i -37 +KPX Tcaron iacute -37 +KPX Tcaron iogonek -37 +KPX Tcaron o -95 +KPX Tcaron oacute -95 +KPX Tcaron ocircumflex -95 +KPX Tcaron odieresis -95 +KPX Tcaron ograve -95 +KPX Tcaron ohungarumlaut -95 +KPX Tcaron omacron -95 +KPX Tcaron oslash -95 +KPX Tcaron otilde -95 +KPX Tcaron period -92 +KPX Tcaron r -37 +KPX Tcaron racute -37 +KPX Tcaron rcaron -37 +KPX Tcaron rcommaaccent -37 +KPX Tcaron semicolon -74 +KPX Tcaron u -37 +KPX Tcaron uacute -37 +KPX Tcaron ucircumflex -37 +KPX Tcaron udieresis -37 +KPX Tcaron ugrave -37 +KPX Tcaron uhungarumlaut -37 +KPX Tcaron umacron -37 +KPX Tcaron uogonek -37 +KPX Tcaron uring -37 +KPX Tcaron w -37 +KPX Tcaron y -37 +KPX Tcaron yacute -37 +KPX Tcaron ydieresis -37 +KPX Tcommaaccent A -55 +KPX Tcommaaccent Aacute -55 +KPX Tcommaaccent Abreve -55 +KPX Tcommaaccent Acircumflex -55 +KPX Tcommaaccent Adieresis -55 +KPX Tcommaaccent Agrave -55 +KPX Tcommaaccent Amacron -55 +KPX Tcommaaccent Aogonek -55 +KPX Tcommaaccent Aring -55 +KPX Tcommaaccent Atilde -55 +KPX Tcommaaccent O -18 +KPX Tcommaaccent Oacute -18 +KPX Tcommaaccent Ocircumflex -18 +KPX Tcommaaccent Odieresis -18 +KPX Tcommaaccent Ograve -18 +KPX Tcommaaccent Ohungarumlaut -18 +KPX Tcommaaccent Omacron -18 +KPX Tcommaaccent Oslash -18 +KPX Tcommaaccent Otilde -18 +KPX Tcommaaccent a -92 +KPX Tcommaaccent aacute -92 +KPX Tcommaaccent abreve -92 +KPX Tcommaaccent acircumflex -92 +KPX Tcommaaccent adieresis -92 +KPX Tcommaaccent agrave -92 +KPX Tcommaaccent amacron -92 +KPX Tcommaaccent aogonek -92 +KPX Tcommaaccent aring -92 +KPX Tcommaaccent atilde -92 +KPX Tcommaaccent colon -74 +KPX Tcommaaccent comma -92 +KPX Tcommaaccent e -92 +KPX Tcommaaccent eacute -92 +KPX Tcommaaccent ecaron -92 +KPX Tcommaaccent ecircumflex -92 +KPX Tcommaaccent edieresis -52 +KPX Tcommaaccent edotaccent -92 +KPX Tcommaaccent egrave -52 +KPX Tcommaaccent emacron -52 +KPX Tcommaaccent eogonek -92 +KPX Tcommaaccent hyphen -92 +KPX Tcommaaccent i -37 +KPX Tcommaaccent iacute -37 +KPX Tcommaaccent iogonek -37 +KPX Tcommaaccent o -95 +KPX Tcommaaccent oacute -95 +KPX Tcommaaccent ocircumflex -95 +KPX Tcommaaccent odieresis -95 +KPX Tcommaaccent ograve -95 +KPX Tcommaaccent ohungarumlaut -95 +KPX Tcommaaccent omacron -95 +KPX Tcommaaccent oslash -95 +KPX Tcommaaccent otilde -95 +KPX Tcommaaccent period -92 +KPX Tcommaaccent r -37 +KPX Tcommaaccent racute -37 +KPX Tcommaaccent rcaron -37 +KPX Tcommaaccent rcommaaccent -37 +KPX Tcommaaccent semicolon -74 +KPX Tcommaaccent u -37 +KPX Tcommaaccent uacute -37 +KPX Tcommaaccent ucircumflex -37 +KPX Tcommaaccent udieresis -37 +KPX Tcommaaccent ugrave -37 +KPX Tcommaaccent uhungarumlaut -37 +KPX Tcommaaccent umacron -37 +KPX Tcommaaccent uogonek -37 +KPX Tcommaaccent uring -37 +KPX Tcommaaccent w -37 +KPX Tcommaaccent y -37 +KPX Tcommaaccent yacute -37 +KPX Tcommaaccent ydieresis -37 +KPX U A -45 +KPX U Aacute -45 +KPX U Abreve -45 +KPX U Acircumflex -45 +KPX U Adieresis -45 +KPX U Agrave -45 +KPX U Amacron -45 +KPX U Aogonek -45 +KPX U Aring -45 +KPX U Atilde -45 +KPX Uacute A -45 +KPX Uacute Aacute -45 +KPX Uacute Abreve -45 +KPX Uacute Acircumflex -45 +KPX Uacute Adieresis -45 +KPX Uacute Agrave -45 +KPX Uacute Amacron -45 +KPX Uacute Aogonek -45 +KPX Uacute Aring -45 +KPX Uacute Atilde -45 +KPX Ucircumflex A -45 +KPX Ucircumflex Aacute -45 +KPX Ucircumflex Abreve -45 +KPX Ucircumflex Acircumflex -45 +KPX Ucircumflex Adieresis -45 +KPX Ucircumflex Agrave -45 +KPX Ucircumflex Amacron -45 +KPX Ucircumflex Aogonek -45 +KPX Ucircumflex Aring -45 +KPX Ucircumflex Atilde -45 +KPX Udieresis A -45 +KPX Udieresis Aacute -45 +KPX Udieresis Abreve -45 +KPX Udieresis Acircumflex -45 +KPX Udieresis Adieresis -45 +KPX Udieresis Agrave -45 +KPX Udieresis Amacron -45 +KPX Udieresis Aogonek -45 +KPX Udieresis Aring -45 +KPX Udieresis Atilde -45 +KPX Ugrave A -45 +KPX Ugrave Aacute -45 +KPX Ugrave Abreve -45 +KPX Ugrave Acircumflex -45 +KPX Ugrave Adieresis -45 +KPX Ugrave Agrave -45 +KPX Ugrave Amacron -45 +KPX Ugrave Aogonek -45 +KPX Ugrave Aring -45 +KPX Ugrave Atilde -45 +KPX Uhungarumlaut A -45 +KPX Uhungarumlaut Aacute -45 +KPX Uhungarumlaut Abreve -45 +KPX Uhungarumlaut Acircumflex -45 +KPX Uhungarumlaut Adieresis -45 +KPX Uhungarumlaut Agrave -45 +KPX Uhungarumlaut Amacron -45 +KPX Uhungarumlaut Aogonek -45 +KPX Uhungarumlaut Aring -45 +KPX Uhungarumlaut Atilde -45 +KPX Umacron A -45 +KPX Umacron Aacute -45 +KPX Umacron Abreve -45 +KPX Umacron Acircumflex -45 +KPX Umacron Adieresis -45 +KPX Umacron Agrave -45 +KPX Umacron Amacron -45 +KPX Umacron Aogonek -45 +KPX Umacron Aring -45 +KPX Umacron Atilde -45 +KPX Uogonek A -45 +KPX Uogonek Aacute -45 +KPX Uogonek Abreve -45 +KPX Uogonek Acircumflex -45 +KPX Uogonek Adieresis -45 +KPX Uogonek Agrave -45 +KPX Uogonek Amacron -45 +KPX Uogonek Aogonek -45 +KPX Uogonek Aring -45 +KPX Uogonek Atilde -45 +KPX Uring A -45 +KPX Uring Aacute -45 +KPX Uring Abreve -45 +KPX Uring Acircumflex -45 +KPX Uring Adieresis -45 +KPX Uring Agrave -45 +KPX Uring Amacron -45 +KPX Uring Aogonek -45 +KPX Uring Aring -45 +KPX Uring Atilde -45 +KPX V A -85 +KPX V Aacute -85 +KPX V Abreve -85 +KPX V Acircumflex -85 +KPX V Adieresis -85 +KPX V Agrave -85 +KPX V Amacron -85 +KPX V Aogonek -85 +KPX V Aring -85 +KPX V Atilde -85 +KPX V G -10 +KPX V Gbreve -10 +KPX V Gcommaaccent -10 +KPX V O -30 +KPX V Oacute -30 +KPX V Ocircumflex -30 +KPX V Odieresis -30 +KPX V Ograve -30 +KPX V Ohungarumlaut -30 +KPX V Omacron -30 +KPX V Oslash -30 +KPX V Otilde -30 +KPX V a -111 +KPX V aacute -111 +KPX V abreve -111 +KPX V acircumflex -111 +KPX V adieresis -111 +KPX V agrave -111 +KPX V amacron -111 +KPX V aogonek -111 +KPX V aring -111 +KPX V atilde -111 +KPX V colon -74 +KPX V comma -129 +KPX V e -111 +KPX V eacute -111 +KPX V ecaron -111 +KPX V ecircumflex -111 +KPX V edieresis -71 +KPX V edotaccent -111 +KPX V egrave -71 +KPX V emacron -71 +KPX V eogonek -111 +KPX V hyphen -70 +KPX V i -55 +KPX V iacute -55 +KPX V iogonek -55 +KPX V o -111 +KPX V oacute -111 +KPX V ocircumflex -111 +KPX V odieresis -111 +KPX V ograve -111 +KPX V ohungarumlaut -111 +KPX V omacron -111 +KPX V oslash -111 +KPX V otilde -111 +KPX V period -129 +KPX V semicolon -74 +KPX V u -55 +KPX V uacute -55 +KPX V ucircumflex -55 +KPX V udieresis -55 +KPX V ugrave -55 +KPX V uhungarumlaut -55 +KPX V umacron -55 +KPX V uogonek -55 +KPX V uring -55 +KPX W A -74 +KPX W Aacute -74 +KPX W Abreve -74 +KPX W Acircumflex -74 +KPX W Adieresis -74 +KPX W Agrave -74 +KPX W Amacron -74 +KPX W Aogonek -74 +KPX W Aring -74 +KPX W Atilde -74 +KPX W O -15 +KPX W Oacute -15 +KPX W Ocircumflex -15 +KPX W Odieresis -15 +KPX W Ograve -15 +KPX W Ohungarumlaut -15 +KPX W Omacron -15 +KPX W Oslash -15 +KPX W Otilde -15 +KPX W a -85 +KPX W aacute -85 +KPX W abreve -85 +KPX W acircumflex -85 +KPX W adieresis -85 +KPX W agrave -85 +KPX W amacron -85 +KPX W aogonek -85 +KPX W aring -85 +KPX W atilde -85 +KPX W colon -55 +KPX W comma -74 +KPX W e -90 +KPX W eacute -90 +KPX W ecaron -90 +KPX W ecircumflex -90 +KPX W edieresis -50 +KPX W edotaccent -90 +KPX W egrave -50 +KPX W emacron -50 +KPX W eogonek -90 +KPX W hyphen -50 +KPX W i -37 +KPX W iacute -37 +KPX W iogonek -37 +KPX W o -80 +KPX W oacute -80 +KPX W ocircumflex -80 +KPX W odieresis -80 +KPX W ograve -80 +KPX W ohungarumlaut -80 +KPX W omacron -80 +KPX W oslash -80 +KPX W otilde -80 +KPX W period -74 +KPX W semicolon -55 +KPX W u -55 +KPX W uacute -55 +KPX W ucircumflex -55 +KPX W udieresis -55 +KPX W ugrave -55 +KPX W uhungarumlaut -55 +KPX W umacron -55 +KPX W uogonek -55 +KPX W uring -55 +KPX W y -55 +KPX W yacute -55 +KPX W ydieresis -55 +KPX Y A -74 +KPX Y Aacute -74 +KPX Y Abreve -74 +KPX Y Acircumflex -74 +KPX Y Adieresis -74 +KPX Y Agrave -74 +KPX Y Amacron -74 +KPX Y Aogonek -74 +KPX Y Aring -74 +KPX Y Atilde -74 +KPX Y O -25 +KPX Y Oacute -25 +KPX Y Ocircumflex -25 +KPX Y Odieresis -25 +KPX Y Ograve -25 +KPX Y Ohungarumlaut -25 +KPX Y Omacron -25 +KPX Y Oslash -25 +KPX Y Otilde -25 +KPX Y a -92 +KPX Y aacute -92 +KPX Y abreve -92 +KPX Y acircumflex -92 +KPX Y adieresis -92 +KPX Y agrave -92 +KPX Y amacron -92 +KPX Y aogonek -92 +KPX Y aring -92 +KPX Y atilde -92 +KPX Y colon -92 +KPX Y comma -92 +KPX Y e -111 +KPX Y eacute -111 +KPX Y ecaron -111 +KPX Y ecircumflex -71 +KPX Y edieresis -71 +KPX Y edotaccent -111 +KPX Y egrave -71 +KPX Y emacron -71 +KPX Y eogonek -111 +KPX Y hyphen -92 +KPX Y i -55 +KPX Y iacute -55 +KPX Y iogonek -55 +KPX Y o -111 +KPX Y oacute -111 +KPX Y ocircumflex -111 +KPX Y odieresis -111 +KPX Y ograve -111 +KPX Y ohungarumlaut -111 +KPX Y omacron -111 +KPX Y oslash -111 +KPX Y otilde -111 +KPX Y period -74 +KPX Y semicolon -92 +KPX Y u -92 +KPX Y uacute -92 +KPX Y ucircumflex -92 +KPX Y udieresis -92 +KPX Y ugrave -92 +KPX Y uhungarumlaut -92 +KPX Y umacron -92 +KPX Y uogonek -92 +KPX Y uring -92 +KPX Yacute A -74 +KPX Yacute Aacute -74 +KPX Yacute Abreve -74 +KPX Yacute Acircumflex -74 +KPX Yacute Adieresis -74 +KPX Yacute Agrave -74 +KPX Yacute Amacron -74 +KPX Yacute Aogonek -74 +KPX Yacute Aring -74 +KPX Yacute Atilde -74 +KPX Yacute O -25 +KPX Yacute Oacute -25 +KPX Yacute Ocircumflex -25 +KPX Yacute Odieresis -25 +KPX Yacute Ograve -25 +KPX Yacute Ohungarumlaut -25 +KPX Yacute Omacron -25 +KPX Yacute Oslash -25 +KPX Yacute Otilde -25 +KPX Yacute a -92 +KPX Yacute aacute -92 +KPX Yacute abreve -92 +KPX Yacute acircumflex -92 +KPX Yacute adieresis -92 +KPX Yacute agrave -92 +KPX Yacute amacron -92 +KPX Yacute aogonek -92 +KPX Yacute aring -92 +KPX Yacute atilde -92 +KPX Yacute colon -92 +KPX Yacute comma -92 +KPX Yacute e -111 +KPX Yacute eacute -111 +KPX Yacute ecaron -111 +KPX Yacute ecircumflex -71 +KPX Yacute edieresis -71 +KPX Yacute edotaccent -111 +KPX Yacute egrave -71 +KPX Yacute emacron -71 +KPX Yacute eogonek -111 +KPX Yacute hyphen -92 +KPX Yacute i -55 +KPX Yacute iacute -55 +KPX Yacute iogonek -55 +KPX Yacute o -111 +KPX Yacute oacute -111 +KPX Yacute ocircumflex -111 +KPX Yacute odieresis -111 +KPX Yacute ograve -111 +KPX Yacute ohungarumlaut -111 +KPX Yacute omacron -111 +KPX Yacute oslash -111 +KPX Yacute otilde -111 +KPX Yacute period -74 +KPX Yacute semicolon -92 +KPX Yacute u -92 +KPX Yacute uacute -92 +KPX Yacute ucircumflex -92 +KPX Yacute udieresis -92 +KPX Yacute ugrave -92 +KPX Yacute uhungarumlaut -92 +KPX Yacute umacron -92 +KPX Yacute uogonek -92 +KPX Yacute uring -92 +KPX Ydieresis A -74 +KPX Ydieresis Aacute -74 +KPX Ydieresis Abreve -74 +KPX Ydieresis Acircumflex -74 +KPX Ydieresis Adieresis -74 +KPX Ydieresis Agrave -74 +KPX Ydieresis Amacron -74 +KPX Ydieresis Aogonek -74 +KPX Ydieresis Aring -74 +KPX Ydieresis Atilde -74 +KPX Ydieresis O -25 +KPX Ydieresis Oacute -25 +KPX Ydieresis Ocircumflex -25 +KPX Ydieresis Odieresis -25 +KPX Ydieresis Ograve -25 +KPX Ydieresis Ohungarumlaut -25 +KPX Ydieresis Omacron -25 +KPX Ydieresis Oslash -25 +KPX Ydieresis Otilde -25 +KPX Ydieresis a -92 +KPX Ydieresis aacute -92 +KPX Ydieresis abreve -92 +KPX Ydieresis acircumflex -92 +KPX Ydieresis adieresis -92 +KPX Ydieresis agrave -92 +KPX Ydieresis amacron -92 +KPX Ydieresis aogonek -92 +KPX Ydieresis aring -92 +KPX Ydieresis atilde -92 +KPX Ydieresis colon -92 +KPX Ydieresis comma -92 +KPX Ydieresis e -111 +KPX Ydieresis eacute -111 +KPX Ydieresis ecaron -111 +KPX Ydieresis ecircumflex -71 +KPX Ydieresis edieresis -71 +KPX Ydieresis edotaccent -111 +KPX Ydieresis egrave -71 +KPX Ydieresis emacron -71 +KPX Ydieresis eogonek -111 +KPX Ydieresis hyphen -92 +KPX Ydieresis i -55 +KPX Ydieresis iacute -55 +KPX Ydieresis iogonek -55 +KPX Ydieresis o -111 +KPX Ydieresis oacute -111 +KPX Ydieresis ocircumflex -111 +KPX Ydieresis odieresis -111 +KPX Ydieresis ograve -111 +KPX Ydieresis ohungarumlaut -111 +KPX Ydieresis omacron -111 +KPX Ydieresis oslash -111 +KPX Ydieresis otilde -111 +KPX Ydieresis period -74 +KPX Ydieresis semicolon -92 +KPX Ydieresis u -92 +KPX Ydieresis uacute -92 +KPX Ydieresis ucircumflex -92 +KPX Ydieresis udieresis -92 +KPX Ydieresis ugrave -92 +KPX Ydieresis uhungarumlaut -92 +KPX Ydieresis umacron -92 +KPX Ydieresis uogonek -92 +KPX Ydieresis uring -92 +KPX b b -10 +KPX b period -40 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX c h -10 +KPX c k -10 +KPX c kcommaaccent -10 +KPX cacute h -10 +KPX cacute k -10 +KPX cacute kcommaaccent -10 +KPX ccaron h -10 +KPX ccaron k -10 +KPX ccaron kcommaaccent -10 +KPX ccedilla h -10 +KPX ccedilla k -10 +KPX ccedilla kcommaaccent -10 +KPX comma quotedblright -95 +KPX comma quoteright -95 +KPX e b -10 +KPX eacute b -10 +KPX ecaron b -10 +KPX ecircumflex b -10 +KPX edieresis b -10 +KPX edotaccent b -10 +KPX egrave b -10 +KPX emacron b -10 +KPX eogonek b -10 +KPX f comma -10 +KPX f dotlessi -30 +KPX f e -10 +KPX f eacute -10 +KPX f edotaccent -10 +KPX f eogonek -10 +KPX f f -18 +KPX f o -10 +KPX f oacute -10 +KPX f ocircumflex -10 +KPX f ograve -10 +KPX f ohungarumlaut -10 +KPX f oslash -10 +KPX f otilde -10 +KPX f period -10 +KPX f quoteright 55 +KPX k e -30 +KPX k eacute -30 +KPX k ecaron -30 +KPX k ecircumflex -30 +KPX k edieresis -30 +KPX k edotaccent -30 +KPX k egrave -30 +KPX k emacron -30 +KPX k eogonek -30 +KPX k o -10 +KPX k oacute -10 +KPX k ocircumflex -10 +KPX k odieresis -10 +KPX k ograve -10 +KPX k ohungarumlaut -10 +KPX k omacron -10 +KPX k oslash -10 +KPX k otilde -10 +KPX kcommaaccent e -30 +KPX kcommaaccent eacute -30 +KPX kcommaaccent ecaron -30 +KPX kcommaaccent ecircumflex -30 +KPX kcommaaccent edieresis -30 +KPX kcommaaccent edotaccent -30 +KPX kcommaaccent egrave -30 +KPX kcommaaccent emacron -30 +KPX kcommaaccent eogonek -30 +KPX kcommaaccent o -10 +KPX kcommaaccent oacute -10 +KPX kcommaaccent ocircumflex -10 +KPX kcommaaccent odieresis -10 +KPX kcommaaccent ograve -10 +KPX kcommaaccent ohungarumlaut -10 +KPX kcommaaccent omacron -10 +KPX kcommaaccent oslash -10 +KPX kcommaaccent otilde -10 +KPX n v -40 +KPX nacute v -40 +KPX ncaron v -40 +KPX ncommaaccent v -40 +KPX ntilde v -40 +KPX o v -15 +KPX o w -25 +KPX o x -10 +KPX o y -10 +KPX o yacute -10 +KPX o ydieresis -10 +KPX oacute v -15 +KPX oacute w -25 +KPX oacute x -10 +KPX oacute y -10 +KPX oacute yacute -10 +KPX oacute ydieresis -10 +KPX ocircumflex v -15 +KPX ocircumflex w -25 +KPX ocircumflex x -10 +KPX ocircumflex y -10 +KPX ocircumflex yacute -10 +KPX ocircumflex ydieresis -10 +KPX odieresis v -15 +KPX odieresis w -25 +KPX odieresis x -10 +KPX odieresis y -10 +KPX odieresis yacute -10 +KPX odieresis ydieresis -10 +KPX ograve v -15 +KPX ograve w -25 +KPX ograve x -10 +KPX ograve y -10 +KPX ograve yacute -10 +KPX ograve ydieresis -10 +KPX ohungarumlaut v -15 +KPX ohungarumlaut w -25 +KPX ohungarumlaut x -10 +KPX ohungarumlaut y -10 +KPX ohungarumlaut yacute -10 +KPX ohungarumlaut ydieresis -10 +KPX omacron v -15 +KPX omacron w -25 +KPX omacron x -10 +KPX omacron y -10 +KPX omacron yacute -10 +KPX omacron ydieresis -10 +KPX oslash v -15 +KPX oslash w -25 +KPX oslash x -10 +KPX oslash y -10 +KPX oslash yacute -10 +KPX oslash ydieresis -10 +KPX otilde v -15 +KPX otilde w -25 +KPX otilde x -10 +KPX otilde y -10 +KPX otilde yacute -10 +KPX otilde ydieresis -10 +KPX period quotedblright -95 +KPX period quoteright -95 +KPX quoteleft quoteleft -74 +KPX quoteright d -15 +KPX quoteright dcroat -15 +KPX quoteright quoteright -74 +KPX quoteright r -15 +KPX quoteright racute -15 +KPX quoteright rcaron -15 +KPX quoteright rcommaaccent -15 +KPX quoteright s -74 +KPX quoteright sacute -74 +KPX quoteright scaron -74 +KPX quoteright scedilla -74 +KPX quoteright scommaaccent -74 +KPX quoteright space -74 +KPX quoteright t -37 +KPX quoteright tcommaaccent -37 +KPX quoteright v -15 +KPX r comma -65 +KPX r period -65 +KPX racute comma -65 +KPX racute period -65 +KPX rcaron comma -65 +KPX rcaron period -65 +KPX rcommaaccent comma -65 +KPX rcommaaccent period -65 +KPX space A -37 +KPX space Aacute -37 +KPX space Abreve -37 +KPX space Acircumflex -37 +KPX space Adieresis -37 +KPX space Agrave -37 +KPX space Amacron -37 +KPX space Aogonek -37 +KPX space Aring -37 +KPX space Atilde -37 +KPX space V -70 +KPX space W -70 +KPX space Y -70 +KPX space Yacute -70 +KPX space Ydieresis -70 +KPX v comma -37 +KPX v e -15 +KPX v eacute -15 +KPX v ecaron -15 +KPX v ecircumflex -15 +KPX v edieresis -15 +KPX v edotaccent -15 +KPX v egrave -15 +KPX v emacron -15 +KPX v eogonek -15 +KPX v o -15 +KPX v oacute -15 +KPX v ocircumflex -15 +KPX v odieresis -15 +KPX v ograve -15 +KPX v ohungarumlaut -15 +KPX v omacron -15 +KPX v oslash -15 +KPX v otilde -15 +KPX v period -37 +KPX w a -10 +KPX w aacute -10 +KPX w abreve -10 +KPX w acircumflex -10 +KPX w adieresis -10 +KPX w agrave -10 +KPX w amacron -10 +KPX w aogonek -10 +KPX w aring -10 +KPX w atilde -10 +KPX w comma -37 +KPX w e -10 +KPX w eacute -10 +KPX w ecaron -10 +KPX w ecircumflex -10 +KPX w edieresis -10 +KPX w edotaccent -10 +KPX w egrave -10 +KPX w emacron -10 +KPX w eogonek -10 +KPX w o -15 +KPX w oacute -15 +KPX w ocircumflex -15 +KPX w odieresis -15 +KPX w ograve -15 +KPX w ohungarumlaut -15 +KPX w omacron -15 +KPX w oslash -15 +KPX w otilde -15 +KPX w period -37 +KPX x e -10 +KPX x eacute -10 +KPX x ecaron -10 +KPX x ecircumflex -10 +KPX x edieresis -10 +KPX x edotaccent -10 +KPX x egrave -10 +KPX x emacron -10 +KPX x eogonek -10 +KPX y comma -37 +KPX y period -37 +KPX yacute comma -37 +KPX yacute period -37 +KPX ydieresis comma -37 +KPX ydieresis period -37 +EndKernPairs +EndKernData +EndFontMetrics addfile ./Core14_AFMs/Times-Italic.afm hunk ./Core14_AFMs/Times-Italic.afm 1 +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 12:56:55 1997 +Comment UniqueID 43067 +Comment VMusage 47727 58752 +FontName Times-Italic +FullName Times Italic +FamilyName Times +Weight Medium +ItalicAngle -15.5 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -169 -217 1010 883 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 653 +XHeight 441 +Ascender 683 +Descender -217 +StdHW 32 +StdVW 76 +StartCharMetrics 315 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 39 -11 302 667 ; +C 34 ; WX 420 ; N quotedbl ; B 144 421 432 666 ; +C 35 ; WX 500 ; N numbersign ; B 2 0 540 676 ; +C 36 ; WX 500 ; N dollar ; B 31 -89 497 731 ; +C 37 ; WX 833 ; N percent ; B 79 -13 790 676 ; +C 38 ; WX 778 ; N ampersand ; B 76 -18 723 666 ; +C 39 ; WX 333 ; N quoteright ; B 151 436 290 666 ; +C 40 ; WX 333 ; N parenleft ; B 42 -181 315 669 ; +C 41 ; WX 333 ; N parenright ; B 16 -180 289 669 ; +C 42 ; WX 500 ; N asterisk ; B 128 255 492 666 ; +C 43 ; WX 675 ; N plus ; B 86 0 590 506 ; +C 44 ; WX 250 ; N comma ; B -4 -129 135 101 ; +C 45 ; WX 333 ; N hyphen ; B 49 192 282 255 ; +C 46 ; WX 250 ; N period ; B 27 -11 138 100 ; +C 47 ; WX 278 ; N slash ; B -65 -18 386 666 ; +C 48 ; WX 500 ; N zero ; B 32 -7 497 676 ; +C 49 ; WX 500 ; N one ; B 49 0 409 676 ; +C 50 ; WX 500 ; N two ; B 12 0 452 676 ; +C 51 ; WX 500 ; N three ; B 15 -7 465 676 ; +C 52 ; WX 500 ; N four ; B 1 0 479 676 ; +C 53 ; WX 500 ; N five ; B 15 -7 491 666 ; +C 54 ; WX 500 ; N six ; B 30 -7 521 686 ; +C 55 ; WX 500 ; N seven ; B 75 -8 537 666 ; +C 56 ; WX 500 ; N eight ; B 30 -7 493 676 ; +C 57 ; WX 500 ; N nine ; B 23 -17 492 676 ; +C 58 ; WX 333 ; N colon ; B 50 -11 261 441 ; +C 59 ; WX 333 ; N semicolon ; B 27 -129 261 441 ; +C 60 ; WX 675 ; N less ; B 84 -8 592 514 ; +C 61 ; WX 675 ; N equal ; B 86 120 590 386 ; +C 62 ; WX 675 ; N greater ; B 84 -8 592 514 ; +C 63 ; WX 500 ; N question ; B 132 -12 472 664 ; +C 64 ; WX 920 ; N at ; B 118 -18 806 666 ; +C 65 ; WX 611 ; N A ; B -51 0 564 668 ; +C 66 ; WX 611 ; N B ; B -8 0 588 653 ; +C 67 ; WX 667 ; N C ; B 66 -18 689 666 ; +C 68 ; WX 722 ; N D ; B -8 0 700 653 ; +C 69 ; WX 611 ; N E ; B -1 0 634 653 ; +C 70 ; WX 611 ; N F ; B 8 0 645 653 ; +C 71 ; WX 722 ; N G ; B 52 -18 722 666 ; +C 72 ; WX 722 ; N H ; B -8 0 767 653 ; +C 73 ; WX 333 ; N I ; B -8 0 384 653 ; +C 74 ; WX 444 ; N J ; B -6 -18 491 653 ; +C 75 ; WX 667 ; N K ; B 7 0 722 653 ; +C 76 ; WX 556 ; N L ; B -8 0 559 653 ; +C 77 ; WX 833 ; N M ; B -18 0 873 653 ; +C 78 ; WX 667 ; N N ; B -20 -15 727 653 ; +C 79 ; WX 722 ; N O ; B 60 -18 699 666 ; +C 80 ; WX 611 ; N P ; B 0 0 605 653 ; +C 81 ; WX 722 ; N Q ; B 59 -182 699 666 ; +C 82 ; WX 611 ; N R ; B -13 0 588 653 ; +C 83 ; WX 500 ; N S ; B 17 -18 508 667 ; +C 84 ; WX 556 ; N T ; B 59 0 633 653 ; +C 85 ; WX 722 ; N U ; B 102 -18 765 653 ; +C 86 ; WX 611 ; N V ; B 76 -18 688 653 ; +C 87 ; WX 833 ; N W ; B 71 -18 906 653 ; +C 88 ; WX 611 ; N X ; B -29 0 655 653 ; +C 89 ; WX 556 ; N Y ; B 78 0 633 653 ; +C 90 ; WX 556 ; N Z ; B -6 0 606 653 ; +C 91 ; WX 389 ; N bracketleft ; B 21 -153 391 663 ; +C 92 ; WX 278 ; N backslash ; B -41 -18 319 666 ; +C 93 ; WX 389 ; N bracketright ; B 12 -153 382 663 ; +C 94 ; WX 422 ; N asciicircum ; B 0 301 422 666 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 333 ; N quoteleft ; B 171 436 310 666 ; +C 97 ; WX 500 ; N a ; B 17 -11 476 441 ; +C 98 ; WX 500 ; N b ; B 23 -11 473 683 ; +C 99 ; WX 444 ; N c ; B 30 -11 425 441 ; +C 100 ; WX 500 ; N d ; B 15 -13 527 683 ; +C 101 ; WX 444 ; N e ; B 31 -11 412 441 ; +C 102 ; WX 278 ; N f ; B -147 -207 424 678 ; L i fi ; L l fl ; +C 103 ; WX 500 ; N g ; B 8 -206 472 441 ; +C 104 ; WX 500 ; N h ; B 19 -9 478 683 ; +C 105 ; WX 278 ; N i ; B 49 -11 264 654 ; +C 106 ; WX 278 ; N j ; B -124 -207 276 654 ; +C 107 ; WX 444 ; N k ; B 14 -11 461 683 ; +C 108 ; WX 278 ; N l ; B 41 -11 279 683 ; +C 109 ; WX 722 ; N m ; B 12 -9 704 441 ; +C 110 ; WX 500 ; N n ; B 14 -9 474 441 ; +C 111 ; WX 500 ; N o ; B 27 -11 468 441 ; +C 112 ; WX 500 ; N p ; B -75 -205 469 441 ; +C 113 ; WX 500 ; N q ; B 25 -209 483 441 ; +C 114 ; WX 389 ; N r ; B 45 0 412 441 ; +C 115 ; WX 389 ; N s ; B 16 -13 366 442 ; +C 116 ; WX 278 ; N t ; B 37 -11 296 546 ; +C 117 ; WX 500 ; N u ; B 42 -11 475 441 ; +C 118 ; WX 444 ; N v ; B 21 -18 426 441 ; +C 119 ; WX 667 ; N w ; B 16 -18 648 441 ; +C 120 ; WX 444 ; N x ; B -27 -11 447 441 ; +C 121 ; WX 444 ; N y ; B -24 -206 426 441 ; +C 122 ; WX 389 ; N z ; B -2 -81 380 428 ; +C 123 ; WX 400 ; N braceleft ; B 51 -177 407 687 ; +C 124 ; WX 275 ; N bar ; B 105 -217 171 783 ; +C 125 ; WX 400 ; N braceright ; B -7 -177 349 687 ; +C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ; +C 161 ; WX 389 ; N exclamdown ; B 59 -205 322 473 ; +C 162 ; WX 500 ; N cent ; B 77 -143 472 560 ; +C 163 ; WX 500 ; N sterling ; B 10 -6 517 670 ; +C 164 ; WX 167 ; N fraction ; B -169 -10 337 676 ; +C 165 ; WX 500 ; N yen ; B 27 0 603 653 ; +C 166 ; WX 500 ; N florin ; B 25 -182 507 682 ; +C 167 ; WX 500 ; N section ; B 53 -162 461 666 ; +C 168 ; WX 500 ; N currency ; B -22 53 522 597 ; +C 169 ; WX 214 ; N quotesingle ; B 132 421 241 666 ; +C 170 ; WX 556 ; N quotedblleft ; B 166 436 514 666 ; +C 171 ; WX 500 ; N guillemotleft ; B 53 37 445 403 ; +C 172 ; WX 333 ; N guilsinglleft ; B 51 37 281 403 ; +C 173 ; WX 333 ; N guilsinglright ; B 52 37 282 403 ; +C 174 ; WX 500 ; N fi ; B -141 -207 481 681 ; +C 175 ; WX 500 ; N fl ; B -141 -204 518 682 ; +C 177 ; WX 500 ; N endash ; B -6 197 505 243 ; +C 178 ; WX 500 ; N dagger ; B 101 -159 488 666 ; +C 179 ; WX 500 ; N daggerdbl ; B 22 -143 491 666 ; +C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ; +C 182 ; WX 523 ; N paragraph ; B 55 -123 616 653 ; +C 183 ; WX 350 ; N bullet ; B 40 191 310 461 ; +C 184 ; WX 333 ; N quotesinglbase ; B 44 -129 183 101 ; +C 185 ; WX 556 ; N quotedblbase ; B 57 -129 405 101 ; +C 186 ; WX 556 ; N quotedblright ; B 151 436 499 666 ; +C 187 ; WX 500 ; N guillemotright ; B 55 37 447 403 ; +C 188 ; WX 889 ; N ellipsis ; B 57 -11 762 100 ; +C 189 ; WX 1000 ; N perthousand ; B 25 -19 1010 706 ; +C 191 ; WX 500 ; N questiondown ; B 28 -205 368 471 ; +C 193 ; WX 333 ; N grave ; B 121 492 311 664 ; +C 194 ; WX 333 ; N acute ; B 180 494 403 664 ; +C 195 ; WX 333 ; N circumflex ; B 91 492 385 661 ; +C 196 ; WX 333 ; N tilde ; B 100 517 427 624 ; +C 197 ; WX 333 ; N macron ; B 99 532 411 583 ; +C 198 ; WX 333 ; N breve ; B 117 492 418 650 ; +C 199 ; WX 333 ; N dotaccent ; B 207 548 305 646 ; +C 200 ; WX 333 ; N dieresis ; B 107 548 405 646 ; +C 202 ; WX 333 ; N ring ; B 155 492 355 691 ; +C 203 ; WX 333 ; N cedilla ; B -30 -217 182 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B 93 494 486 664 ; +C 206 ; WX 333 ; N ogonek ; B 20 -169 203 40 ; +C 207 ; WX 333 ; N caron ; B 121 492 426 661 ; +C 208 ; WX 889 ; N emdash ; B -6 197 894 243 ; +C 225 ; WX 889 ; N AE ; B -27 0 911 653 ; +C 227 ; WX 276 ; N ordfeminine ; B 42 406 352 676 ; +C 232 ; WX 556 ; N Lslash ; B -8 0 559 653 ; +C 233 ; WX 722 ; N Oslash ; B 60 -105 699 722 ; +C 234 ; WX 944 ; N OE ; B 49 -8 964 666 ; +C 235 ; WX 310 ; N ordmasculine ; B 67 406 362 676 ; +C 241 ; WX 667 ; N ae ; B 23 -11 640 441 ; +C 245 ; WX 278 ; N dotlessi ; B 49 -11 235 441 ; +C 248 ; WX 278 ; N lslash ; B 41 -11 312 683 ; +C 249 ; WX 500 ; N oslash ; B 28 -135 469 554 ; +C 250 ; WX 667 ; N oe ; B 20 -12 646 441 ; +C 251 ; WX 500 ; N germandbls ; B -168 -207 493 679 ; +C -1 ; WX 333 ; N Idieresis ; B -8 0 435 818 ; +C -1 ; WX 444 ; N eacute ; B 31 -11 459 664 ; +C -1 ; WX 500 ; N abreve ; B 17 -11 502 650 ; +C -1 ; WX 500 ; N uhungarumlaut ; B 42 -11 580 664 ; +C -1 ; WX 444 ; N ecaron ; B 31 -11 482 661 ; +C -1 ; WX 556 ; N Ydieresis ; B 78 0 633 818 ; +C -1 ; WX 675 ; N divide ; B 86 -11 590 517 ; +C -1 ; WX 556 ; N Yacute ; B 78 0 633 876 ; +C -1 ; WX 611 ; N Acircumflex ; B -51 0 564 873 ; +C -1 ; WX 500 ; N aacute ; B 17 -11 487 664 ; +C -1 ; WX 722 ; N Ucircumflex ; B 102 -18 765 873 ; +C -1 ; WX 444 ; N yacute ; B -24 -206 459 664 ; +C -1 ; WX 389 ; N scommaaccent ; B 16 -217 366 442 ; +C -1 ; WX 444 ; N ecircumflex ; B 31 -11 441 661 ; +C -1 ; WX 722 ; N Uring ; B 102 -18 765 883 ; +C -1 ; WX 722 ; N Udieresis ; B 102 -18 765 818 ; +C -1 ; WX 500 ; N aogonek ; B 17 -169 476 441 ; +C -1 ; WX 722 ; N Uacute ; B 102 -18 765 876 ; +C -1 ; WX 500 ; N uogonek ; B 42 -169 477 441 ; +C -1 ; WX 611 ; N Edieresis ; B -1 0 634 818 ; +C -1 ; WX 722 ; N Dcroat ; B -8 0 700 653 ; +C -1 ; WX 250 ; N commaaccent ; B 8 -217 133 -50 ; +C -1 ; WX 760 ; N copyright ; B 41 -18 719 666 ; +C -1 ; WX 611 ; N Emacron ; B -1 0 634 795 ; +C -1 ; WX 444 ; N ccaron ; B 30 -11 482 661 ; +C -1 ; WX 500 ; N aring ; B 17 -11 476 691 ; +C -1 ; WX 667 ; N Ncommaaccent ; B -20 -187 727 653 ; +C -1 ; WX 278 ; N lacute ; B 41 -11 395 876 ; +C -1 ; WX 500 ; N agrave ; B 17 -11 476 664 ; +C -1 ; WX 556 ; N Tcommaaccent ; B 59 -217 633 653 ; +C -1 ; WX 667 ; N Cacute ; B 66 -18 690 876 ; +C -1 ; WX 500 ; N atilde ; B 17 -11 511 624 ; +C -1 ; WX 611 ; N Edotaccent ; B -1 0 634 818 ; +C -1 ; WX 389 ; N scaron ; B 16 -13 454 661 ; +C -1 ; WX 389 ; N scedilla ; B 16 -217 366 442 ; +C -1 ; WX 278 ; N iacute ; B 49 -11 355 664 ; +C -1 ; WX 471 ; N lozenge ; B 13 0 459 724 ; +C -1 ; WX 611 ; N Rcaron ; B -13 0 588 873 ; +C -1 ; WX 722 ; N Gcommaaccent ; B 52 -217 722 666 ; +C -1 ; WX 500 ; N ucircumflex ; B 42 -11 475 661 ; +C -1 ; WX 500 ; N acircumflex ; B 17 -11 476 661 ; +C -1 ; WX 611 ; N Amacron ; B -51 0 564 795 ; +C -1 ; WX 389 ; N rcaron ; B 45 0 434 661 ; +C -1 ; WX 444 ; N ccedilla ; B 30 -217 425 441 ; +C -1 ; WX 556 ; N Zdotaccent ; B -6 0 606 818 ; +C -1 ; WX 611 ; N Thorn ; B 0 0 569 653 ; +C -1 ; WX 722 ; N Omacron ; B 60 -18 699 795 ; +C -1 ; WX 611 ; N Racute ; B -13 0 588 876 ; +C -1 ; WX 500 ; N Sacute ; B 17 -18 508 876 ; +C -1 ; WX 544 ; N dcaron ; B 15 -13 658 683 ; +C -1 ; WX 722 ; N Umacron ; B 102 -18 765 795 ; +C -1 ; WX 500 ; N uring ; B 42 -11 475 691 ; +C -1 ; WX 300 ; N threesuperior ; B 43 268 339 676 ; +C -1 ; WX 722 ; N Ograve ; B 60 -18 699 876 ; +C -1 ; WX 611 ; N Agrave ; B -51 0 564 876 ; +C -1 ; WX 611 ; N Abreve ; B -51 0 564 862 ; +C -1 ; WX 675 ; N multiply ; B 93 8 582 497 ; +C -1 ; WX 500 ; N uacute ; B 42 -11 477 664 ; +C -1 ; WX 556 ; N Tcaron ; B 59 0 633 873 ; +C -1 ; WX 476 ; N partialdiff ; B 17 -38 459 710 ; +C -1 ; WX 444 ; N ydieresis ; B -24 -206 441 606 ; +C -1 ; WX 667 ; N Nacute ; B -20 -15 727 876 ; +C -1 ; WX 278 ; N icircumflex ; B 33 -11 327 661 ; +C -1 ; WX 611 ; N Ecircumflex ; B -1 0 634 873 ; +C -1 ; WX 500 ; N adieresis ; B 17 -11 489 606 ; +C -1 ; WX 444 ; N edieresis ; B 31 -11 451 606 ; +C -1 ; WX 444 ; N cacute ; B 30 -11 459 664 ; +C -1 ; WX 500 ; N nacute ; B 14 -9 477 664 ; +C -1 ; WX 500 ; N umacron ; B 42 -11 485 583 ; +C -1 ; WX 667 ; N Ncaron ; B -20 -15 727 873 ; +C -1 ; WX 333 ; N Iacute ; B -8 0 433 876 ; +C -1 ; WX 675 ; N plusminus ; B 86 0 590 506 ; +C -1 ; WX 275 ; N brokenbar ; B 105 -142 171 708 ; +C -1 ; WX 760 ; N registered ; B 41 -18 719 666 ; +C -1 ; WX 722 ; N Gbreve ; B 52 -18 722 862 ; +C -1 ; WX 333 ; N Idotaccent ; B -8 0 384 818 ; +C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ; +C -1 ; WX 611 ; N Egrave ; B -1 0 634 876 ; +C -1 ; WX 389 ; N racute ; B 45 0 431 664 ; +C -1 ; WX 500 ; N omacron ; B 27 -11 495 583 ; +C -1 ; WX 556 ; N Zacute ; B -6 0 606 876 ; +C -1 ; WX 556 ; N Zcaron ; B -6 0 606 873 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 523 658 ; +C -1 ; WX 722 ; N Eth ; B -8 0 700 653 ; +C -1 ; WX 667 ; N Ccedilla ; B 66 -217 689 666 ; +C -1 ; WX 278 ; N lcommaaccent ; B 22 -217 279 683 ; +C -1 ; WX 300 ; N tcaron ; B 37 -11 407 681 ; +C -1 ; WX 444 ; N eogonek ; B 31 -169 412 441 ; +C -1 ; WX 722 ; N Uogonek ; B 102 -184 765 653 ; +C -1 ; WX 611 ; N Aacute ; B -51 0 564 876 ; +C -1 ; WX 611 ; N Adieresis ; B -51 0 564 818 ; +C -1 ; WX 444 ; N egrave ; B 31 -11 412 664 ; +C -1 ; WX 389 ; N zacute ; B -2 -81 431 664 ; +C -1 ; WX 278 ; N iogonek ; B 49 -169 264 654 ; +C -1 ; WX 722 ; N Oacute ; B 60 -18 699 876 ; +C -1 ; WX 500 ; N oacute ; B 27 -11 487 664 ; +C -1 ; WX 500 ; N amacron ; B 17 -11 495 583 ; +C -1 ; WX 389 ; N sacute ; B 16 -13 431 664 ; +C -1 ; WX 278 ; N idieresis ; B 49 -11 352 606 ; +C -1 ; WX 722 ; N Ocircumflex ; B 60 -18 699 873 ; +C -1 ; WX 722 ; N Ugrave ; B 102 -18 765 876 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 500 ; N thorn ; B -75 -205 469 683 ; +C -1 ; WX 300 ; N twosuperior ; B 33 271 324 676 ; +C -1 ; WX 722 ; N Odieresis ; B 60 -18 699 818 ; +C -1 ; WX 500 ; N mu ; B -30 -209 497 428 ; +C -1 ; WX 278 ; N igrave ; B 49 -11 284 664 ; +C -1 ; WX 500 ; N ohungarumlaut ; B 27 -11 590 664 ; +C -1 ; WX 611 ; N Eogonek ; B -1 -169 634 653 ; +C -1 ; WX 500 ; N dcroat ; B 15 -13 572 683 ; +C -1 ; WX 750 ; N threequarters ; B 23 -10 736 676 ; +C -1 ; WX 500 ; N Scedilla ; B 17 -217 508 667 ; +C -1 ; WX 300 ; N lcaron ; B 41 -11 407 683 ; +C -1 ; WX 667 ; N Kcommaaccent ; B 7 -217 722 653 ; +C -1 ; WX 556 ; N Lacute ; B -8 0 559 876 ; +C -1 ; WX 980 ; N trademark ; B 30 247 957 653 ; +C -1 ; WX 444 ; N edotaccent ; B 31 -11 412 606 ; +C -1 ; WX 333 ; N Igrave ; B -8 0 384 876 ; +C -1 ; WX 333 ; N Imacron ; B -8 0 441 795 ; +C -1 ; WX 611 ; N Lcaron ; B -8 0 586 653 ; +C -1 ; WX 750 ; N onehalf ; B 34 -10 749 676 ; +C -1 ; WX 549 ; N lessequal ; B 26 0 523 658 ; +C -1 ; WX 500 ; N ocircumflex ; B 27 -11 468 661 ; +C -1 ; WX 500 ; N ntilde ; B 14 -9 476 624 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 102 -18 765 876 ; +C -1 ; WX 611 ; N Eacute ; B -1 0 634 876 ; +C -1 ; WX 444 ; N emacron ; B 31 -11 457 583 ; +C -1 ; WX 500 ; N gbreve ; B 8 -206 487 650 ; +C -1 ; WX 750 ; N onequarter ; B 33 -10 736 676 ; +C -1 ; WX 500 ; N Scaron ; B 17 -18 520 873 ; +C -1 ; WX 500 ; N Scommaaccent ; B 17 -217 508 667 ; +C -1 ; WX 722 ; N Ohungarumlaut ; B 60 -18 699 876 ; +C -1 ; WX 400 ; N degree ; B 101 390 387 676 ; +C -1 ; WX 500 ; N ograve ; B 27 -11 468 664 ; +C -1 ; WX 667 ; N Ccaron ; B 66 -18 689 873 ; +C -1 ; WX 500 ; N ugrave ; B 42 -11 475 664 ; +C -1 ; WX 453 ; N radical ; B 2 -60 452 768 ; +C -1 ; WX 722 ; N Dcaron ; B -8 0 700 873 ; +C -1 ; WX 389 ; N rcommaaccent ; B -3 -217 412 441 ; +C -1 ; WX 667 ; N Ntilde ; B -20 -15 727 836 ; +C -1 ; WX 500 ; N otilde ; B 27 -11 496 624 ; +C -1 ; WX 611 ; N Rcommaaccent ; B -13 -187 588 653 ; +C -1 ; WX 556 ; N Lcommaaccent ; B -8 -217 559 653 ; +C -1 ; WX 611 ; N Atilde ; B -51 0 566 836 ; +C -1 ; WX 611 ; N Aogonek ; B -51 -169 566 668 ; +C -1 ; WX 611 ; N Aring ; B -51 0 564 883 ; +C -1 ; WX 722 ; N Otilde ; B 60 -18 699 836 ; +C -1 ; WX 389 ; N zdotaccent ; B -2 -81 380 606 ; +C -1 ; WX 611 ; N Ecaron ; B -1 0 634 873 ; +C -1 ; WX 333 ; N Iogonek ; B -8 -169 384 653 ; +C -1 ; WX 444 ; N kcommaaccent ; B 14 -187 461 683 ; +C -1 ; WX 675 ; N minus ; B 86 220 590 286 ; +C -1 ; WX 333 ; N Icircumflex ; B -8 0 425 873 ; +C -1 ; WX 500 ; N ncaron ; B 14 -9 510 661 ; +C -1 ; WX 278 ; N tcommaaccent ; B 2 -217 296 546 ; +C -1 ; WX 675 ; N logicalnot ; B 86 108 590 386 ; +C -1 ; WX 500 ; N odieresis ; B 27 -11 489 606 ; +C -1 ; WX 500 ; N udieresis ; B 42 -11 479 606 ; +C -1 ; WX 549 ; N notequal ; B 12 -29 537 541 ; +C -1 ; WX 500 ; N gcommaaccent ; B 8 -206 472 706 ; +C -1 ; WX 500 ; N eth ; B 27 -11 482 683 ; +C -1 ; WX 389 ; N zcaron ; B -2 -81 434 661 ; +C -1 ; WX 500 ; N ncommaaccent ; B 14 -187 474 441 ; +C -1 ; WX 300 ; N onesuperior ; B 43 271 284 676 ; +C -1 ; WX 278 ; N imacron ; B 46 -11 311 583 ; +C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2321 +KPX A C -30 +KPX A Cacute -30 +KPX A Ccaron -30 +KPX A Ccedilla -30 +KPX A G -35 +KPX A Gbreve -35 +KPX A Gcommaaccent -35 +KPX A O -40 +KPX A Oacute -40 +KPX A Ocircumflex -40 +KPX A Odieresis -40 +KPX A Ograve -40 +KPX A Ohungarumlaut -40 +KPX A Omacron -40 +KPX A Oslash -40 +KPX A Otilde -40 +KPX A Q -40 +KPX A T -37 +KPX A Tcaron -37 +KPX A Tcommaaccent -37 +KPX A U -50 +KPX A Uacute -50 +KPX A Ucircumflex -50 +KPX A Udieresis -50 +KPX A Ugrave -50 +KPX A Uhungarumlaut -50 +KPX A Umacron -50 +KPX A Uogonek -50 +KPX A Uring -50 +KPX A V -105 +KPX A W -95 +KPX A Y -55 +KPX A Yacute -55 +KPX A Ydieresis -55 +KPX A quoteright -37 +KPX A u -20 +KPX A uacute -20 +KPX A ucircumflex -20 +KPX A udieresis -20 +KPX A ugrave -20 +KPX A uhungarumlaut -20 +KPX A umacron -20 +KPX A uogonek -20 +KPX A uring -20 +KPX A v -55 +KPX A w -55 +KPX A y -55 +KPX A yacute -55 +KPX A ydieresis -55 +KPX Aacute C -30 +KPX Aacute Cacute -30 +KPX Aacute Ccaron -30 +KPX Aacute Ccedilla -30 +KPX Aacute G -35 +KPX Aacute Gbreve -35 +KPX Aacute Gcommaaccent -35 +KPX Aacute O -40 +KPX Aacute Oacute -40 +KPX Aacute Ocircumflex -40 +KPX Aacute Odieresis -40 +KPX Aacute Ograve -40 +KPX Aacute Ohungarumlaut -40 +KPX Aacute Omacron -40 +KPX Aacute Oslash -40 +KPX Aacute Otilde -40 +KPX Aacute Q -40 +KPX Aacute T -37 +KPX Aacute Tcaron -37 +KPX Aacute Tcommaaccent -37 +KPX Aacute U -50 +KPX Aacute Uacute -50 +KPX Aacute Ucircumflex -50 +KPX Aacute Udieresis -50 +KPX Aacute Ugrave -50 +KPX Aacute Uhungarumlaut -50 +KPX Aacute Umacron -50 +KPX Aacute Uogonek -50 +KPX Aacute Uring -50 +KPX Aacute V -105 +KPX Aacute W -95 +KPX Aacute Y -55 +KPX Aacute Yacute -55 +KPX Aacute Ydieresis -55 +KPX Aacute quoteright -37 +KPX Aacute u -20 +KPX Aacute uacute -20 +KPX Aacute ucircumflex -20 +KPX Aacute udieresis -20 +KPX Aacute ugrave -20 +KPX Aacute uhungarumlaut -20 +KPX Aacute umacron -20 +KPX Aacute uogonek -20 +KPX Aacute uring -20 +KPX Aacute v -55 +KPX Aacute w -55 +KPX Aacute y -55 +KPX Aacute yacute -55 +KPX Aacute ydieresis -55 +KPX Abreve C -30 +KPX Abreve Cacute -30 +KPX Abreve Ccaron -30 +KPX Abreve Ccedilla -30 +KPX Abreve G -35 +KPX Abreve Gbreve -35 +KPX Abreve Gcommaaccent -35 +KPX Abreve O -40 +KPX Abreve Oacute -40 +KPX Abreve Ocircumflex -40 +KPX Abreve Odieresis -40 +KPX Abreve Ograve -40 +KPX Abreve Ohungarumlaut -40 +KPX Abreve Omacron -40 +KPX Abreve Oslash -40 +KPX Abreve Otilde -40 +KPX Abreve Q -40 +KPX Abreve T -37 +KPX Abreve Tcaron -37 +KPX Abreve Tcommaaccent -37 +KPX Abreve U -50 +KPX Abreve Uacute -50 +KPX Abreve Ucircumflex -50 +KPX Abreve Udieresis -50 +KPX Abreve Ugrave -50 +KPX Abreve Uhungarumlaut -50 +KPX Abreve Umacron -50 +KPX Abreve Uogonek -50 +KPX Abreve Uring -50 +KPX Abreve V -105 +KPX Abreve W -95 +KPX Abreve Y -55 +KPX Abreve Yacute -55 +KPX Abreve Ydieresis -55 +KPX Abreve quoteright -37 +KPX Abreve u -20 +KPX Abreve uacute -20 +KPX Abreve ucircumflex -20 +KPX Abreve udieresis -20 +KPX Abreve ugrave -20 +KPX Abreve uhungarumlaut -20 +KPX Abreve umacron -20 +KPX Abreve uogonek -20 +KPX Abreve uring -20 +KPX Abreve v -55 +KPX Abreve w -55 +KPX Abreve y -55 +KPX Abreve yacute -55 +KPX Abreve ydieresis -55 +KPX Acircumflex C -30 +KPX Acircumflex Cacute -30 +KPX Acircumflex Ccaron -30 +KPX Acircumflex Ccedilla -30 +KPX Acircumflex G -35 +KPX Acircumflex Gbreve -35 +KPX Acircumflex Gcommaaccent -35 +KPX Acircumflex O -40 +KPX Acircumflex Oacute -40 +KPX Acircumflex Ocircumflex -40 +KPX Acircumflex Odieresis -40 +KPX Acircumflex Ograve -40 +KPX Acircumflex Ohungarumlaut -40 +KPX Acircumflex Omacron -40 +KPX Acircumflex Oslash -40 +KPX Acircumflex Otilde -40 +KPX Acircumflex Q -40 +KPX Acircumflex T -37 +KPX Acircumflex Tcaron -37 +KPX Acircumflex Tcommaaccent -37 +KPX Acircumflex U -50 +KPX Acircumflex Uacute -50 +KPX Acircumflex Ucircumflex -50 +KPX Acircumflex Udieresis -50 +KPX Acircumflex Ugrave -50 +KPX Acircumflex Uhungarumlaut -50 +KPX Acircumflex Umacron -50 +KPX Acircumflex Uogonek -50 +KPX Acircumflex Uring -50 +KPX Acircumflex V -105 +KPX Acircumflex W -95 +KPX Acircumflex Y -55 +KPX Acircumflex Yacute -55 +KPX Acircumflex Ydieresis -55 +KPX Acircumflex quoteright -37 +KPX Acircumflex u -20 +KPX Acircumflex uacute -20 +KPX Acircumflex ucircumflex -20 +KPX Acircumflex udieresis -20 +KPX Acircumflex ugrave -20 +KPX Acircumflex uhungarumlaut -20 +KPX Acircumflex umacron -20 +KPX Acircumflex uogonek -20 +KPX Acircumflex uring -20 +KPX Acircumflex v -55 +KPX Acircumflex w -55 +KPX Acircumflex y -55 +KPX Acircumflex yacute -55 +KPX Acircumflex ydieresis -55 +KPX Adieresis C -30 +KPX Adieresis Cacute -30 +KPX Adieresis Ccaron -30 +KPX Adieresis Ccedilla -30 +KPX Adieresis G -35 +KPX Adieresis Gbreve -35 +KPX Adieresis Gcommaaccent -35 +KPX Adieresis O -40 +KPX Adieresis Oacute -40 +KPX Adieresis Ocircumflex -40 +KPX Adieresis Odieresis -40 +KPX Adieresis Ograve -40 +KPX Adieresis Ohungarumlaut -40 +KPX Adieresis Omacron -40 +KPX Adieresis Oslash -40 +KPX Adieresis Otilde -40 +KPX Adieresis Q -40 +KPX Adieresis T -37 +KPX Adieresis Tcaron -37 +KPX Adieresis Tcommaaccent -37 +KPX Adieresis U -50 +KPX Adieresis Uacute -50 +KPX Adieresis Ucircumflex -50 +KPX Adieresis Udieresis -50 +KPX Adieresis Ugrave -50 +KPX Adieresis Uhungarumlaut -50 +KPX Adieresis Umacron -50 +KPX Adieresis Uogonek -50 +KPX Adieresis Uring -50 +KPX Adieresis V -105 +KPX Adieresis W -95 +KPX Adieresis Y -55 +KPX Adieresis Yacute -55 +KPX Adieresis Ydieresis -55 +KPX Adieresis quoteright -37 +KPX Adieresis u -20 +KPX Adieresis uacute -20 +KPX Adieresis ucircumflex -20 +KPX Adieresis udieresis -20 +KPX Adieresis ugrave -20 +KPX Adieresis uhungarumlaut -20 +KPX Adieresis umacron -20 +KPX Adieresis uogonek -20 +KPX Adieresis uring -20 +KPX Adieresis v -55 +KPX Adieresis w -55 +KPX Adieresis y -55 +KPX Adieresis yacute -55 +KPX Adieresis ydieresis -55 +KPX Agrave C -30 +KPX Agrave Cacute -30 +KPX Agrave Ccaron -30 +KPX Agrave Ccedilla -30 +KPX Agrave G -35 +KPX Agrave Gbreve -35 +KPX Agrave Gcommaaccent -35 +KPX Agrave O -40 +KPX Agrave Oacute -40 +KPX Agrave Ocircumflex -40 +KPX Agrave Odieresis -40 +KPX Agrave Ograve -40 +KPX Agrave Ohungarumlaut -40 +KPX Agrave Omacron -40 +KPX Agrave Oslash -40 +KPX Agrave Otilde -40 +KPX Agrave Q -40 +KPX Agrave T -37 +KPX Agrave Tcaron -37 +KPX Agrave Tcommaaccent -37 +KPX Agrave U -50 +KPX Agrave Uacute -50 +KPX Agrave Ucircumflex -50 +KPX Agrave Udieresis -50 +KPX Agrave Ugrave -50 +KPX Agrave Uhungarumlaut -50 +KPX Agrave Umacron -50 +KPX Agrave Uogonek -50 +KPX Agrave Uring -50 +KPX Agrave V -105 +KPX Agrave W -95 +KPX Agrave Y -55 +KPX Agrave Yacute -55 +KPX Agrave Ydieresis -55 +KPX Agrave quoteright -37 +KPX Agrave u -20 +KPX Agrave uacute -20 +KPX Agrave ucircumflex -20 +KPX Agrave udieresis -20 +KPX Agrave ugrave -20 +KPX Agrave uhungarumlaut -20 +KPX Agrave umacron -20 +KPX Agrave uogonek -20 +KPX Agrave uring -20 +KPX Agrave v -55 +KPX Agrave w -55 +KPX Agrave y -55 +KPX Agrave yacute -55 +KPX Agrave ydieresis -55 +KPX Amacron C -30 +KPX Amacron Cacute -30 +KPX Amacron Ccaron -30 +KPX Amacron Ccedilla -30 +KPX Amacron G -35 +KPX Amacron Gbreve -35 +KPX Amacron Gcommaaccent -35 +KPX Amacron O -40 +KPX Amacron Oacute -40 +KPX Amacron Ocircumflex -40 +KPX Amacron Odieresis -40 +KPX Amacron Ograve -40 +KPX Amacron Ohungarumlaut -40 +KPX Amacron Omacron -40 +KPX Amacron Oslash -40 +KPX Amacron Otilde -40 +KPX Amacron Q -40 +KPX Amacron T -37 +KPX Amacron Tcaron -37 +KPX Amacron Tcommaaccent -37 +KPX Amacron U -50 +KPX Amacron Uacute -50 +KPX Amacron Ucircumflex -50 +KPX Amacron Udieresis -50 +KPX Amacron Ugrave -50 +KPX Amacron Uhungarumlaut -50 +KPX Amacron Umacron -50 +KPX Amacron Uogonek -50 +KPX Amacron Uring -50 +KPX Amacron V -105 +KPX Amacron W -95 +KPX Amacron Y -55 +KPX Amacron Yacute -55 +KPX Amacron Ydieresis -55 +KPX Amacron quoteright -37 +KPX Amacron u -20 +KPX Amacron uacute -20 +KPX Amacron ucircumflex -20 +KPX Amacron udieresis -20 +KPX Amacron ugrave -20 +KPX Amacron uhungarumlaut -20 +KPX Amacron umacron -20 +KPX Amacron uogonek -20 +KPX Amacron uring -20 +KPX Amacron v -55 +KPX Amacron w -55 +KPX Amacron y -55 +KPX Amacron yacute -55 +KPX Amacron ydieresis -55 +KPX Aogonek C -30 +KPX Aogonek Cacute -30 +KPX Aogonek Ccaron -30 +KPX Aogonek Ccedilla -30 +KPX Aogonek G -35 +KPX Aogonek Gbreve -35 +KPX Aogonek Gcommaaccent -35 +KPX Aogonek O -40 +KPX Aogonek Oacute -40 +KPX Aogonek Ocircumflex -40 +KPX Aogonek Odieresis -40 +KPX Aogonek Ograve -40 +KPX Aogonek Ohungarumlaut -40 +KPX Aogonek Omacron -40 +KPX Aogonek Oslash -40 +KPX Aogonek Otilde -40 +KPX Aogonek Q -40 +KPX Aogonek T -37 +KPX Aogonek Tcaron -37 +KPX Aogonek Tcommaaccent -37 +KPX Aogonek U -50 +KPX Aogonek Uacute -50 +KPX Aogonek Ucircumflex -50 +KPX Aogonek Udieresis -50 +KPX Aogonek Ugrave -50 +KPX Aogonek Uhungarumlaut -50 +KPX Aogonek Umacron -50 +KPX Aogonek Uogonek -50 +KPX Aogonek Uring -50 +KPX Aogonek V -105 +KPX Aogonek W -95 +KPX Aogonek Y -55 +KPX Aogonek Yacute -55 +KPX Aogonek Ydieresis -55 +KPX Aogonek quoteright -37 +KPX Aogonek u -20 +KPX Aogonek uacute -20 +KPX Aogonek ucircumflex -20 +KPX Aogonek udieresis -20 +KPX Aogonek ugrave -20 +KPX Aogonek uhungarumlaut -20 +KPX Aogonek umacron -20 +KPX Aogonek uogonek -20 +KPX Aogonek uring -20 +KPX Aogonek v -55 +KPX Aogonek w -55 +KPX Aogonek y -55 +KPX Aogonek yacute -55 +KPX Aogonek ydieresis -55 +KPX Aring C -30 +KPX Aring Cacute -30 +KPX Aring Ccaron -30 +KPX Aring Ccedilla -30 +KPX Aring G -35 +KPX Aring Gbreve -35 +KPX Aring Gcommaaccent -35 +KPX Aring O -40 +KPX Aring Oacute -40 +KPX Aring Ocircumflex -40 +KPX Aring Odieresis -40 +KPX Aring Ograve -40 +KPX Aring Ohungarumlaut -40 +KPX Aring Omacron -40 +KPX Aring Oslash -40 +KPX Aring Otilde -40 +KPX Aring Q -40 +KPX Aring T -37 +KPX Aring Tcaron -37 +KPX Aring Tcommaaccent -37 +KPX Aring U -50 +KPX Aring Uacute -50 +KPX Aring Ucircumflex -50 +KPX Aring Udieresis -50 +KPX Aring Ugrave -50 +KPX Aring Uhungarumlaut -50 +KPX Aring Umacron -50 +KPX Aring Uogonek -50 +KPX Aring Uring -50 +KPX Aring V -105 +KPX Aring W -95 +KPX Aring Y -55 +KPX Aring Yacute -55 +KPX Aring Ydieresis -55 +KPX Aring quoteright -37 +KPX Aring u -20 +KPX Aring uacute -20 +KPX Aring ucircumflex -20 +KPX Aring udieresis -20 +KPX Aring ugrave -20 +KPX Aring uhungarumlaut -20 +KPX Aring umacron -20 +KPX Aring uogonek -20 +KPX Aring uring -20 +KPX Aring v -55 +KPX Aring w -55 +KPX Aring y -55 +KPX Aring yacute -55 +KPX Aring ydieresis -55 +KPX Atilde C -30 +KPX Atilde Cacute -30 +KPX Atilde Ccaron -30 +KPX Atilde Ccedilla -30 +KPX Atilde G -35 +KPX Atilde Gbreve -35 +KPX Atilde Gcommaaccent -35 +KPX Atilde O -40 +KPX Atilde Oacute -40 +KPX Atilde Ocircumflex -40 +KPX Atilde Odieresis -40 +KPX Atilde Ograve -40 +KPX Atilde Ohungarumlaut -40 +KPX Atilde Omacron -40 +KPX Atilde Oslash -40 +KPX Atilde Otilde -40 +KPX Atilde Q -40 +KPX Atilde T -37 +KPX Atilde Tcaron -37 +KPX Atilde Tcommaaccent -37 +KPX Atilde U -50 +KPX Atilde Uacute -50 +KPX Atilde Ucircumflex -50 +KPX Atilde Udieresis -50 +KPX Atilde Ugrave -50 +KPX Atilde Uhungarumlaut -50 +KPX Atilde Umacron -50 +KPX Atilde Uogonek -50 +KPX Atilde Uring -50 +KPX Atilde V -105 +KPX Atilde W -95 +KPX Atilde Y -55 +KPX Atilde Yacute -55 +KPX Atilde Ydieresis -55 +KPX Atilde quoteright -37 +KPX Atilde u -20 +KPX Atilde uacute -20 +KPX Atilde ucircumflex -20 +KPX Atilde udieresis -20 +KPX Atilde ugrave -20 +KPX Atilde uhungarumlaut -20 +KPX Atilde umacron -20 +KPX Atilde uogonek -20 +KPX Atilde uring -20 +KPX Atilde v -55 +KPX Atilde w -55 +KPX Atilde y -55 +KPX Atilde yacute -55 +KPX Atilde ydieresis -55 +KPX B A -25 +KPX B Aacute -25 +KPX B Abreve -25 +KPX B Acircumflex -25 +KPX B Adieresis -25 +KPX B Agrave -25 +KPX B Amacron -25 +KPX B Aogonek -25 +KPX B Aring -25 +KPX B Atilde -25 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX D A -35 +KPX D Aacute -35 +KPX D Abreve -35 +KPX D Acircumflex -35 +KPX D Adieresis -35 +KPX D Agrave -35 +KPX D Amacron -35 +KPX D Aogonek -35 +KPX D Aring -35 +KPX D Atilde -35 +KPX D V -40 +KPX D W -40 +KPX D Y -40 +KPX D Yacute -40 +KPX D Ydieresis -40 +KPX Dcaron A -35 +KPX Dcaron Aacute -35 +KPX Dcaron Abreve -35 +KPX Dcaron Acircumflex -35 +KPX Dcaron Adieresis -35 +KPX Dcaron Agrave -35 +KPX Dcaron Amacron -35 +KPX Dcaron Aogonek -35 +KPX Dcaron Aring -35 +KPX Dcaron Atilde -35 +KPX Dcaron V -40 +KPX Dcaron W -40 +KPX Dcaron Y -40 +KPX Dcaron Yacute -40 +KPX Dcaron Ydieresis -40 +KPX Dcroat A -35 +KPX Dcroat Aacute -35 +KPX Dcroat Abreve -35 +KPX Dcroat Acircumflex -35 +KPX Dcroat Adieresis -35 +KPX Dcroat Agrave -35 +KPX Dcroat Amacron -35 +KPX Dcroat Aogonek -35 +KPX Dcroat Aring -35 +KPX Dcroat Atilde -35 +KPX Dcroat V -40 +KPX Dcroat W -40 +KPX Dcroat Y -40 +KPX Dcroat Yacute -40 +KPX Dcroat Ydieresis -40 +KPX F A -115 +KPX F Aacute -115 +KPX F Abreve -115 +KPX F Acircumflex -115 +KPX F Adieresis -115 +KPX F Agrave -115 +KPX F Amacron -115 +KPX F Aogonek -115 +KPX F Aring -115 +KPX F Atilde -115 +KPX F a -75 +KPX F aacute -75 +KPX F abreve -75 +KPX F acircumflex -75 +KPX F adieresis -75 +KPX F agrave -75 +KPX F amacron -75 +KPX F aogonek -75 +KPX F aring -75 +KPX F atilde -75 +KPX F comma -135 +KPX F e -75 +KPX F eacute -75 +KPX F ecaron -75 +KPX F ecircumflex -75 +KPX F edieresis -75 +KPX F edotaccent -75 +KPX F egrave -75 +KPX F emacron -75 +KPX F eogonek -75 +KPX F i -45 +KPX F iacute -45 +KPX F icircumflex -45 +KPX F idieresis -45 +KPX F igrave -45 +KPX F imacron -45 +KPX F iogonek -45 +KPX F o -105 +KPX F oacute -105 +KPX F ocircumflex -105 +KPX F odieresis -105 +KPX F ograve -105 +KPX F ohungarumlaut -105 +KPX F omacron -105 +KPX F oslash -105 +KPX F otilde -105 +KPX F period -135 +KPX F r -55 +KPX F racute -55 +KPX F rcaron -55 +KPX F rcommaaccent -55 +KPX J A -40 +KPX J Aacute -40 +KPX J Abreve -40 +KPX J Acircumflex -40 +KPX J Adieresis -40 +KPX J Agrave -40 +KPX J Amacron -40 +KPX J Aogonek -40 +KPX J Aring -40 +KPX J Atilde -40 +KPX J a -35 +KPX J aacute -35 +KPX J abreve -35 +KPX J acircumflex -35 +KPX J adieresis -35 +KPX J agrave -35 +KPX J amacron -35 +KPX J aogonek -35 +KPX J aring -35 +KPX J atilde -35 +KPX J comma -25 +KPX J e -25 +KPX J eacute -25 +KPX J ecaron -25 +KPX J ecircumflex -25 +KPX J edieresis -25 +KPX J edotaccent -25 +KPX J egrave -25 +KPX J emacron -25 +KPX J eogonek -25 +KPX J o -25 +KPX J oacute -25 +KPX J ocircumflex -25 +KPX J odieresis -25 +KPX J ograve -25 +KPX J ohungarumlaut -25 +KPX J omacron -25 +KPX J oslash -25 +KPX J otilde -25 +KPX J period -25 +KPX J u -35 +KPX J uacute -35 +KPX J ucircumflex -35 +KPX J udieresis -35 +KPX J ugrave -35 +KPX J uhungarumlaut -35 +KPX J umacron -35 +KPX J uogonek -35 +KPX J uring -35 +KPX K O -50 +KPX K Oacute -50 +KPX K Ocircumflex -50 +KPX K Odieresis -50 +KPX K Ograve -50 +KPX K Ohungarumlaut -50 +KPX K Omacron -50 +KPX K Oslash -50 +KPX K Otilde -50 +KPX K e -35 +KPX K eacute -35 +KPX K ecaron -35 +KPX K ecircumflex -35 +KPX K edieresis -35 +KPX K edotaccent -35 +KPX K egrave -35 +KPX K emacron -35 +KPX K eogonek -35 +KPX K o -40 +KPX K oacute -40 +KPX K ocircumflex -40 +KPX K odieresis -40 +KPX K ograve -40 +KPX K ohungarumlaut -40 +KPX K omacron -40 +KPX K oslash -40 +KPX K otilde -40 +KPX K u -40 +KPX K uacute -40 +KPX K ucircumflex -40 +KPX K udieresis -40 +KPX K ugrave -40 +KPX K uhungarumlaut -40 +KPX K umacron -40 +KPX K uogonek -40 +KPX K uring -40 +KPX K y -40 +KPX K yacute -40 +KPX K ydieresis -40 +KPX Kcommaaccent O -50 +KPX Kcommaaccent Oacute -50 +KPX Kcommaaccent Ocircumflex -50 +KPX Kcommaaccent Odieresis -50 +KPX Kcommaaccent Ograve -50 +KPX Kcommaaccent Ohungarumlaut -50 +KPX Kcommaaccent Omacron -50 +KPX Kcommaaccent Oslash -50 +KPX Kcommaaccent Otilde -50 +KPX Kcommaaccent e -35 +KPX Kcommaaccent eacute -35 +KPX Kcommaaccent ecaron -35 +KPX Kcommaaccent ecircumflex -35 +KPX Kcommaaccent edieresis -35 +KPX Kcommaaccent edotaccent -35 +KPX Kcommaaccent egrave -35 +KPX Kcommaaccent emacron -35 +KPX Kcommaaccent eogonek -35 +KPX Kcommaaccent o -40 +KPX Kcommaaccent oacute -40 +KPX Kcommaaccent ocircumflex -40 +KPX Kcommaaccent odieresis -40 +KPX Kcommaaccent ograve -40 +KPX Kcommaaccent ohungarumlaut -40 +KPX Kcommaaccent omacron -40 +KPX Kcommaaccent oslash -40 +KPX Kcommaaccent otilde -40 +KPX Kcommaaccent u -40 +KPX Kcommaaccent uacute -40 +KPX Kcommaaccent ucircumflex -40 +KPX Kcommaaccent udieresis -40 +KPX Kcommaaccent ugrave -40 +KPX Kcommaaccent uhungarumlaut -40 +KPX Kcommaaccent umacron -40 +KPX Kcommaaccent uogonek -40 +KPX Kcommaaccent uring -40 +KPX Kcommaaccent y -40 +KPX Kcommaaccent yacute -40 +KPX Kcommaaccent ydieresis -40 +KPX L T -20 +KPX L Tcaron -20 +KPX L Tcommaaccent -20 +KPX L V -55 +KPX L W -55 +KPX L Y -20 +KPX L Yacute -20 +KPX L Ydieresis -20 +KPX L quoteright -37 +KPX L y -30 +KPX L yacute -30 +KPX L ydieresis -30 +KPX Lacute T -20 +KPX Lacute Tcaron -20 +KPX Lacute Tcommaaccent -20 +KPX Lacute V -55 +KPX Lacute W -55 +KPX Lacute Y -20 +KPX Lacute Yacute -20 +KPX Lacute Ydieresis -20 +KPX Lacute quoteright -37 +KPX Lacute y -30 +KPX Lacute yacute -30 +KPX Lacute ydieresis -30 +KPX Lcommaaccent T -20 +KPX Lcommaaccent Tcaron -20 +KPX Lcommaaccent Tcommaaccent -20 +KPX Lcommaaccent V -55 +KPX Lcommaaccent W -55 +KPX Lcommaaccent Y -20 +KPX Lcommaaccent Yacute -20 +KPX Lcommaaccent Ydieresis -20 +KPX Lcommaaccent quoteright -37 +KPX Lcommaaccent y -30 +KPX Lcommaaccent yacute -30 +KPX Lcommaaccent ydieresis -30 +KPX Lslash T -20 +KPX Lslash Tcaron -20 +KPX Lslash Tcommaaccent -20 +KPX Lslash V -55 +KPX Lslash W -55 +KPX Lslash Y -20 +KPX Lslash Yacute -20 +KPX Lslash Ydieresis -20 +KPX Lslash quoteright -37 +KPX Lslash y -30 +KPX Lslash yacute -30 +KPX Lslash ydieresis -30 +KPX N A -27 +KPX N Aacute -27 +KPX N Abreve -27 +KPX N Acircumflex -27 +KPX N Adieresis -27 +KPX N Agrave -27 +KPX N Amacron -27 +KPX N Aogonek -27 +KPX N Aring -27 +KPX N Atilde -27 +KPX Nacute A -27 +KPX Nacute Aacute -27 +KPX Nacute Abreve -27 +KPX Nacute Acircumflex -27 +KPX Nacute Adieresis -27 +KPX Nacute Agrave -27 +KPX Nacute Amacron -27 +KPX Nacute Aogonek -27 +KPX Nacute Aring -27 +KPX Nacute Atilde -27 +KPX Ncaron A -27 +KPX Ncaron Aacute -27 +KPX Ncaron Abreve -27 +KPX Ncaron Acircumflex -27 +KPX Ncaron Adieresis -27 +KPX Ncaron Agrave -27 +KPX Ncaron Amacron -27 +KPX Ncaron Aogonek -27 +KPX Ncaron Aring -27 +KPX Ncaron Atilde -27 +KPX Ncommaaccent A -27 +KPX Ncommaaccent Aacute -27 +KPX Ncommaaccent Abreve -27 +KPX Ncommaaccent Acircumflex -27 +KPX Ncommaaccent Adieresis -27 +KPX Ncommaaccent Agrave -27 +KPX Ncommaaccent Amacron -27 +KPX Ncommaaccent Aogonek -27 +KPX Ncommaaccent Aring -27 +KPX Ncommaaccent Atilde -27 +KPX Ntilde A -27 +KPX Ntilde Aacute -27 +KPX Ntilde Abreve -27 +KPX Ntilde Acircumflex -27 +KPX Ntilde Adieresis -27 +KPX Ntilde Agrave -27 +KPX Ntilde Amacron -27 +KPX Ntilde Aogonek -27 +KPX Ntilde Aring -27 +KPX Ntilde Atilde -27 +KPX O A -55 +KPX O Aacute -55 +KPX O Abreve -55 +KPX O Acircumflex -55 +KPX O Adieresis -55 +KPX O Agrave -55 +KPX O Amacron -55 +KPX O Aogonek -55 +KPX O Aring -55 +KPX O Atilde -55 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -50 +KPX O X -40 +KPX O Y -50 +KPX O Yacute -50 +KPX O Ydieresis -50 +KPX Oacute A -55 +KPX Oacute Aacute -55 +KPX Oacute Abreve -55 +KPX Oacute Acircumflex -55 +KPX Oacute Adieresis -55 +KPX Oacute Agrave -55 +KPX Oacute Amacron -55 +KPX Oacute Aogonek -55 +KPX Oacute Aring -55 +KPX Oacute Atilde -55 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -50 +KPX Oacute X -40 +KPX Oacute Y -50 +KPX Oacute Yacute -50 +KPX Oacute Ydieresis -50 +KPX Ocircumflex A -55 +KPX Ocircumflex Aacute -55 +KPX Ocircumflex Abreve -55 +KPX Ocircumflex Acircumflex -55 +KPX Ocircumflex Adieresis -55 +KPX Ocircumflex Agrave -55 +KPX Ocircumflex Amacron -55 +KPX Ocircumflex Aogonek -55 +KPX Ocircumflex Aring -55 +KPX Ocircumflex Atilde -55 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -50 +KPX Ocircumflex X -40 +KPX Ocircumflex Y -50 +KPX Ocircumflex Yacute -50 +KPX Ocircumflex Ydieresis -50 +KPX Odieresis A -55 +KPX Odieresis Aacute -55 +KPX Odieresis Abreve -55 +KPX Odieresis Acircumflex -55 +KPX Odieresis Adieresis -55 +KPX Odieresis Agrave -55 +KPX Odieresis Amacron -55 +KPX Odieresis Aogonek -55 +KPX Odieresis Aring -55 +KPX Odieresis Atilde -55 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -50 +KPX Odieresis X -40 +KPX Odieresis Y -50 +KPX Odieresis Yacute -50 +KPX Odieresis Ydieresis -50 +KPX Ograve A -55 +KPX Ograve Aacute -55 +KPX Ograve Abreve -55 +KPX Ograve Acircumflex -55 +KPX Ograve Adieresis -55 +KPX Ograve Agrave -55 +KPX Ograve Amacron -55 +KPX Ograve Aogonek -55 +KPX Ograve Aring -55 +KPX Ograve Atilde -55 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -50 +KPX Ograve X -40 +KPX Ograve Y -50 +KPX Ograve Yacute -50 +KPX Ograve Ydieresis -50 +KPX Ohungarumlaut A -55 +KPX Ohungarumlaut Aacute -55 +KPX Ohungarumlaut Abreve -55 +KPX Ohungarumlaut Acircumflex -55 +KPX Ohungarumlaut Adieresis -55 +KPX Ohungarumlaut Agrave -55 +KPX Ohungarumlaut Amacron -55 +KPX Ohungarumlaut Aogonek -55 +KPX Ohungarumlaut Aring -55 +KPX Ohungarumlaut Atilde -55 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -50 +KPX Ohungarumlaut X -40 +KPX Ohungarumlaut Y -50 +KPX Ohungarumlaut Yacute -50 +KPX Ohungarumlaut Ydieresis -50 +KPX Omacron A -55 +KPX Omacron Aacute -55 +KPX Omacron Abreve -55 +KPX Omacron Acircumflex -55 +KPX Omacron Adieresis -55 +KPX Omacron Agrave -55 +KPX Omacron Amacron -55 +KPX Omacron Aogonek -55 +KPX Omacron Aring -55 +KPX Omacron Atilde -55 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -50 +KPX Omacron X -40 +KPX Omacron Y -50 +KPX Omacron Yacute -50 +KPX Omacron Ydieresis -50 +KPX Oslash A -55 +KPX Oslash Aacute -55 +KPX Oslash Abreve -55 +KPX Oslash Acircumflex -55 +KPX Oslash Adieresis -55 +KPX Oslash Agrave -55 +KPX Oslash Amacron -55 +KPX Oslash Aogonek -55 +KPX Oslash Aring -55 +KPX Oslash Atilde -55 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -50 +KPX Oslash X -40 +KPX Oslash Y -50 +KPX Oslash Yacute -50 +KPX Oslash Ydieresis -50 +KPX Otilde A -55 +KPX Otilde Aacute -55 +KPX Otilde Abreve -55 +KPX Otilde Acircumflex -55 +KPX Otilde Adieresis -55 +KPX Otilde Agrave -55 +KPX Otilde Amacron -55 +KPX Otilde Aogonek -55 +KPX Otilde Aring -55 +KPX Otilde Atilde -55 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -50 +KPX Otilde X -40 +KPX Otilde Y -50 +KPX Otilde Yacute -50 +KPX Otilde Ydieresis -50 +KPX P A -90 +KPX P Aacute -90 +KPX P Abreve -90 +KPX P Acircumflex -90 +KPX P Adieresis -90 +KPX P Agrave -90 +KPX P Amacron -90 +KPX P Aogonek -90 +KPX P Aring -90 +KPX P Atilde -90 +KPX P a -80 +KPX P aacute -80 +KPX P abreve -80 +KPX P acircumflex -80 +KPX P adieresis -80 +KPX P agrave -80 +KPX P amacron -80 +KPX P aogonek -80 +KPX P aring -80 +KPX P atilde -80 +KPX P comma -135 +KPX P e -80 +KPX P eacute -80 +KPX P ecaron -80 +KPX P ecircumflex -80 +KPX P edieresis -80 +KPX P edotaccent -80 +KPX P egrave -80 +KPX P emacron -80 +KPX P eogonek -80 +KPX P o -80 +KPX P oacute -80 +KPX P ocircumflex -80 +KPX P odieresis -80 +KPX P ograve -80 +KPX P ohungarumlaut -80 +KPX P omacron -80 +KPX P oslash -80 +KPX P otilde -80 +KPX P period -135 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX R O -40 +KPX R Oacute -40 +KPX R Ocircumflex -40 +KPX R Odieresis -40 +KPX R Ograve -40 +KPX R Ohungarumlaut -40 +KPX R Omacron -40 +KPX R Oslash -40 +KPX R Otilde -40 +KPX R U -40 +KPX R Uacute -40 +KPX R Ucircumflex -40 +KPX R Udieresis -40 +KPX R Ugrave -40 +KPX R Uhungarumlaut -40 +KPX R Umacron -40 +KPX R Uogonek -40 +KPX R Uring -40 +KPX R V -18 +KPX R W -18 +KPX R Y -18 +KPX R Yacute -18 +KPX R Ydieresis -18 +KPX Racute O -40 +KPX Racute Oacute -40 +KPX Racute Ocircumflex -40 +KPX Racute Odieresis -40 +KPX Racute Ograve -40 +KPX Racute Ohungarumlaut -40 +KPX Racute Omacron -40 +KPX Racute Oslash -40 +KPX Racute Otilde -40 +KPX Racute U -40 +KPX Racute Uacute -40 +KPX Racute Ucircumflex -40 +KPX Racute Udieresis -40 +KPX Racute Ugrave -40 +KPX Racute Uhungarumlaut -40 +KPX Racute Umacron -40 +KPX Racute Uogonek -40 +KPX Racute Uring -40 +KPX Racute V -18 +KPX Racute W -18 +KPX Racute Y -18 +KPX Racute Yacute -18 +KPX Racute Ydieresis -18 +KPX Rcaron O -40 +KPX Rcaron Oacute -40 +KPX Rcaron Ocircumflex -40 +KPX Rcaron Odieresis -40 +KPX Rcaron Ograve -40 +KPX Rcaron Ohungarumlaut -40 +KPX Rcaron Omacron -40 +KPX Rcaron Oslash -40 +KPX Rcaron Otilde -40 +KPX Rcaron U -40 +KPX Rcaron Uacute -40 +KPX Rcaron Ucircumflex -40 +KPX Rcaron Udieresis -40 +KPX Rcaron Ugrave -40 +KPX Rcaron Uhungarumlaut -40 +KPX Rcaron Umacron -40 +KPX Rcaron Uogonek -40 +KPX Rcaron Uring -40 +KPX Rcaron V -18 +KPX Rcaron W -18 +KPX Rcaron Y -18 +KPX Rcaron Yacute -18 +KPX Rcaron Ydieresis -18 +KPX Rcommaaccent O -40 +KPX Rcommaaccent Oacute -40 +KPX Rcommaaccent Ocircumflex -40 +KPX Rcommaaccent Odieresis -40 +KPX Rcommaaccent Ograve -40 +KPX Rcommaaccent Ohungarumlaut -40 +KPX Rcommaaccent Omacron -40 +KPX Rcommaaccent Oslash -40 +KPX Rcommaaccent Otilde -40 +KPX Rcommaaccent U -40 +KPX Rcommaaccent Uacute -40 +KPX Rcommaaccent Ucircumflex -40 +KPX Rcommaaccent Udieresis -40 +KPX Rcommaaccent Ugrave -40 +KPX Rcommaaccent Uhungarumlaut -40 +KPX Rcommaaccent Umacron -40 +KPX Rcommaaccent Uogonek -40 +KPX Rcommaaccent Uring -40 +KPX Rcommaaccent V -18 +KPX Rcommaaccent W -18 +KPX Rcommaaccent Y -18 +KPX Rcommaaccent Yacute -18 +KPX Rcommaaccent Ydieresis -18 +KPX T A -50 +KPX T Aacute -50 +KPX T Abreve -50 +KPX T Acircumflex -50 +KPX T Adieresis -50 +KPX T Agrave -50 +KPX T Amacron -50 +KPX T Aogonek -50 +KPX T Aring -50 +KPX T Atilde -50 +KPX T O -18 +KPX T Oacute -18 +KPX T Ocircumflex -18 +KPX T Odieresis -18 +KPX T Ograve -18 +KPX T Ohungarumlaut -18 +KPX T Omacron -18 +KPX T Oslash -18 +KPX T Otilde -18 +KPX T a -92 +KPX T aacute -92 +KPX T abreve -92 +KPX T acircumflex -92 +KPX T adieresis -92 +KPX T agrave -92 +KPX T amacron -92 +KPX T aogonek -92 +KPX T aring -92 +KPX T atilde -92 +KPX T colon -55 +KPX T comma -74 +KPX T e -92 +KPX T eacute -92 +KPX T ecaron -92 +KPX T ecircumflex -52 +KPX T edieresis -52 +KPX T edotaccent -92 +KPX T egrave -52 +KPX T emacron -52 +KPX T eogonek -92 +KPX T hyphen -74 +KPX T i -55 +KPX T iacute -55 +KPX T iogonek -55 +KPX T o -92 +KPX T oacute -92 +KPX T ocircumflex -92 +KPX T odieresis -92 +KPX T ograve -92 +KPX T ohungarumlaut -92 +KPX T omacron -92 +KPX T oslash -92 +KPX T otilde -92 +KPX T period -74 +KPX T r -55 +KPX T racute -55 +KPX T rcaron -55 +KPX T rcommaaccent -55 +KPX T semicolon -65 +KPX T u -55 +KPX T uacute -55 +KPX T ucircumflex -55 +KPX T udieresis -55 +KPX T ugrave -55 +KPX T uhungarumlaut -55 +KPX T umacron -55 +KPX T uogonek -55 +KPX T uring -55 +KPX T w -74 +KPX T y -74 +KPX T yacute -74 +KPX T ydieresis -34 +KPX Tcaron A -50 +KPX Tcaron Aacute -50 +KPX Tcaron Abreve -50 +KPX Tcaron Acircumflex -50 +KPX Tcaron Adieresis -50 +KPX Tcaron Agrave -50 +KPX Tcaron Amacron -50 +KPX Tcaron Aogonek -50 +KPX Tcaron Aring -50 +KPX Tcaron Atilde -50 +KPX Tcaron O -18 +KPX Tcaron Oacute -18 +KPX Tcaron Ocircumflex -18 +KPX Tcaron Odieresis -18 +KPX Tcaron Ograve -18 +KPX Tcaron Ohungarumlaut -18 +KPX Tcaron Omacron -18 +KPX Tcaron Oslash -18 +KPX Tcaron Otilde -18 +KPX Tcaron a -92 +KPX Tcaron aacute -92 +KPX Tcaron abreve -92 +KPX Tcaron acircumflex -92 +KPX Tcaron adieresis -92 +KPX Tcaron agrave -92 +KPX Tcaron amacron -92 +KPX Tcaron aogonek -92 +KPX Tcaron aring -92 +KPX Tcaron atilde -92 +KPX Tcaron colon -55 +KPX Tcaron comma -74 +KPX Tcaron e -92 +KPX Tcaron eacute -92 +KPX Tcaron ecaron -92 +KPX Tcaron ecircumflex -52 +KPX Tcaron edieresis -52 +KPX Tcaron edotaccent -92 +KPX Tcaron egrave -52 +KPX Tcaron emacron -52 +KPX Tcaron eogonek -92 +KPX Tcaron hyphen -74 +KPX Tcaron i -55 +KPX Tcaron iacute -55 +KPX Tcaron iogonek -55 +KPX Tcaron o -92 +KPX Tcaron oacute -92 +KPX Tcaron ocircumflex -92 +KPX Tcaron odieresis -92 +KPX Tcaron ograve -92 +KPX Tcaron ohungarumlaut -92 +KPX Tcaron omacron -92 +KPX Tcaron oslash -92 +KPX Tcaron otilde -92 +KPX Tcaron period -74 +KPX Tcaron r -55 +KPX Tcaron racute -55 +KPX Tcaron rcaron -55 +KPX Tcaron rcommaaccent -55 +KPX Tcaron semicolon -65 +KPX Tcaron u -55 +KPX Tcaron uacute -55 +KPX Tcaron ucircumflex -55 +KPX Tcaron udieresis -55 +KPX Tcaron ugrave -55 +KPX Tcaron uhungarumlaut -55 +KPX Tcaron umacron -55 +KPX Tcaron uogonek -55 +KPX Tcaron uring -55 +KPX Tcaron w -74 +KPX Tcaron y -74 +KPX Tcaron yacute -74 +KPX Tcaron ydieresis -34 +KPX Tcommaaccent A -50 +KPX Tcommaaccent Aacute -50 +KPX Tcommaaccent Abreve -50 +KPX Tcommaaccent Acircumflex -50 +KPX Tcommaaccent Adieresis -50 +KPX Tcommaaccent Agrave -50 +KPX Tcommaaccent Amacron -50 +KPX Tcommaaccent Aogonek -50 +KPX Tcommaaccent Aring -50 +KPX Tcommaaccent Atilde -50 +KPX Tcommaaccent O -18 +KPX Tcommaaccent Oacute -18 +KPX Tcommaaccent Ocircumflex -18 +KPX Tcommaaccent Odieresis -18 +KPX Tcommaaccent Ograve -18 +KPX Tcommaaccent Ohungarumlaut -18 +KPX Tcommaaccent Omacron -18 +KPX Tcommaaccent Oslash -18 +KPX Tcommaaccent Otilde -18 +KPX Tcommaaccent a -92 +KPX Tcommaaccent aacute -92 +KPX Tcommaaccent abreve -92 +KPX Tcommaaccent acircumflex -92 +KPX Tcommaaccent adieresis -92 +KPX Tcommaaccent agrave -92 +KPX Tcommaaccent amacron -92 +KPX Tcommaaccent aogonek -92 +KPX Tcommaaccent aring -92 +KPX Tcommaaccent atilde -92 +KPX Tcommaaccent colon -55 +KPX Tcommaaccent comma -74 +KPX Tcommaaccent e -92 +KPX Tcommaaccent eacute -92 +KPX Tcommaaccent ecaron -92 +KPX Tcommaaccent ecircumflex -52 +KPX Tcommaaccent edieresis -52 +KPX Tcommaaccent edotaccent -92 +KPX Tcommaaccent egrave -52 +KPX Tcommaaccent emacron -52 +KPX Tcommaaccent eogonek -92 +KPX Tcommaaccent hyphen -74 +KPX Tcommaaccent i -55 +KPX Tcommaaccent iacute -55 +KPX Tcommaaccent iogonek -55 +KPX Tcommaaccent o -92 +KPX Tcommaaccent oacute -92 +KPX Tcommaaccent ocircumflex -92 +KPX Tcommaaccent odieresis -92 +KPX Tcommaaccent ograve -92 +KPX Tcommaaccent ohungarumlaut -92 +KPX Tcommaaccent omacron -92 +KPX Tcommaaccent oslash -92 +KPX Tcommaaccent otilde -92 +KPX Tcommaaccent period -74 +KPX Tcommaaccent r -55 +KPX Tcommaaccent racute -55 +KPX Tcommaaccent rcaron -55 +KPX Tcommaaccent rcommaaccent -55 +KPX Tcommaaccent semicolon -65 +KPX Tcommaaccent u -55 +KPX Tcommaaccent uacute -55 +KPX Tcommaaccent ucircumflex -55 +KPX Tcommaaccent udieresis -55 +KPX Tcommaaccent ugrave -55 +KPX Tcommaaccent uhungarumlaut -55 +KPX Tcommaaccent umacron -55 +KPX Tcommaaccent uogonek -55 +KPX Tcommaaccent uring -55 +KPX Tcommaaccent w -74 +KPX Tcommaaccent y -74 +KPX Tcommaaccent yacute -74 +KPX Tcommaaccent ydieresis -34 +KPX U A -40 +KPX U Aacute -40 +KPX U Abreve -40 +KPX U Acircumflex -40 +KPX U Adieresis -40 +KPX U Agrave -40 +KPX U Amacron -40 +KPX U Aogonek -40 +KPX U Aring -40 +KPX U Atilde -40 +KPX U comma -25 +KPX U period -25 +KPX Uacute A -40 +KPX Uacute Aacute -40 +KPX Uacute Abreve -40 +KPX Uacute Acircumflex -40 +KPX Uacute Adieresis -40 +KPX Uacute Agrave -40 +KPX Uacute Amacron -40 +KPX Uacute Aogonek -40 +KPX Uacute Aring -40 +KPX Uacute Atilde -40 +KPX Uacute comma -25 +KPX Uacute period -25 +KPX Ucircumflex A -40 +KPX Ucircumflex Aacute -40 +KPX Ucircumflex Abreve -40 +KPX Ucircumflex Acircumflex -40 +KPX Ucircumflex Adieresis -40 +KPX Ucircumflex Agrave -40 +KPX Ucircumflex Amacron -40 +KPX Ucircumflex Aogonek -40 +KPX Ucircumflex Aring -40 +KPX Ucircumflex Atilde -40 +KPX Ucircumflex comma -25 +KPX Ucircumflex period -25 +KPX Udieresis A -40 +KPX Udieresis Aacute -40 +KPX Udieresis Abreve -40 +KPX Udieresis Acircumflex -40 +KPX Udieresis Adieresis -40 +KPX Udieresis Agrave -40 +KPX Udieresis Amacron -40 +KPX Udieresis Aogonek -40 +KPX Udieresis Aring -40 +KPX Udieresis Atilde -40 +KPX Udieresis comma -25 +KPX Udieresis period -25 +KPX Ugrave A -40 +KPX Ugrave Aacute -40 +KPX Ugrave Abreve -40 +KPX Ugrave Acircumflex -40 +KPX Ugrave Adieresis -40 +KPX Ugrave Agrave -40 +KPX Ugrave Amacron -40 +KPX Ugrave Aogonek -40 +KPX Ugrave Aring -40 +KPX Ugrave Atilde -40 +KPX Ugrave comma -25 +KPX Ugrave period -25 +KPX Uhungarumlaut A -40 +KPX Uhungarumlaut Aacute -40 +KPX Uhungarumlaut Abreve -40 +KPX Uhungarumlaut Acircumflex -40 +KPX Uhungarumlaut Adieresis -40 +KPX Uhungarumlaut Agrave -40 +KPX Uhungarumlaut Amacron -40 +KPX Uhungarumlaut Aogonek -40 +KPX Uhungarumlaut Aring -40 +KPX Uhungarumlaut Atilde -40 +KPX Uhungarumlaut comma -25 +KPX Uhungarumlaut period -25 +KPX Umacron A -40 +KPX Umacron Aacute -40 +KPX Umacron Abreve -40 +KPX Umacron Acircumflex -40 +KPX Umacron Adieresis -40 +KPX Umacron Agrave -40 +KPX Umacron Amacron -40 +KPX Umacron Aogonek -40 +KPX Umacron Aring -40 +KPX Umacron Atilde -40 +KPX Umacron comma -25 +KPX Umacron period -25 +KPX Uogonek A -40 +KPX Uogonek Aacute -40 +KPX Uogonek Abreve -40 +KPX Uogonek Acircumflex -40 +KPX Uogonek Adieresis -40 +KPX Uogonek Agrave -40 +KPX Uogonek Amacron -40 +KPX Uogonek Aogonek -40 +KPX Uogonek Aring -40 +KPX Uogonek Atilde -40 +KPX Uogonek comma -25 +KPX Uogonek period -25 +KPX Uring A -40 +KPX Uring Aacute -40 +KPX Uring Abreve -40 +KPX Uring Acircumflex -40 +KPX Uring Adieresis -40 +KPX Uring Agrave -40 +KPX Uring Amacron -40 +KPX Uring Aogonek -40 +KPX Uring Aring -40 +KPX Uring Atilde -40 +KPX Uring comma -25 +KPX Uring period -25 +KPX V A -60 +KPX V Aacute -60 +KPX V Abreve -60 +KPX V Acircumflex -60 +KPX V Adieresis -60 +KPX V Agrave -60 +KPX V Amacron -60 +KPX V Aogonek -60 +KPX V Aring -60 +KPX V Atilde -60 +KPX V O -30 +KPX V Oacute -30 +KPX V Ocircumflex -30 +KPX V Odieresis -30 +KPX V Ograve -30 +KPX V Ohungarumlaut -30 +KPX V Omacron -30 +KPX V Oslash -30 +KPX V Otilde -30 +KPX V a -111 +KPX V aacute -111 +KPX V abreve -111 +KPX V acircumflex -111 +KPX V adieresis -111 +KPX V agrave -111 +KPX V amacron -111 +KPX V aogonek -111 +KPX V aring -111 +KPX V atilde -111 +KPX V colon -65 +KPX V comma -129 +KPX V e -111 +KPX V eacute -111 +KPX V ecaron -111 +KPX V ecircumflex -111 +KPX V edieresis -71 +KPX V edotaccent -111 +KPX V egrave -71 +KPX V emacron -71 +KPX V eogonek -111 +KPX V hyphen -55 +KPX V i -74 +KPX V iacute -74 +KPX V icircumflex -34 +KPX V idieresis -34 +KPX V igrave -34 +KPX V imacron -34 +KPX V iogonek -74 +KPX V o -111 +KPX V oacute -111 +KPX V ocircumflex -111 +KPX V odieresis -111 +KPX V ograve -111 +KPX V ohungarumlaut -111 +KPX V omacron -111 +KPX V oslash -111 +KPX V otilde -111 +KPX V period -129 +KPX V semicolon -74 +KPX V u -74 +KPX V uacute -74 +KPX V ucircumflex -74 +KPX V udieresis -74 +KPX V ugrave -74 +KPX V uhungarumlaut -74 +KPX V umacron -74 +KPX V uogonek -74 +KPX V uring -74 +KPX W A -60 +KPX W Aacute -60 +KPX W Abreve -60 +KPX W Acircumflex -60 +KPX W Adieresis -60 +KPX W Agrave -60 +KPX W Amacron -60 +KPX W Aogonek -60 +KPX W Aring -60 +KPX W Atilde -60 +KPX W O -25 +KPX W Oacute -25 +KPX W Ocircumflex -25 +KPX W Odieresis -25 +KPX W Ograve -25 +KPX W Ohungarumlaut -25 +KPX W Omacron -25 +KPX W Oslash -25 +KPX W Otilde -25 +KPX W a -92 +KPX W aacute -92 +KPX W abreve -92 +KPX W acircumflex -92 +KPX W adieresis -92 +KPX W agrave -92 +KPX W amacron -92 +KPX W aogonek -92 +KPX W aring -92 +KPX W atilde -92 +KPX W colon -65 +KPX W comma -92 +KPX W e -92 +KPX W eacute -92 +KPX W ecaron -92 +KPX W ecircumflex -92 +KPX W edieresis -52 +KPX W edotaccent -92 +KPX W egrave -52 +KPX W emacron -52 +KPX W eogonek -92 +KPX W hyphen -37 +KPX W i -55 +KPX W iacute -55 +KPX W iogonek -55 +KPX W o -92 +KPX W oacute -92 +KPX W ocircumflex -92 +KPX W odieresis -92 +KPX W ograve -92 +KPX W ohungarumlaut -92 +KPX W omacron -92 +KPX W oslash -92 +KPX W otilde -92 +KPX W period -92 +KPX W semicolon -65 +KPX W u -55 +KPX W uacute -55 +KPX W ucircumflex -55 +KPX W udieresis -55 +KPX W ugrave -55 +KPX W uhungarumlaut -55 +KPX W umacron -55 +KPX W uogonek -55 +KPX W uring -55 +KPX W y -70 +KPX W yacute -70 +KPX W ydieresis -70 +KPX Y A -50 +KPX Y Aacute -50 +KPX Y Abreve -50 +KPX Y Acircumflex -50 +KPX Y Adieresis -50 +KPX Y Agrave -50 +KPX Y Amacron -50 +KPX Y Aogonek -50 +KPX Y Aring -50 +KPX Y Atilde -50 +KPX Y O -15 +KPX Y Oacute -15 +KPX Y Ocircumflex -15 +KPX Y Odieresis -15 +KPX Y Ograve -15 +KPX Y Ohungarumlaut -15 +KPX Y Omacron -15 +KPX Y Oslash -15 +KPX Y Otilde -15 +KPX Y a -92 +KPX Y aacute -92 +KPX Y abreve -92 +KPX Y acircumflex -92 +KPX Y adieresis -92 +KPX Y agrave -92 +KPX Y amacron -92 +KPX Y aogonek -92 +KPX Y aring -92 +KPX Y atilde -92 +KPX Y colon -65 +KPX Y comma -92 +KPX Y e -92 +KPX Y eacute -92 +KPX Y ecaron -92 +KPX Y ecircumflex -92 +KPX Y edieresis -52 +KPX Y edotaccent -92 +KPX Y egrave -52 +KPX Y emacron -52 +KPX Y eogonek -92 +KPX Y hyphen -74 +KPX Y i -74 +KPX Y iacute -74 +KPX Y icircumflex -34 +KPX Y idieresis -34 +KPX Y igrave -34 +KPX Y imacron -34 +KPX Y iogonek -74 +KPX Y o -92 +KPX Y oacute -92 +KPX Y ocircumflex -92 +KPX Y odieresis -92 +KPX Y ograve -92 +KPX Y ohungarumlaut -92 +KPX Y omacron -92 +KPX Y oslash -92 +KPX Y otilde -92 +KPX Y period -92 +KPX Y semicolon -65 +KPX Y u -92 +KPX Y uacute -92 +KPX Y ucircumflex -92 +KPX Y udieresis -92 +KPX Y ugrave -92 +KPX Y uhungarumlaut -92 +KPX Y umacron -92 +KPX Y uogonek -92 +KPX Y uring -92 +KPX Yacute A -50 +KPX Yacute Aacute -50 +KPX Yacute Abreve -50 +KPX Yacute Acircumflex -50 +KPX Yacute Adieresis -50 +KPX Yacute Agrave -50 +KPX Yacute Amacron -50 +KPX Yacute Aogonek -50 +KPX Yacute Aring -50 +KPX Yacute Atilde -50 +KPX Yacute O -15 +KPX Yacute Oacute -15 +KPX Yacute Ocircumflex -15 +KPX Yacute Odieresis -15 +KPX Yacute Ograve -15 +KPX Yacute Ohungarumlaut -15 +KPX Yacute Omacron -15 +KPX Yacute Oslash -15 +KPX Yacute Otilde -15 +KPX Yacute a -92 +KPX Yacute aacute -92 +KPX Yacute abreve -92 +KPX Yacute acircumflex -92 +KPX Yacute adieresis -92 +KPX Yacute agrave -92 +KPX Yacute amacron -92 +KPX Yacute aogonek -92 +KPX Yacute aring -92 +KPX Yacute atilde -92 +KPX Yacute colon -65 +KPX Yacute comma -92 +KPX Yacute e -92 +KPX Yacute eacute -92 +KPX Yacute ecaron -92 +KPX Yacute ecircumflex -92 +KPX Yacute edieresis -52 +KPX Yacute edotaccent -92 +KPX Yacute egrave -52 +KPX Yacute emacron -52 +KPX Yacute eogonek -92 +KPX Yacute hyphen -74 +KPX Yacute i -74 +KPX Yacute iacute -74 +KPX Yacute icircumflex -34 +KPX Yacute idieresis -34 +KPX Yacute igrave -34 +KPX Yacute imacron -34 +KPX Yacute iogonek -74 +KPX Yacute o -92 +KPX Yacute oacute -92 +KPX Yacute ocircumflex -92 +KPX Yacute odieresis -92 +KPX Yacute ograve -92 +KPX Yacute ohungarumlaut -92 +KPX Yacute omacron -92 +KPX Yacute oslash -92 +KPX Yacute otilde -92 +KPX Yacute period -92 +KPX Yacute semicolon -65 +KPX Yacute u -92 +KPX Yacute uacute -92 +KPX Yacute ucircumflex -92 +KPX Yacute udieresis -92 +KPX Yacute ugrave -92 +KPX Yacute uhungarumlaut -92 +KPX Yacute umacron -92 +KPX Yacute uogonek -92 +KPX Yacute uring -92 +KPX Ydieresis A -50 +KPX Ydieresis Aacute -50 +KPX Ydieresis Abreve -50 +KPX Ydieresis Acircumflex -50 +KPX Ydieresis Adieresis -50 +KPX Ydieresis Agrave -50 +KPX Ydieresis Amacron -50 +KPX Ydieresis Aogonek -50 +KPX Ydieresis Aring -50 +KPX Ydieresis Atilde -50 +KPX Ydieresis O -15 +KPX Ydieresis Oacute -15 +KPX Ydieresis Ocircumflex -15 +KPX Ydieresis Odieresis -15 +KPX Ydieresis Ograve -15 +KPX Ydieresis Ohungarumlaut -15 +KPX Ydieresis Omacron -15 +KPX Ydieresis Oslash -15 +KPX Ydieresis Otilde -15 +KPX Ydieresis a -92 +KPX Ydieresis aacute -92 +KPX Ydieresis abreve -92 +KPX Ydieresis acircumflex -92 +KPX Ydieresis adieresis -92 +KPX Ydieresis agrave -92 +KPX Ydieresis amacron -92 +KPX Ydieresis aogonek -92 +KPX Ydieresis aring -92 +KPX Ydieresis atilde -92 +KPX Ydieresis colon -65 +KPX Ydieresis comma -92 +KPX Ydieresis e -92 +KPX Ydieresis eacute -92 +KPX Ydieresis ecaron -92 +KPX Ydieresis ecircumflex -92 +KPX Ydieresis edieresis -52 +KPX Ydieresis edotaccent -92 +KPX Ydieresis egrave -52 +KPX Ydieresis emacron -52 +KPX Ydieresis eogonek -92 +KPX Ydieresis hyphen -74 +KPX Ydieresis i -74 +KPX Ydieresis iacute -74 +KPX Ydieresis icircumflex -34 +KPX Ydieresis idieresis -34 +KPX Ydieresis igrave -34 +KPX Ydieresis imacron -34 +KPX Ydieresis iogonek -74 +KPX Ydieresis o -92 +KPX Ydieresis oacute -92 +KPX Ydieresis ocircumflex -92 +KPX Ydieresis odieresis -92 +KPX Ydieresis ograve -92 +KPX Ydieresis ohungarumlaut -92 +KPX Ydieresis omacron -92 +KPX Ydieresis oslash -92 +KPX Ydieresis otilde -92 +KPX Ydieresis period -92 +KPX Ydieresis semicolon -65 +KPX Ydieresis u -92 +KPX Ydieresis uacute -92 +KPX Ydieresis ucircumflex -92 +KPX Ydieresis udieresis -92 +KPX Ydieresis ugrave -92 +KPX Ydieresis uhungarumlaut -92 +KPX Ydieresis umacron -92 +KPX Ydieresis uogonek -92 +KPX Ydieresis uring -92 +KPX a g -10 +KPX a gbreve -10 +KPX a gcommaaccent -10 +KPX aacute g -10 +KPX aacute gbreve -10 +KPX aacute gcommaaccent -10 +KPX abreve g -10 +KPX abreve gbreve -10 +KPX abreve gcommaaccent -10 +KPX acircumflex g -10 +KPX acircumflex gbreve -10 +KPX acircumflex gcommaaccent -10 +KPX adieresis g -10 +KPX adieresis gbreve -10 +KPX adieresis gcommaaccent -10 +KPX agrave g -10 +KPX agrave gbreve -10 +KPX agrave gcommaaccent -10 +KPX amacron g -10 +KPX amacron gbreve -10 +KPX amacron gcommaaccent -10 +KPX aogonek g -10 +KPX aogonek gbreve -10 +KPX aogonek gcommaaccent -10 +KPX aring g -10 +KPX aring gbreve -10 +KPX aring gcommaaccent -10 +KPX atilde g -10 +KPX atilde gbreve -10 +KPX atilde gcommaaccent -10 +KPX b period -40 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX c h -15 +KPX c k -20 +KPX c kcommaaccent -20 +KPX cacute h -15 +KPX cacute k -20 +KPX cacute kcommaaccent -20 +KPX ccaron h -15 +KPX ccaron k -20 +KPX ccaron kcommaaccent -20 +KPX ccedilla h -15 +KPX ccedilla k -20 +KPX ccedilla kcommaaccent -20 +KPX comma quotedblright -140 +KPX comma quoteright -140 +KPX e comma -10 +KPX e g -40 +KPX e gbreve -40 +KPX e gcommaaccent -40 +KPX e period -15 +KPX e v -15 +KPX e w -15 +KPX e x -20 +KPX e y -30 +KPX e yacute -30 +KPX e ydieresis -30 +KPX eacute comma -10 +KPX eacute g -40 +KPX eacute gbreve -40 +KPX eacute gcommaaccent -40 +KPX eacute period -15 +KPX eacute v -15 +KPX eacute w -15 +KPX eacute x -20 +KPX eacute y -30 +KPX eacute yacute -30 +KPX eacute ydieresis -30 +KPX ecaron comma -10 +KPX ecaron g -40 +KPX ecaron gbreve -40 +KPX ecaron gcommaaccent -40 +KPX ecaron period -15 +KPX ecaron v -15 +KPX ecaron w -15 +KPX ecaron x -20 +KPX ecaron y -30 +KPX ecaron yacute -30 +KPX ecaron ydieresis -30 +KPX ecircumflex comma -10 +KPX ecircumflex g -40 +KPX ecircumflex gbreve -40 +KPX ecircumflex gcommaaccent -40 +KPX ecircumflex period -15 +KPX ecircumflex v -15 +KPX ecircumflex w -15 +KPX ecircumflex x -20 +KPX ecircumflex y -30 +KPX ecircumflex yacute -30 +KPX ecircumflex ydieresis -30 +KPX edieresis comma -10 +KPX edieresis g -40 +KPX edieresis gbreve -40 +KPX edieresis gcommaaccent -40 +KPX edieresis period -15 +KPX edieresis v -15 +KPX edieresis w -15 +KPX edieresis x -20 +KPX edieresis y -30 +KPX edieresis yacute -30 +KPX edieresis ydieresis -30 +KPX edotaccent comma -10 +KPX edotaccent g -40 +KPX edotaccent gbreve -40 +KPX edotaccent gcommaaccent -40 +KPX edotaccent period -15 +KPX edotaccent v -15 +KPX edotaccent w -15 +KPX edotaccent x -20 +KPX edotaccent y -30 +KPX edotaccent yacute -30 +KPX edotaccent ydieresis -30 +KPX egrave comma -10 +KPX egrave g -40 +KPX egrave gbreve -40 +KPX egrave gcommaaccent -40 +KPX egrave period -15 +KPX egrave v -15 +KPX egrave w -15 +KPX egrave x -20 +KPX egrave y -30 +KPX egrave yacute -30 +KPX egrave ydieresis -30 +KPX emacron comma -10 +KPX emacron g -40 +KPX emacron gbreve -40 +KPX emacron gcommaaccent -40 +KPX emacron period -15 +KPX emacron v -15 +KPX emacron w -15 +KPX emacron x -20 +KPX emacron y -30 +KPX emacron yacute -30 +KPX emacron ydieresis -30 +KPX eogonek comma -10 +KPX eogonek g -40 +KPX eogonek gbreve -40 +KPX eogonek gcommaaccent -40 +KPX eogonek period -15 +KPX eogonek v -15 +KPX eogonek w -15 +KPX eogonek x -20 +KPX eogonek y -30 +KPX eogonek yacute -30 +KPX eogonek ydieresis -30 +KPX f comma -10 +KPX f dotlessi -60 +KPX f f -18 +KPX f i -20 +KPX f iogonek -20 +KPX f period -15 +KPX f quoteright 92 +KPX g comma -10 +KPX g e -10 +KPX g eacute -10 +KPX g ecaron -10 +KPX g ecircumflex -10 +KPX g edieresis -10 +KPX g edotaccent -10 +KPX g egrave -10 +KPX g emacron -10 +KPX g eogonek -10 +KPX g g -10 +KPX g gbreve -10 +KPX g gcommaaccent -10 +KPX g period -15 +KPX gbreve comma -10 +KPX gbreve e -10 +KPX gbreve eacute -10 +KPX gbreve ecaron -10 +KPX gbreve ecircumflex -10 +KPX gbreve edieresis -10 +KPX gbreve edotaccent -10 +KPX gbreve egrave -10 +KPX gbreve emacron -10 +KPX gbreve eogonek -10 +KPX gbreve g -10 +KPX gbreve gbreve -10 +KPX gbreve gcommaaccent -10 +KPX gbreve period -15 +KPX gcommaaccent comma -10 +KPX gcommaaccent e -10 +KPX gcommaaccent eacute -10 +KPX gcommaaccent ecaron -10 +KPX gcommaaccent ecircumflex -10 +KPX gcommaaccent edieresis -10 +KPX gcommaaccent edotaccent -10 +KPX gcommaaccent egrave -10 +KPX gcommaaccent emacron -10 +KPX gcommaaccent eogonek -10 +KPX gcommaaccent g -10 +KPX gcommaaccent gbreve -10 +KPX gcommaaccent gcommaaccent -10 +KPX gcommaaccent period -15 +KPX k e -10 +KPX k eacute -10 +KPX k ecaron -10 +KPX k ecircumflex -10 +KPX k edieresis -10 +KPX k edotaccent -10 +KPX k egrave -10 +KPX k emacron -10 +KPX k eogonek -10 +KPX k o -10 +KPX k oacute -10 +KPX k ocircumflex -10 +KPX k odieresis -10 +KPX k ograve -10 +KPX k ohungarumlaut -10 +KPX k omacron -10 +KPX k oslash -10 +KPX k otilde -10 +KPX k y -10 +KPX k yacute -10 +KPX k ydieresis -10 +KPX kcommaaccent e -10 +KPX kcommaaccent eacute -10 +KPX kcommaaccent ecaron -10 +KPX kcommaaccent ecircumflex -10 +KPX kcommaaccent edieresis -10 +KPX kcommaaccent edotaccent -10 +KPX kcommaaccent egrave -10 +KPX kcommaaccent emacron -10 +KPX kcommaaccent eogonek -10 +KPX kcommaaccent o -10 +KPX kcommaaccent oacute -10 +KPX kcommaaccent ocircumflex -10 +KPX kcommaaccent odieresis -10 +KPX kcommaaccent ograve -10 +KPX kcommaaccent ohungarumlaut -10 +KPX kcommaaccent omacron -10 +KPX kcommaaccent oslash -10 +KPX kcommaaccent otilde -10 +KPX kcommaaccent y -10 +KPX kcommaaccent yacute -10 +KPX kcommaaccent ydieresis -10 +KPX n v -40 +KPX nacute v -40 +KPX ncaron v -40 +KPX ncommaaccent v -40 +KPX ntilde v -40 +KPX o g -10 +KPX o gbreve -10 +KPX o gcommaaccent -10 +KPX o v -10 +KPX oacute g -10 +KPX oacute gbreve -10 +KPX oacute gcommaaccent -10 +KPX oacute v -10 +KPX ocircumflex g -10 +KPX ocircumflex gbreve -10 +KPX ocircumflex gcommaaccent -10 +KPX ocircumflex v -10 +KPX odieresis g -10 +KPX odieresis gbreve -10 +KPX odieresis gcommaaccent -10 +KPX odieresis v -10 +KPX ograve g -10 +KPX ograve gbreve -10 +KPX ograve gcommaaccent -10 +KPX ograve v -10 +KPX ohungarumlaut g -10 +KPX ohungarumlaut gbreve -10 +KPX ohungarumlaut gcommaaccent -10 +KPX ohungarumlaut v -10 +KPX omacron g -10 +KPX omacron gbreve -10 +KPX omacron gcommaaccent -10 +KPX omacron v -10 +KPX oslash g -10 +KPX oslash gbreve -10 +KPX oslash gcommaaccent -10 +KPX oslash v -10 +KPX otilde g -10 +KPX otilde gbreve -10 +KPX otilde gcommaaccent -10 +KPX otilde v -10 +KPX period quotedblright -140 +KPX period quoteright -140 +KPX quoteleft quoteleft -111 +KPX quoteright d -25 +KPX quoteright dcroat -25 +KPX quoteright quoteright -111 +KPX quoteright r -25 +KPX quoteright racute -25 +KPX quoteright rcaron -25 +KPX quoteright rcommaaccent -25 +KPX quoteright s -40 +KPX quoteright sacute -40 +KPX quoteright scaron -40 +KPX quoteright scedilla -40 +KPX quoteright scommaaccent -40 +KPX quoteright space -111 +KPX quoteright t -30 +KPX quoteright tcommaaccent -30 +KPX quoteright v -10 +KPX r a -15 +KPX r aacute -15 +KPX r abreve -15 +KPX r acircumflex -15 +KPX r adieresis -15 +KPX r agrave -15 +KPX r amacron -15 +KPX r aogonek -15 +KPX r aring -15 +KPX r atilde -15 +KPX r c -37 +KPX r cacute -37 +KPX r ccaron -37 +KPX r ccedilla -37 +KPX r comma -111 +KPX r d -37 +KPX r dcroat -37 +KPX r e -37 +KPX r eacute -37 +KPX r ecaron -37 +KPX r ecircumflex -37 +KPX r edieresis -37 +KPX r edotaccent -37 +KPX r egrave -37 +KPX r emacron -37 +KPX r eogonek -37 +KPX r g -37 +KPX r gbreve -37 +KPX r gcommaaccent -37 +KPX r hyphen -20 +KPX r o -45 +KPX r oacute -45 +KPX r ocircumflex -45 +KPX r odieresis -45 +KPX r ograve -45 +KPX r ohungarumlaut -45 +KPX r omacron -45 +KPX r oslash -45 +KPX r otilde -45 +KPX r period -111 +KPX r q -37 +KPX r s -10 +KPX r sacute -10 +KPX r scaron -10 +KPX r scedilla -10 +KPX r scommaaccent -10 +KPX racute a -15 +KPX racute aacute -15 +KPX racute abreve -15 +KPX racute acircumflex -15 +KPX racute adieresis -15 +KPX racute agrave -15 +KPX racute amacron -15 +KPX racute aogonek -15 +KPX racute aring -15 +KPX racute atilde -15 +KPX racute c -37 +KPX racute cacute -37 +KPX racute ccaron -37 +KPX racute ccedilla -37 +KPX racute comma -111 +KPX racute d -37 +KPX racute dcroat -37 +KPX racute e -37 +KPX racute eacute -37 +KPX racute ecaron -37 +KPX racute ecircumflex -37 +KPX racute edieresis -37 +KPX racute edotaccent -37 +KPX racute egrave -37 +KPX racute emacron -37 +KPX racute eogonek -37 +KPX racute g -37 +KPX racute gbreve -37 +KPX racute gcommaaccent -37 +KPX racute hyphen -20 +KPX racute o -45 +KPX racute oacute -45 +KPX racute ocircumflex -45 +KPX racute odieresis -45 +KPX racute ograve -45 +KPX racute ohungarumlaut -45 +KPX racute omacron -45 +KPX racute oslash -45 +KPX racute otilde -45 +KPX racute period -111 +KPX racute q -37 +KPX racute s -10 +KPX racute sacute -10 +KPX racute scaron -10 +KPX racute scedilla -10 +KPX racute scommaaccent -10 +KPX rcaron a -15 +KPX rcaron aacute -15 +KPX rcaron abreve -15 +KPX rcaron acircumflex -15 +KPX rcaron adieresis -15 +KPX rcaron agrave -15 +KPX rcaron amacron -15 +KPX rcaron aogonek -15 +KPX rcaron aring -15 +KPX rcaron atilde -15 +KPX rcaron c -37 +KPX rcaron cacute -37 +KPX rcaron ccaron -37 +KPX rcaron ccedilla -37 +KPX rcaron comma -111 +KPX rcaron d -37 +KPX rcaron dcroat -37 +KPX rcaron e -37 +KPX rcaron eacute -37 +KPX rcaron ecaron -37 +KPX rcaron ecircumflex -37 +KPX rcaron edieresis -37 +KPX rcaron edotaccent -37 +KPX rcaron egrave -37 +KPX rcaron emacron -37 +KPX rcaron eogonek -37 +KPX rcaron g -37 +KPX rcaron gbreve -37 +KPX rcaron gcommaaccent -37 +KPX rcaron hyphen -20 +KPX rcaron o -45 +KPX rcaron oacute -45 +KPX rcaron ocircumflex -45 +KPX rcaron odieresis -45 +KPX rcaron ograve -45 +KPX rcaron ohungarumlaut -45 +KPX rcaron omacron -45 +KPX rcaron oslash -45 +KPX rcaron otilde -45 +KPX rcaron period -111 +KPX rcaron q -37 +KPX rcaron s -10 +KPX rcaron sacute -10 +KPX rcaron scaron -10 +KPX rcaron scedilla -10 +KPX rcaron scommaaccent -10 +KPX rcommaaccent a -15 +KPX rcommaaccent aacute -15 +KPX rcommaaccent abreve -15 +KPX rcommaaccent acircumflex -15 +KPX rcommaaccent adieresis -15 +KPX rcommaaccent agrave -15 +KPX rcommaaccent amacron -15 +KPX rcommaaccent aogonek -15 +KPX rcommaaccent aring -15 +KPX rcommaaccent atilde -15 +KPX rcommaaccent c -37 +KPX rcommaaccent cacute -37 +KPX rcommaaccent ccaron -37 +KPX rcommaaccent ccedilla -37 +KPX rcommaaccent comma -111 +KPX rcommaaccent d -37 +KPX rcommaaccent dcroat -37 +KPX rcommaaccent e -37 +KPX rcommaaccent eacute -37 +KPX rcommaaccent ecaron -37 +KPX rcommaaccent ecircumflex -37 +KPX rcommaaccent edieresis -37 +KPX rcommaaccent edotaccent -37 +KPX rcommaaccent egrave -37 +KPX rcommaaccent emacron -37 +KPX rcommaaccent eogonek -37 +KPX rcommaaccent g -37 +KPX rcommaaccent gbreve -37 +KPX rcommaaccent gcommaaccent -37 +KPX rcommaaccent hyphen -20 +KPX rcommaaccent o -45 +KPX rcommaaccent oacute -45 +KPX rcommaaccent ocircumflex -45 +KPX rcommaaccent odieresis -45 +KPX rcommaaccent ograve -45 +KPX rcommaaccent ohungarumlaut -45 +KPX rcommaaccent omacron -45 +KPX rcommaaccent oslash -45 +KPX rcommaaccent otilde -45 +KPX rcommaaccent period -111 +KPX rcommaaccent q -37 +KPX rcommaaccent s -10 +KPX rcommaaccent sacute -10 +KPX rcommaaccent scaron -10 +KPX rcommaaccent scedilla -10 +KPX rcommaaccent scommaaccent -10 +KPX space A -18 +KPX space Aacute -18 +KPX space Abreve -18 +KPX space Acircumflex -18 +KPX space Adieresis -18 +KPX space Agrave -18 +KPX space Amacron -18 +KPX space Aogonek -18 +KPX space Aring -18 +KPX space Atilde -18 +KPX space T -18 +KPX space Tcaron -18 +KPX space Tcommaaccent -18 +KPX space V -35 +KPX space W -40 +KPX space Y -75 +KPX space Yacute -75 +KPX space Ydieresis -75 +KPX v comma -74 +KPX v period -74 +KPX w comma -74 +KPX w period -74 +KPX y comma -55 +KPX y period -55 +KPX yacute comma -55 +KPX yacute period -55 +KPX ydieresis comma -55 +KPX ydieresis period -55 +EndKernPairs +EndKernData +EndFontMetrics addfile ./Core14_AFMs/Times-Roman.afm hunk ./Core14_AFMs/Times-Roman.afm 1 +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 12:49:17 1997 +Comment UniqueID 43068 +Comment VMusage 43909 54934 +FontName Times-Roman +FullName Times Roman +FamilyName Times +Weight Roman +ItalicAngle 0 +IsFixedPitch false +CharacterSet ExtendedRoman +FontBBox -168 -218 1000 898 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries. +EncodingScheme AdobeStandardEncoding +CapHeight 662 +XHeight 450 +Ascender 683 +Descender -217 +StdHW 28 +StdVW 84 +StartCharMetrics 315 +C 32 ; WX 250 ; N space ; B 0 0 0 0 ; +C 33 ; WX 333 ; N exclam ; B 130 -9 238 676 ; +C 34 ; WX 408 ; N quotedbl ; B 77 431 331 676 ; +C 35 ; WX 500 ; N numbersign ; B 5 0 496 662 ; +C 36 ; WX 500 ; N dollar ; B 44 -87 457 727 ; +C 37 ; WX 833 ; N percent ; B 61 -13 772 676 ; +C 38 ; WX 778 ; N ampersand ; B 42 -13 750 676 ; +C 39 ; WX 333 ; N quoteright ; B 79 433 218 676 ; +C 40 ; WX 333 ; N parenleft ; B 48 -177 304 676 ; +C 41 ; WX 333 ; N parenright ; B 29 -177 285 676 ; +C 42 ; WX 500 ; N asterisk ; B 69 265 432 676 ; +C 43 ; WX 564 ; N plus ; B 30 0 534 506 ; +C 44 ; WX 250 ; N comma ; B 56 -141 195 102 ; +C 45 ; WX 333 ; N hyphen ; B 39 194 285 257 ; +C 46 ; WX 250 ; N period ; B 70 -11 181 100 ; +C 47 ; WX 278 ; N slash ; B -9 -14 287 676 ; +C 48 ; WX 500 ; N zero ; B 24 -14 476 676 ; +C 49 ; WX 500 ; N one ; B 111 0 394 676 ; +C 50 ; WX 500 ; N two ; B 30 0 475 676 ; +C 51 ; WX 500 ; N three ; B 43 -14 431 676 ; +C 52 ; WX 500 ; N four ; B 12 0 472 676 ; +C 53 ; WX 500 ; N five ; B 32 -14 438 688 ; +C 54 ; WX 500 ; N six ; B 34 -14 468 684 ; +C 55 ; WX 500 ; N seven ; B 20 -8 449 662 ; +C 56 ; WX 500 ; N eight ; B 56 -14 445 676 ; +C 57 ; WX 500 ; N nine ; B 30 -22 459 676 ; +C 58 ; WX 278 ; N colon ; B 81 -11 192 459 ; +C 59 ; WX 278 ; N semicolon ; B 80 -141 219 459 ; +C 60 ; WX 564 ; N less ; B 28 -8 536 514 ; +C 61 ; WX 564 ; N equal ; B 30 120 534 386 ; +C 62 ; WX 564 ; N greater ; B 28 -8 536 514 ; +C 63 ; WX 444 ; N question ; B 68 -8 414 676 ; +C 64 ; WX 921 ; N at ; B 116 -14 809 676 ; +C 65 ; WX 722 ; N A ; B 15 0 706 674 ; +C 66 ; WX 667 ; N B ; B 17 0 593 662 ; +C 67 ; WX 667 ; N C ; B 28 -14 633 676 ; +C 68 ; WX 722 ; N D ; B 16 0 685 662 ; +C 69 ; WX 611 ; N E ; B 12 0 597 662 ; +C 70 ; WX 556 ; N F ; B 12 0 546 662 ; +C 71 ; WX 722 ; N G ; B 32 -14 709 676 ; +C 72 ; WX 722 ; N H ; B 19 0 702 662 ; +C 73 ; WX 333 ; N I ; B 18 0 315 662 ; +C 74 ; WX 389 ; N J ; B 10 -14 370 662 ; +C 75 ; WX 722 ; N K ; B 34 0 723 662 ; +C 76 ; WX 611 ; N L ; B 12 0 598 662 ; +C 77 ; WX 889 ; N M ; B 12 0 863 662 ; +C 78 ; WX 722 ; N N ; B 12 -11 707 662 ; +C 79 ; WX 722 ; N O ; B 34 -14 688 676 ; +C 80 ; WX 556 ; N P ; B 16 0 542 662 ; +C 81 ; WX 722 ; N Q ; B 34 -178 701 676 ; +C 82 ; WX 667 ; N R ; B 17 0 659 662 ; +C 83 ; WX 556 ; N S ; B 42 -14 491 676 ; +C 84 ; WX 611 ; N T ; B 17 0 593 662 ; +C 85 ; WX 722 ; N U ; B 14 -14 705 662 ; +C 86 ; WX 722 ; N V ; B 16 -11 697 662 ; +C 87 ; WX 944 ; N W ; B 5 -11 932 662 ; +C 88 ; WX 722 ; N X ; B 10 0 704 662 ; +C 89 ; WX 722 ; N Y ; B 22 0 703 662 ; +C 90 ; WX 611 ; N Z ; B 9 0 597 662 ; +C 91 ; WX 333 ; N bracketleft ; B 88 -156 299 662 ; +C 92 ; WX 278 ; N backslash ; B -9 -14 287 676 ; +C 93 ; WX 333 ; N bracketright ; B 34 -156 245 662 ; +C 94 ; WX 469 ; N asciicircum ; B 24 297 446 662 ; +C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; +C 96 ; WX 333 ; N quoteleft ; B 115 433 254 676 ; +C 97 ; WX 444 ; N a ; B 37 -10 442 460 ; +C 98 ; WX 500 ; N b ; B 3 -10 468 683 ; +C 99 ; WX 444 ; N c ; B 25 -10 412 460 ; +C 100 ; WX 500 ; N d ; B 27 -10 491 683 ; +C 101 ; WX 444 ; N e ; B 25 -10 424 460 ; +C 102 ; WX 333 ; N f ; B 20 0 383 683 ; L i fi ; L l fl ; +C 103 ; WX 500 ; N g ; B 28 -218 470 460 ; +C 104 ; WX 500 ; N h ; B 9 0 487 683 ; +C 105 ; WX 278 ; N i ; B 16 0 253 683 ; +C 106 ; WX 278 ; N j ; B -70 -218 194 683 ; +C 107 ; WX 500 ; N k ; B 7 0 505 683 ; +C 108 ; WX 278 ; N l ; B 19 0 257 683 ; +C 109 ; WX 778 ; N m ; B 16 0 775 460 ; +C 110 ; WX 500 ; N n ; B 16 0 485 460 ; +C 111 ; WX 500 ; N o ; B 29 -10 470 460 ; +C 112 ; WX 500 ; N p ; B 5 -217 470 460 ; +C 113 ; WX 500 ; N q ; B 24 -217 488 460 ; +C 114 ; WX 333 ; N r ; B 5 0 335 460 ; +C 115 ; WX 389 ; N s ; B 51 -10 348 460 ; +C 116 ; WX 278 ; N t ; B 13 -10 279 579 ; +C 117 ; WX 500 ; N u ; B 9 -10 479 450 ; +C 118 ; WX 500 ; N v ; B 19 -14 477 450 ; +C 119 ; WX 722 ; N w ; B 21 -14 694 450 ; +C 120 ; WX 500 ; N x ; B 17 0 479 450 ; +C 121 ; WX 500 ; N y ; B 14 -218 475 450 ; +C 122 ; WX 444 ; N z ; B 27 0 418 450 ; +C 123 ; WX 480 ; N braceleft ; B 100 -181 350 680 ; +C 124 ; WX 200 ; N bar ; B 67 -218 133 782 ; +C 125 ; WX 480 ; N braceright ; B 130 -181 380 680 ; +C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ; +C 161 ; WX 333 ; N exclamdown ; B 97 -218 205 467 ; +C 162 ; WX 500 ; N cent ; B 53 -138 448 579 ; +C 163 ; WX 500 ; N sterling ; B 12 -8 490 676 ; +C 164 ; WX 167 ; N fraction ; B -168 -14 331 676 ; +C 165 ; WX 500 ; N yen ; B -53 0 512 662 ; +C 166 ; WX 500 ; N florin ; B 7 -189 490 676 ; +C 167 ; WX 500 ; N section ; B 70 -148 426 676 ; +C 168 ; WX 500 ; N currency ; B -22 58 522 602 ; +C 169 ; WX 180 ; N quotesingle ; B 48 431 133 676 ; +C 170 ; WX 444 ; N quotedblleft ; B 43 433 414 676 ; +C 171 ; WX 500 ; N guillemotleft ; B 42 33 456 416 ; +C 172 ; WX 333 ; N guilsinglleft ; B 63 33 285 416 ; +C 173 ; WX 333 ; N guilsinglright ; B 48 33 270 416 ; +C 174 ; WX 556 ; N fi ; B 31 0 521 683 ; +C 175 ; WX 556 ; N fl ; B 32 0 521 683 ; +C 177 ; WX 500 ; N endash ; B 0 201 500 250 ; +C 178 ; WX 500 ; N dagger ; B 59 -149 442 676 ; +C 179 ; WX 500 ; N daggerdbl ; B 58 -153 442 676 ; +C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ; +C 182 ; WX 453 ; N paragraph ; B -22 -154 450 662 ; +C 183 ; WX 350 ; N bullet ; B 40 196 310 466 ; +C 184 ; WX 333 ; N quotesinglbase ; B 79 -141 218 102 ; +C 185 ; WX 444 ; N quotedblbase ; B 45 -141 416 102 ; +C 186 ; WX 444 ; N quotedblright ; B 30 433 401 676 ; +C 187 ; WX 500 ; N guillemotright ; B 44 33 458 416 ; +C 188 ; WX 1000 ; N ellipsis ; B 111 -11 888 100 ; +C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 706 ; +C 191 ; WX 444 ; N questiondown ; B 30 -218 376 466 ; +C 193 ; WX 333 ; N grave ; B 19 507 242 678 ; +C 194 ; WX 333 ; N acute ; B 93 507 317 678 ; +C 195 ; WX 333 ; N circumflex ; B 11 507 322 674 ; +C 196 ; WX 333 ; N tilde ; B 1 532 331 638 ; +C 197 ; WX 333 ; N macron ; B 11 547 322 601 ; +C 198 ; WX 333 ; N breve ; B 26 507 307 664 ; +C 199 ; WX 333 ; N dotaccent ; B 118 581 216 681 ; +C 200 ; WX 333 ; N dieresis ; B 18 581 315 681 ; +C 202 ; WX 333 ; N ring ; B 67 512 266 711 ; +C 203 ; WX 333 ; N cedilla ; B 52 -215 261 0 ; +C 205 ; WX 333 ; N hungarumlaut ; B -3 507 377 678 ; +C 206 ; WX 333 ; N ogonek ; B 62 -165 243 0 ; +C 207 ; WX 333 ; N caron ; B 11 507 322 674 ; +C 208 ; WX 1000 ; N emdash ; B 0 201 1000 250 ; +C 225 ; WX 889 ; N AE ; B 0 0 863 662 ; +C 227 ; WX 276 ; N ordfeminine ; B 4 394 270 676 ; +C 232 ; WX 611 ; N Lslash ; B 12 0 598 662 ; +C 233 ; WX 722 ; N Oslash ; B 34 -80 688 734 ; +C 234 ; WX 889 ; N OE ; B 30 -6 885 668 ; +C 235 ; WX 310 ; N ordmasculine ; B 6 394 304 676 ; +C 241 ; WX 667 ; N ae ; B 38 -10 632 460 ; +C 245 ; WX 278 ; N dotlessi ; B 16 0 253 460 ; +C 248 ; WX 278 ; N lslash ; B 19 0 259 683 ; +C 249 ; WX 500 ; N oslash ; B 29 -112 470 551 ; +C 250 ; WX 722 ; N oe ; B 30 -10 690 460 ; +C 251 ; WX 500 ; N germandbls ; B 12 -9 468 683 ; +C -1 ; WX 333 ; N Idieresis ; B 18 0 315 835 ; +C -1 ; WX 444 ; N eacute ; B 25 -10 424 678 ; +C -1 ; WX 444 ; N abreve ; B 37 -10 442 664 ; +C -1 ; WX 500 ; N uhungarumlaut ; B 9 -10 501 678 ; +C -1 ; WX 444 ; N ecaron ; B 25 -10 424 674 ; +C -1 ; WX 722 ; N Ydieresis ; B 22 0 703 835 ; +C -1 ; WX 564 ; N divide ; B 30 -10 534 516 ; +C -1 ; WX 722 ; N Yacute ; B 22 0 703 890 ; +C -1 ; WX 722 ; N Acircumflex ; B 15 0 706 886 ; +C -1 ; WX 444 ; N aacute ; B 37 -10 442 678 ; +C -1 ; WX 722 ; N Ucircumflex ; B 14 -14 705 886 ; +C -1 ; WX 500 ; N yacute ; B 14 -218 475 678 ; +C -1 ; WX 389 ; N scommaaccent ; B 51 -218 348 460 ; +C -1 ; WX 444 ; N ecircumflex ; B 25 -10 424 674 ; +C -1 ; WX 722 ; N Uring ; B 14 -14 705 898 ; +C -1 ; WX 722 ; N Udieresis ; B 14 -14 705 835 ; +C -1 ; WX 444 ; N aogonek ; B 37 -165 469 460 ; +C -1 ; WX 722 ; N Uacute ; B 14 -14 705 890 ; +C -1 ; WX 500 ; N uogonek ; B 9 -155 487 450 ; +C -1 ; WX 611 ; N Edieresis ; B 12 0 597 835 ; +C -1 ; WX 722 ; N Dcroat ; B 16 0 685 662 ; +C -1 ; WX 250 ; N commaaccent ; B 59 -218 184 -50 ; +C -1 ; WX 760 ; N copyright ; B 38 -14 722 676 ; +C -1 ; WX 611 ; N Emacron ; B 12 0 597 813 ; +C -1 ; WX 444 ; N ccaron ; B 25 -10 412 674 ; +C -1 ; WX 444 ; N aring ; B 37 -10 442 711 ; +C -1 ; WX 722 ; N Ncommaaccent ; B 12 -198 707 662 ; +C -1 ; WX 278 ; N lacute ; B 19 0 290 890 ; +C -1 ; WX 444 ; N agrave ; B 37 -10 442 678 ; +C -1 ; WX 611 ; N Tcommaaccent ; B 17 -218 593 662 ; +C -1 ; WX 667 ; N Cacute ; B 28 -14 633 890 ; +C -1 ; WX 444 ; N atilde ; B 37 -10 442 638 ; +C -1 ; WX 611 ; N Edotaccent ; B 12 0 597 835 ; +C -1 ; WX 389 ; N scaron ; B 39 -10 350 674 ; +C -1 ; WX 389 ; N scedilla ; B 51 -215 348 460 ; +C -1 ; WX 278 ; N iacute ; B 16 0 290 678 ; +C -1 ; WX 471 ; N lozenge ; B 13 0 459 724 ; +C -1 ; WX 667 ; N Rcaron ; B 17 0 659 886 ; +C -1 ; WX 722 ; N Gcommaaccent ; B 32 -218 709 676 ; +C -1 ; WX 500 ; N ucircumflex ; B 9 -10 479 674 ; +C -1 ; WX 444 ; N acircumflex ; B 37 -10 442 674 ; +C -1 ; WX 722 ; N Amacron ; B 15 0 706 813 ; +C -1 ; WX 333 ; N rcaron ; B 5 0 335 674 ; +C -1 ; WX 444 ; N ccedilla ; B 25 -215 412 460 ; +C -1 ; WX 611 ; N Zdotaccent ; B 9 0 597 835 ; +C -1 ; WX 556 ; N Thorn ; B 16 0 542 662 ; +C -1 ; WX 722 ; N Omacron ; B 34 -14 688 813 ; +C -1 ; WX 667 ; N Racute ; B 17 0 659 890 ; +C -1 ; WX 556 ; N Sacute ; B 42 -14 491 890 ; +C -1 ; WX 588 ; N dcaron ; B 27 -10 589 695 ; +C -1 ; WX 722 ; N Umacron ; B 14 -14 705 813 ; +C -1 ; WX 500 ; N uring ; B 9 -10 479 711 ; +C -1 ; WX 300 ; N threesuperior ; B 15 262 291 676 ; +C -1 ; WX 722 ; N Ograve ; B 34 -14 688 890 ; +C -1 ; WX 722 ; N Agrave ; B 15 0 706 890 ; +C -1 ; WX 722 ; N Abreve ; B 15 0 706 876 ; +C -1 ; WX 564 ; N multiply ; B 38 8 527 497 ; +C -1 ; WX 500 ; N uacute ; B 9 -10 479 678 ; +C -1 ; WX 611 ; N Tcaron ; B 17 0 593 886 ; +C -1 ; WX 476 ; N partialdiff ; B 17 -38 459 710 ; +C -1 ; WX 500 ; N ydieresis ; B 14 -218 475 623 ; +C -1 ; WX 722 ; N Nacute ; B 12 -11 707 890 ; +C -1 ; WX 278 ; N icircumflex ; B -16 0 295 674 ; +C -1 ; WX 611 ; N Ecircumflex ; B 12 0 597 886 ; +C -1 ; WX 444 ; N adieresis ; B 37 -10 442 623 ; +C -1 ; WX 444 ; N edieresis ; B 25 -10 424 623 ; +C -1 ; WX 444 ; N cacute ; B 25 -10 413 678 ; +C -1 ; WX 500 ; N nacute ; B 16 0 485 678 ; +C -1 ; WX 500 ; N umacron ; B 9 -10 479 601 ; +C -1 ; WX 722 ; N Ncaron ; B 12 -11 707 886 ; +C -1 ; WX 333 ; N Iacute ; B 18 0 317 890 ; +C -1 ; WX 564 ; N plusminus ; B 30 0 534 506 ; +C -1 ; WX 200 ; N brokenbar ; B 67 -143 133 707 ; +C -1 ; WX 760 ; N registered ; B 38 -14 722 676 ; +C -1 ; WX 722 ; N Gbreve ; B 32 -14 709 876 ; +C -1 ; WX 333 ; N Idotaccent ; B 18 0 315 835 ; +C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ; +C -1 ; WX 611 ; N Egrave ; B 12 0 597 890 ; +C -1 ; WX 333 ; N racute ; B 5 0 335 678 ; +C -1 ; WX 500 ; N omacron ; B 29 -10 470 601 ; +C -1 ; WX 611 ; N Zacute ; B 9 0 597 890 ; +C -1 ; WX 611 ; N Zcaron ; B 9 0 597 886 ; +C -1 ; WX 549 ; N greaterequal ; B 26 0 523 666 ; +C -1 ; WX 722 ; N Eth ; B 16 0 685 662 ; +C -1 ; WX 667 ; N Ccedilla ; B 28 -215 633 676 ; +C -1 ; WX 278 ; N lcommaaccent ; B 19 -218 257 683 ; +C -1 ; WX 326 ; N tcaron ; B 13 -10 318 722 ; +C -1 ; WX 444 ; N eogonek ; B 25 -165 424 460 ; +C -1 ; WX 722 ; N Uogonek ; B 14 -165 705 662 ; +C -1 ; WX 722 ; N Aacute ; B 15 0 706 890 ; +C -1 ; WX 722 ; N Adieresis ; B 15 0 706 835 ; +C -1 ; WX 444 ; N egrave ; B 25 -10 424 678 ; +C -1 ; WX 444 ; N zacute ; B 27 0 418 678 ; +C -1 ; WX 278 ; N iogonek ; B 16 -165 265 683 ; +C -1 ; WX 722 ; N Oacute ; B 34 -14 688 890 ; +C -1 ; WX 500 ; N oacute ; B 29 -10 470 678 ; +C -1 ; WX 444 ; N amacron ; B 37 -10 442 601 ; +C -1 ; WX 389 ; N sacute ; B 51 -10 348 678 ; +C -1 ; WX 278 ; N idieresis ; B -9 0 288 623 ; +C -1 ; WX 722 ; N Ocircumflex ; B 34 -14 688 886 ; +C -1 ; WX 722 ; N Ugrave ; B 14 -14 705 890 ; +C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; +C -1 ; WX 500 ; N thorn ; B 5 -217 470 683 ; +C -1 ; WX 300 ; N twosuperior ; B 1 270 296 676 ; +C -1 ; WX 722 ; N Odieresis ; B 34 -14 688 835 ; +C -1 ; WX 500 ; N mu ; B 36 -218 512 450 ; +C -1 ; WX 278 ; N igrave ; B -8 0 253 678 ; +C -1 ; WX 500 ; N ohungarumlaut ; B 29 -10 491 678 ; +C -1 ; WX 611 ; N Eogonek ; B 12 -165 597 662 ; +C -1 ; WX 500 ; N dcroat ; B 27 -10 500 683 ; +C -1 ; WX 750 ; N threequarters ; B 15 -14 718 676 ; +C -1 ; WX 556 ; N Scedilla ; B 42 -215 491 676 ; +C -1 ; WX 344 ; N lcaron ; B 19 0 347 695 ; +C -1 ; WX 722 ; N Kcommaaccent ; B 34 -198 723 662 ; +C -1 ; WX 611 ; N Lacute ; B 12 0 598 890 ; +C -1 ; WX 980 ; N trademark ; B 30 256 957 662 ; +C -1 ; WX 444 ; N edotaccent ; B 25 -10 424 623 ; +C -1 ; WX 333 ; N Igrave ; B 18 0 315 890 ; +C -1 ; WX 333 ; N Imacron ; B 11 0 322 813 ; +C -1 ; WX 611 ; N Lcaron ; B 12 0 598 676 ; +C -1 ; WX 750 ; N onehalf ; B 31 -14 746 676 ; +C -1 ; WX 549 ; N lessequal ; B 26 0 523 666 ; +C -1 ; WX 500 ; N ocircumflex ; B 29 -10 470 674 ; +C -1 ; WX 500 ; N ntilde ; B 16 0 485 638 ; +C -1 ; WX 722 ; N Uhungarumlaut ; B 14 -14 705 890 ; +C -1 ; WX 611 ; N Eacute ; B 12 0 597 890 ; +C -1 ; WX 444 ; N emacron ; B 25 -10 424 601 ; +C -1 ; WX 500 ; N gbreve ; B 28 -218 470 664 ; +C -1 ; WX 750 ; N onequarter ; B 37 -14 718 676 ; +C -1 ; WX 556 ; N Scaron ; B 42 -14 491 886 ; +C -1 ; WX 556 ; N Scommaaccent ; B 42 -218 491 676 ; +C -1 ; WX 722 ; N Ohungarumlaut ; B 34 -14 688 890 ; +C -1 ; WX 400 ; N degree ; B 57 390 343 676 ; +C -1 ; WX 500 ; N ograve ; B 29 -10 470 678 ; +C -1 ; WX 667 ; N Ccaron ; B 28 -14 633 886 ; +C -1 ; WX 500 ; N ugrave ; B 9 -10 479 678 ; +C -1 ; WX 453 ; N radical ; B 2 -60 452 768 ; +C -1 ; WX 722 ; N Dcaron ; B 16 0 685 886 ; +C -1 ; WX 333 ; N rcommaaccent ; B 5 -218 335 460 ; +C -1 ; WX 722 ; N Ntilde ; B 12 -11 707 850 ; +C -1 ; WX 500 ; N otilde ; B 29 -10 470 638 ; +C -1 ; WX 667 ; N Rcommaaccent ; B 17 -198 659 662 ; +C -1 ; WX 611 ; N Lcommaaccent ; B 12 -218 598 662 ; +C -1 ; WX 722 ; N Atilde ; B 15 0 706 850 ; +C -1 ; WX 722 ; N Aogonek ; B 15 -165 738 674 ; +C -1 ; WX 722 ; N Aring ; B 15 0 706 898 ; +C -1 ; WX 722 ; N Otilde ; B 34 -14 688 850 ; +C -1 ; WX 444 ; N zdotaccent ; B 27 0 418 623 ; +C -1 ; WX 611 ; N Ecaron ; B 12 0 597 886 ; +C -1 ; WX 333 ; N Iogonek ; B 18 -165 315 662 ; +C -1 ; WX 500 ; N kcommaaccent ; B 7 -218 505 683 ; +C -1 ; WX 564 ; N minus ; B 30 220 534 286 ; +C -1 ; WX 333 ; N Icircumflex ; B 11 0 322 886 ; +C -1 ; WX 500 ; N ncaron ; B 16 0 485 674 ; +C -1 ; WX 278 ; N tcommaaccent ; B 13 -218 279 579 ; +C -1 ; WX 564 ; N logicalnot ; B 30 108 534 386 ; +C -1 ; WX 500 ; N odieresis ; B 29 -10 470 623 ; +C -1 ; WX 500 ; N udieresis ; B 9 -10 479 623 ; +C -1 ; WX 549 ; N notequal ; B 12 -31 537 547 ; +C -1 ; WX 500 ; N gcommaaccent ; B 28 -218 470 749 ; +C -1 ; WX 500 ; N eth ; B 29 -10 471 686 ; +C -1 ; WX 444 ; N zcaron ; B 27 0 418 674 ; +C -1 ; WX 500 ; N ncommaaccent ; B 16 -218 485 460 ; +C -1 ; WX 300 ; N onesuperior ; B 57 270 248 676 ; +C -1 ; WX 278 ; N imacron ; B 6 0 271 601 ; +C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +StartKernData +StartKernPairs 2073 +KPX A C -40 +KPX A Cacute -40 +KPX A Ccaron -40 +KPX A Ccedilla -40 +KPX A G -40 +KPX A Gbreve -40 +KPX A Gcommaaccent -40 +KPX A O -55 +KPX A Oacute -55 +KPX A Ocircumflex -55 +KPX A Odieresis -55 +KPX A Ograve -55 +KPX A Ohungarumlaut -55 +KPX A Omacron -55 +KPX A Oslash -55 +KPX A Otilde -55 +KPX A Q -55 +KPX A T -111 +KPX A Tcaron -111 +KPX A Tcommaaccent -111 +KPX A U -55 +KPX A Uacute -55 +KPX A Ucircumflex -55 +KPX A Udieresis -55 +KPX A Ugrave -55 +KPX A Uhungarumlaut -55 +KPX A Umacron -55 +KPX A Uogonek -55 +KPX A Uring -55 +KPX A V -135 +KPX A W -90 +KPX A Y -105 +KPX A Yacute -105 +KPX A Ydieresis -105 +KPX A quoteright -111 +KPX A v -74 +KPX A w -92 +KPX A y -92 +KPX A yacute -92 +KPX A ydieresis -92 +KPX Aacute C -40 +KPX Aacute Cacute -40 +KPX Aacute Ccaron -40 +KPX Aacute Ccedilla -40 +KPX Aacute G -40 +KPX Aacute Gbreve -40 +KPX Aacute Gcommaaccent -40 +KPX Aacute O -55 +KPX Aacute Oacute -55 +KPX Aacute Ocircumflex -55 +KPX Aacute Odieresis -55 +KPX Aacute Ograve -55 +KPX Aacute Ohungarumlaut -55 +KPX Aacute Omacron -55 +KPX Aacute Oslash -55 +KPX Aacute Otilde -55 +KPX Aacute Q -55 +KPX Aacute T -111 +KPX Aacute Tcaron -111 +KPX Aacute Tcommaaccent -111 +KPX Aacute U -55 +KPX Aacute Uacute -55 +KPX Aacute Ucircumflex -55 +KPX Aacute Udieresis -55 +KPX Aacute Ugrave -55 +KPX Aacute Uhungarumlaut -55 +KPX Aacute Umacron -55 +KPX Aacute Uogonek -55 +KPX Aacute Uring -55 +KPX Aacute V -135 +KPX Aacute W -90 +KPX Aacute Y -105 +KPX Aacute Yacute -105 +KPX Aacute Ydieresis -105 +KPX Aacute quoteright -111 +KPX Aacute v -74 +KPX Aacute w -92 +KPX Aacute y -92 +KPX Aacute yacute -92 +KPX Aacute ydieresis -92 +KPX Abreve C -40 +KPX Abreve Cacute -40 +KPX Abreve Ccaron -40 +KPX Abreve Ccedilla -40 +KPX Abreve G -40 +KPX Abreve Gbreve -40 +KPX Abreve Gcommaaccent -40 +KPX Abreve O -55 +KPX Abreve Oacute -55 +KPX Abreve Ocircumflex -55 +KPX Abreve Odieresis -55 +KPX Abreve Ograve -55 +KPX Abreve Ohungarumlaut -55 +KPX Abreve Omacron -55 +KPX Abreve Oslash -55 +KPX Abreve Otilde -55 +KPX Abreve Q -55 +KPX Abreve T -111 +KPX Abreve Tcaron -111 +KPX Abreve Tcommaaccent -111 +KPX Abreve U -55 +KPX Abreve Uacute -55 +KPX Abreve Ucircumflex -55 +KPX Abreve Udieresis -55 +KPX Abreve Ugrave -55 +KPX Abreve Uhungarumlaut -55 +KPX Abreve Umacron -55 +KPX Abreve Uogonek -55 +KPX Abreve Uring -55 +KPX Abreve V -135 +KPX Abreve W -90 +KPX Abreve Y -105 +KPX Abreve Yacute -105 +KPX Abreve Ydieresis -105 +KPX Abreve quoteright -111 +KPX Abreve v -74 +KPX Abreve w -92 +KPX Abreve y -92 +KPX Abreve yacute -92 +KPX Abreve ydieresis -92 +KPX Acircumflex C -40 +KPX Acircumflex Cacute -40 +KPX Acircumflex Ccaron -40 +KPX Acircumflex Ccedilla -40 +KPX Acircumflex G -40 +KPX Acircumflex Gbreve -40 +KPX Acircumflex Gcommaaccent -40 +KPX Acircumflex O -55 +KPX Acircumflex Oacute -55 +KPX Acircumflex Ocircumflex -55 +KPX Acircumflex Odieresis -55 +KPX Acircumflex Ograve -55 +KPX Acircumflex Ohungarumlaut -55 +KPX Acircumflex Omacron -55 +KPX Acircumflex Oslash -55 +KPX Acircumflex Otilde -55 +KPX Acircumflex Q -55 +KPX Acircumflex T -111 +KPX Acircumflex Tcaron -111 +KPX Acircumflex Tcommaaccent -111 +KPX Acircumflex U -55 +KPX Acircumflex Uacute -55 +KPX Acircumflex Ucircumflex -55 +KPX Acircumflex Udieresis -55 +KPX Acircumflex Ugrave -55 +KPX Acircumflex Uhungarumlaut -55 +KPX Acircumflex Umacron -55 +KPX Acircumflex Uogonek -55 +KPX Acircumflex Uring -55 +KPX Acircumflex V -135 +KPX Acircumflex W -90 +KPX Acircumflex Y -105 +KPX Acircumflex Yacute -105 +KPX Acircumflex Ydieresis -105 +KPX Acircumflex quoteright -111 +KPX Acircumflex v -74 +KPX Acircumflex w -92 +KPX Acircumflex y -92 +KPX Acircumflex yacute -92 +KPX Acircumflex ydieresis -92 +KPX Adieresis C -40 +KPX Adieresis Cacute -40 +KPX Adieresis Ccaron -40 +KPX Adieresis Ccedilla -40 +KPX Adieresis G -40 +KPX Adieresis Gbreve -40 +KPX Adieresis Gcommaaccent -40 +KPX Adieresis O -55 +KPX Adieresis Oacute -55 +KPX Adieresis Ocircumflex -55 +KPX Adieresis Odieresis -55 +KPX Adieresis Ograve -55 +KPX Adieresis Ohungarumlaut -55 +KPX Adieresis Omacron -55 +KPX Adieresis Oslash -55 +KPX Adieresis Otilde -55 +KPX Adieresis Q -55 +KPX Adieresis T -111 +KPX Adieresis Tcaron -111 +KPX Adieresis Tcommaaccent -111 +KPX Adieresis U -55 +KPX Adieresis Uacute -55 +KPX Adieresis Ucircumflex -55 +KPX Adieresis Udieresis -55 +KPX Adieresis Ugrave -55 +KPX Adieresis Uhungarumlaut -55 +KPX Adieresis Umacron -55 +KPX Adieresis Uogonek -55 +KPX Adieresis Uring -55 +KPX Adieresis V -135 +KPX Adieresis W -90 +KPX Adieresis Y -105 +KPX Adieresis Yacute -105 +KPX Adieresis Ydieresis -105 +KPX Adieresis quoteright -111 +KPX Adieresis v -74 +KPX Adieresis w -92 +KPX Adieresis y -92 +KPX Adieresis yacute -92 +KPX Adieresis ydieresis -92 +KPX Agrave C -40 +KPX Agrave Cacute -40 +KPX Agrave Ccaron -40 +KPX Agrave Ccedilla -40 +KPX Agrave G -40 +KPX Agrave Gbreve -40 +KPX Agrave Gcommaaccent -40 +KPX Agrave O -55 +KPX Agrave Oacute -55 +KPX Agrave Ocircumflex -55 +KPX Agrave Odieresis -55 +KPX Agrave Ograve -55 +KPX Agrave Ohungarumlaut -55 +KPX Agrave Omacron -55 +KPX Agrave Oslash -55 +KPX Agrave Otilde -55 +KPX Agrave Q -55 +KPX Agrave T -111 +KPX Agrave Tcaron -111 +KPX Agrave Tcommaaccent -111 +KPX Agrave U -55 +KPX Agrave Uacute -55 +KPX Agrave Ucircumflex -55 +KPX Agrave Udieresis -55 +KPX Agrave Ugrave -55 +KPX Agrave Uhungarumlaut -55 +KPX Agrave Umacron -55 +KPX Agrave Uogonek -55 +KPX Agrave Uring -55 +KPX Agrave V -135 +KPX Agrave W -90 +KPX Agrave Y -105 +KPX Agrave Yacute -105 +KPX Agrave Ydieresis -105 +KPX Agrave quoteright -111 +KPX Agrave v -74 +KPX Agrave w -92 +KPX Agrave y -92 +KPX Agrave yacute -92 +KPX Agrave ydieresis -92 +KPX Amacron C -40 +KPX Amacron Cacute -40 +KPX Amacron Ccaron -40 +KPX Amacron Ccedilla -40 +KPX Amacron G -40 +KPX Amacron Gbreve -40 +KPX Amacron Gcommaaccent -40 +KPX Amacron O -55 +KPX Amacron Oacute -55 +KPX Amacron Ocircumflex -55 +KPX Amacron Odieresis -55 +KPX Amacron Ograve -55 +KPX Amacron Ohungarumlaut -55 +KPX Amacron Omacron -55 +KPX Amacron Oslash -55 +KPX Amacron Otilde -55 +KPX Amacron Q -55 +KPX Amacron T -111 +KPX Amacron Tcaron -111 +KPX Amacron Tcommaaccent -111 +KPX Amacron U -55 +KPX Amacron Uacute -55 +KPX Amacron Ucircumflex -55 +KPX Amacron Udieresis -55 +KPX Amacron Ugrave -55 +KPX Amacron Uhungarumlaut -55 +KPX Amacron Umacron -55 +KPX Amacron Uogonek -55 +KPX Amacron Uring -55 +KPX Amacron V -135 +KPX Amacron W -90 +KPX Amacron Y -105 +KPX Amacron Yacute -105 +KPX Amacron Ydieresis -105 +KPX Amacron quoteright -111 +KPX Amacron v -74 +KPX Amacron w -92 +KPX Amacron y -92 +KPX Amacron yacute -92 +KPX Amacron ydieresis -92 +KPX Aogonek C -40 +KPX Aogonek Cacute -40 +KPX Aogonek Ccaron -40 +KPX Aogonek Ccedilla -40 +KPX Aogonek G -40 +KPX Aogonek Gbreve -40 +KPX Aogonek Gcommaaccent -40 +KPX Aogonek O -55 +KPX Aogonek Oacute -55 +KPX Aogonek Ocircumflex -55 +KPX Aogonek Odieresis -55 +KPX Aogonek Ograve -55 +KPX Aogonek Ohungarumlaut -55 +KPX Aogonek Omacron -55 +KPX Aogonek Oslash -55 +KPX Aogonek Otilde -55 +KPX Aogonek Q -55 +KPX Aogonek T -111 +KPX Aogonek Tcaron -111 +KPX Aogonek Tcommaaccent -111 +KPX Aogonek U -55 +KPX Aogonek Uacute -55 +KPX Aogonek Ucircumflex -55 +KPX Aogonek Udieresis -55 +KPX Aogonek Ugrave -55 +KPX Aogonek Uhungarumlaut -55 +KPX Aogonek Umacron -55 +KPX Aogonek Uogonek -55 +KPX Aogonek Uring -55 +KPX Aogonek V -135 +KPX Aogonek W -90 +KPX Aogonek Y -105 +KPX Aogonek Yacute -105 +KPX Aogonek Ydieresis -105 +KPX Aogonek quoteright -111 +KPX Aogonek v -74 +KPX Aogonek w -52 +KPX Aogonek y -52 +KPX Aogonek yacute -52 +KPX Aogonek ydieresis -52 +KPX Aring C -40 +KPX Aring Cacute -40 +KPX Aring Ccaron -40 +KPX Aring Ccedilla -40 +KPX Aring G -40 +KPX Aring Gbreve -40 +KPX Aring Gcommaaccent -40 +KPX Aring O -55 +KPX Aring Oacute -55 +KPX Aring Ocircumflex -55 +KPX Aring Odieresis -55 +KPX Aring Ograve -55 +KPX Aring Ohungarumlaut -55 +KPX Aring Omacron -55 +KPX Aring Oslash -55 +KPX Aring Otilde -55 +KPX Aring Q -55 +KPX Aring T -111 +KPX Aring Tcaron -111 +KPX Aring Tcommaaccent -111 +KPX Aring U -55 +KPX Aring Uacute -55 +KPX Aring Ucircumflex -55 +KPX Aring Udieresis -55 +KPX Aring Ugrave -55 +KPX Aring Uhungarumlaut -55 +KPX Aring Umacron -55 +KPX Aring Uogonek -55 +KPX Aring Uring -55 +KPX Aring V -135 +KPX Aring W -90 +KPX Aring Y -105 +KPX Aring Yacute -105 +KPX Aring Ydieresis -105 +KPX Aring quoteright -111 +KPX Aring v -74 +KPX Aring w -92 +KPX Aring y -92 +KPX Aring yacute -92 +KPX Aring ydieresis -92 +KPX Atilde C -40 +KPX Atilde Cacute -40 +KPX Atilde Ccaron -40 +KPX Atilde Ccedilla -40 +KPX Atilde G -40 +KPX Atilde Gbreve -40 +KPX Atilde Gcommaaccent -40 +KPX Atilde O -55 +KPX Atilde Oacute -55 +KPX Atilde Ocircumflex -55 +KPX Atilde Odieresis -55 +KPX Atilde Ograve -55 +KPX Atilde Ohungarumlaut -55 +KPX Atilde Omacron -55 +KPX Atilde Oslash -55 +KPX Atilde Otilde -55 +KPX Atilde Q -55 +KPX Atilde T -111 +KPX Atilde Tcaron -111 +KPX Atilde Tcommaaccent -111 +KPX Atilde U -55 +KPX Atilde Uacute -55 +KPX Atilde Ucircumflex -55 +KPX Atilde Udieresis -55 +KPX Atilde Ugrave -55 +KPX Atilde Uhungarumlaut -55 +KPX Atilde Umacron -55 +KPX Atilde Uogonek -55 +KPX Atilde Uring -55 +KPX Atilde V -135 +KPX Atilde W -90 +KPX Atilde Y -105 +KPX Atilde Yacute -105 +KPX Atilde Ydieresis -105 +KPX Atilde quoteright -111 +KPX Atilde v -74 +KPX Atilde w -92 +KPX Atilde y -92 +KPX Atilde yacute -92 +KPX Atilde ydieresis -92 +KPX B A -35 +KPX B Aacute -35 +KPX B Abreve -35 +KPX B Acircumflex -35 +KPX B Adieresis -35 +KPX B Agrave -35 +KPX B Amacron -35 +KPX B Aogonek -35 +KPX B Aring -35 +KPX B Atilde -35 +KPX B U -10 +KPX B Uacute -10 +KPX B Ucircumflex -10 +KPX B Udieresis -10 +KPX B Ugrave -10 +KPX B Uhungarumlaut -10 +KPX B Umacron -10 +KPX B Uogonek -10 +KPX B Uring -10 +KPX D A -40 +KPX D Aacute -40 +KPX D Abreve -40 +KPX D Acircumflex -40 +KPX D Adieresis -40 +KPX D Agrave -40 +KPX D Amacron -40 +KPX D Aogonek -40 +KPX D Aring -40 +KPX D Atilde -40 +KPX D V -40 +KPX D W -30 +KPX D Y -55 +KPX D Yacute -55 +KPX D Ydieresis -55 +KPX Dcaron A -40 +KPX Dcaron Aacute -40 +KPX Dcaron Abreve -40 +KPX Dcaron Acircumflex -40 +KPX Dcaron Adieresis -40 +KPX Dcaron Agrave -40 +KPX Dcaron Amacron -40 +KPX Dcaron Aogonek -40 +KPX Dcaron Aring -40 +KPX Dcaron Atilde -40 +KPX Dcaron V -40 +KPX Dcaron W -30 +KPX Dcaron Y -55 +KPX Dcaron Yacute -55 +KPX Dcaron Ydieresis -55 +KPX Dcroat A -40 +KPX Dcroat Aacute -40 +KPX Dcroat Abreve -40 +KPX Dcroat Acircumflex -40 +KPX Dcroat Adieresis -40 +KPX Dcroat Agrave -40 +KPX Dcroat Amacron -40 +KPX Dcroat Aogonek -40 +KPX Dcroat Aring -40 +KPX Dcroat Atilde -40 +KPX Dcroat V -40 +KPX Dcroat W -30 +KPX Dcroat Y -55 +KPX Dcroat Yacute -55 +KPX Dcroat Ydieresis -55 +KPX F A -74 +KPX F Aacute -74 +KPX F Abreve -74 +KPX F Acircumflex -74 +KPX F Adieresis -74 +KPX F Agrave -74 +KPX F Amacron -74 +KPX F Aogonek -74 +KPX F Aring -74 +KPX F Atilde -74 +KPX F a -15 +KPX F aacute -15 +KPX F abreve -15 +KPX F acircumflex -15 +KPX F adieresis -15 +KPX F agrave -15 +KPX F amacron -15 +KPX F aogonek -15 +KPX F aring -15 +KPX F atilde -15 +KPX F comma -80 +KPX F o -15 +KPX F oacute -15 +KPX F ocircumflex -15 +KPX F odieresis -15 +KPX F ograve -15 +KPX F ohungarumlaut -15 +KPX F omacron -15 +KPX F oslash -15 +KPX F otilde -15 +KPX F period -80 +KPX J A -60 +KPX J Aacute -60 +KPX J Abreve -60 +KPX J Acircumflex -60 +KPX J Adieresis -60 +KPX J Agrave -60 +KPX J Amacron -60 +KPX J Aogonek -60 +KPX J Aring -60 +KPX J Atilde -60 +KPX K O -30 +KPX K Oacute -30 +KPX K Ocircumflex -30 +KPX K Odieresis -30 +KPX K Ograve -30 +KPX K Ohungarumlaut -30 +KPX K Omacron -30 +KPX K Oslash -30 +KPX K Otilde -30 +KPX K e -25 +KPX K eacute -25 +KPX K ecaron -25 +KPX K ecircumflex -25 +KPX K edieresis -25 +KPX K edotaccent -25 +KPX K egrave -25 +KPX K emacron -25 +KPX K eogonek -25 +KPX K o -35 +KPX K oacute -35 +KPX K ocircumflex -35 +KPX K odieresis -35 +KPX K ograve -35 +KPX K ohungarumlaut -35 +KPX K omacron -35 +KPX K oslash -35 +KPX K otilde -35 +KPX K u -15 +KPX K uacute -15 +KPX K ucircumflex -15 +KPX K udieresis -15 +KPX K ugrave -15 +KPX K uhungarumlaut -15 +KPX K umacron -15 +KPX K uogonek -15 +KPX K uring -15 +KPX K y -25 +KPX K yacute -25 +KPX K ydieresis -25 +KPX Kcommaaccent O -30 +KPX Kcommaaccent Oacute -30 +KPX Kcommaaccent Ocircumflex -30 +KPX Kcommaaccent Odieresis -30 +KPX Kcommaaccent Ograve -30 +KPX Kcommaaccent Ohungarumlaut -30 +KPX Kcommaaccent Omacron -30 +KPX Kcommaaccent Oslash -30 +KPX Kcommaaccent Otilde -30 +KPX Kcommaaccent e -25 +KPX Kcommaaccent eacute -25 +KPX Kcommaaccent ecaron -25 +KPX Kcommaaccent ecircumflex -25 +KPX Kcommaaccent edieresis -25 +KPX Kcommaaccent edotaccent -25 +KPX Kcommaaccent egrave -25 +KPX Kcommaaccent emacron -25 +KPX Kcommaaccent eogonek -25 +KPX Kcommaaccent o -35 +KPX Kcommaaccent oacute -35 +KPX Kcommaaccent ocircumflex -35 +KPX Kcommaaccent odieresis -35 +KPX Kcommaaccent ograve -35 +KPX Kcommaaccent ohungarumlaut -35 +KPX Kcommaaccent omacron -35 +KPX Kcommaaccent oslash -35 +KPX Kcommaaccent otilde -35 +KPX Kcommaaccent u -15 +KPX Kcommaaccent uacute -15 +KPX Kcommaaccent ucircumflex -15 +KPX Kcommaaccent udieresis -15 +KPX Kcommaaccent ugrave -15 +KPX Kcommaaccent uhungarumlaut -15 +KPX Kcommaaccent umacron -15 +KPX Kcommaaccent uogonek -15 +KPX Kcommaaccent uring -15 +KPX Kcommaaccent y -25 +KPX Kcommaaccent yacute -25 +KPX Kcommaaccent ydieresis -25 +KPX L T -92 +KPX L Tcaron -92 +KPX L Tcommaaccent -92 +KPX L V -100 +KPX L W -74 +KPX L Y -100 +KPX L Yacute -100 +KPX L Ydieresis -100 +KPX L quoteright -92 +KPX L y -55 +KPX L yacute -55 +KPX L ydieresis -55 +KPX Lacute T -92 +KPX Lacute Tcaron -92 +KPX Lacute Tcommaaccent -92 +KPX Lacute V -100 +KPX Lacute W -74 +KPX Lacute Y -100 +KPX Lacute Yacute -100 +KPX Lacute Ydieresis -100 +KPX Lacute quoteright -92 +KPX Lacute y -55 +KPX Lacute yacute -55 +KPX Lacute ydieresis -55 +KPX Lcaron quoteright -92 +KPX Lcaron y -55 +KPX Lcaron yacute -55 +KPX Lcaron ydieresis -55 +KPX Lcommaaccent T -92 +KPX Lcommaaccent Tcaron -92 +KPX Lcommaaccent Tcommaaccent -92 +KPX Lcommaaccent V -100 +KPX Lcommaaccent W -74 +KPX Lcommaaccent Y -100 +KPX Lcommaaccent Yacute -100 +KPX Lcommaaccent Ydieresis -100 +KPX Lcommaaccent quoteright -92 +KPX Lcommaaccent y -55 +KPX Lcommaaccent yacute -55 +KPX Lcommaaccent ydieresis -55 +KPX Lslash T -92 +KPX Lslash Tcaron -92 +KPX Lslash Tcommaaccent -92 +KPX Lslash V -100 +KPX Lslash W -74 +KPX Lslash Y -100 +KPX Lslash Yacute -100 +KPX Lslash Ydieresis -100 +KPX Lslash quoteright -92 +KPX Lslash y -55 +KPX Lslash yacute -55 +KPX Lslash ydieresis -55 +KPX N A -35 +KPX N Aacute -35 +KPX N Abreve -35 +KPX N Acircumflex -35 +KPX N Adieresis -35 +KPX N Agrave -35 +KPX N Amacron -35 +KPX N Aogonek -35 +KPX N Aring -35 +KPX N Atilde -35 +KPX Nacute A -35 +KPX Nacute Aacute -35 +KPX Nacute Abreve -35 +KPX Nacute Acircumflex -35 +KPX Nacute Adieresis -35 +KPX Nacute Agrave -35 +KPX Nacute Amacron -35 +KPX Nacute Aogonek -35 +KPX Nacute Aring -35 +KPX Nacute Atilde -35 +KPX Ncaron A -35 +KPX Ncaron Aacute -35 +KPX Ncaron Abreve -35 +KPX Ncaron Acircumflex -35 +KPX Ncaron Adieresis -35 +KPX Ncaron Agrave -35 +KPX Ncaron Amacron -35 +KPX Ncaron Aogonek -35 +KPX Ncaron Aring -35 +KPX Ncaron Atilde -35 +KPX Ncommaaccent A -35 +KPX Ncommaaccent Aacute -35 +KPX Ncommaaccent Abreve -35 +KPX Ncommaaccent Acircumflex -35 +KPX Ncommaaccent Adieresis -35 +KPX Ncommaaccent Agrave -35 +KPX Ncommaaccent Amacron -35 +KPX Ncommaaccent Aogonek -35 +KPX Ncommaaccent Aring -35 +KPX Ncommaaccent Atilde -35 +KPX Ntilde A -35 +KPX Ntilde Aacute -35 +KPX Ntilde Abreve -35 +KPX Ntilde Acircumflex -35 +KPX Ntilde Adieresis -35 +KPX Ntilde Agrave -35 +KPX Ntilde Amacron -35 +KPX Ntilde Aogonek -35 +KPX Ntilde Aring -35 +KPX Ntilde Atilde -35 +KPX O A -35 +KPX O Aacute -35 +KPX O Abreve -35 +KPX O Acircumflex -35 +KPX O Adieresis -35 +KPX O Agrave -35 +KPX O Amacron -35 +KPX O Aogonek -35 +KPX O Aring -35 +KPX O Atilde -35 +KPX O T -40 +KPX O Tcaron -40 +KPX O Tcommaaccent -40 +KPX O V -50 +KPX O W -35 +KPX O X -40 +KPX O Y -50 +KPX O Yacute -50 +KPX O Ydieresis -50 +KPX Oacute A -35 +KPX Oacute Aacute -35 +KPX Oacute Abreve -35 +KPX Oacute Acircumflex -35 +KPX Oacute Adieresis -35 +KPX Oacute Agrave -35 +KPX Oacute Amacron -35 +KPX Oacute Aogonek -35 +KPX Oacute Aring -35 +KPX Oacute Atilde -35 +KPX Oacute T -40 +KPX Oacute Tcaron -40 +KPX Oacute Tcommaaccent -40 +KPX Oacute V -50 +KPX Oacute W -35 +KPX Oacute X -40 +KPX Oacute Y -50 +KPX Oacute Yacute -50 +KPX Oacute Ydieresis -50 +KPX Ocircumflex A -35 +KPX Ocircumflex Aacute -35 +KPX Ocircumflex Abreve -35 +KPX Ocircumflex Acircumflex -35 +KPX Ocircumflex Adieresis -35 +KPX Ocircumflex Agrave -35 +KPX Ocircumflex Amacron -35 +KPX Ocircumflex Aogonek -35 +KPX Ocircumflex Aring -35 +KPX Ocircumflex Atilde -35 +KPX Ocircumflex T -40 +KPX Ocircumflex Tcaron -40 +KPX Ocircumflex Tcommaaccent -40 +KPX Ocircumflex V -50 +KPX Ocircumflex W -35 +KPX Ocircumflex X -40 +KPX Ocircumflex Y -50 +KPX Ocircumflex Yacute -50 +KPX Ocircumflex Ydieresis -50 +KPX Odieresis A -35 +KPX Odieresis Aacute -35 +KPX Odieresis Abreve -35 +KPX Odieresis Acircumflex -35 +KPX Odieresis Adieresis -35 +KPX Odieresis Agrave -35 +KPX Odieresis Amacron -35 +KPX Odieresis Aogonek -35 +KPX Odieresis Aring -35 +KPX Odieresis Atilde -35 +KPX Odieresis T -40 +KPX Odieresis Tcaron -40 +KPX Odieresis Tcommaaccent -40 +KPX Odieresis V -50 +KPX Odieresis W -35 +KPX Odieresis X -40 +KPX Odieresis Y -50 +KPX Odieresis Yacute -50 +KPX Odieresis Ydieresis -50 +KPX Ograve A -35 +KPX Ograve Aacute -35 +KPX Ograve Abreve -35 +KPX Ograve Acircumflex -35 +KPX Ograve Adieresis -35 +KPX Ograve Agrave -35 +KPX Ograve Amacron -35 +KPX Ograve Aogonek -35 +KPX Ograve Aring -35 +KPX Ograve Atilde -35 +KPX Ograve T -40 +KPX Ograve Tcaron -40 +KPX Ograve Tcommaaccent -40 +KPX Ograve V -50 +KPX Ograve W -35 +KPX Ograve X -40 +KPX Ograve Y -50 +KPX Ograve Yacute -50 +KPX Ograve Ydieresis -50 +KPX Ohungarumlaut A -35 +KPX Ohungarumlaut Aacute -35 +KPX Ohungarumlaut Abreve -35 +KPX Ohungarumlaut Acircumflex -35 +KPX Ohungarumlaut Adieresis -35 +KPX Ohungarumlaut Agrave -35 +KPX Ohungarumlaut Amacron -35 +KPX Ohungarumlaut Aogonek -35 +KPX Ohungarumlaut Aring -35 +KPX Ohungarumlaut Atilde -35 +KPX Ohungarumlaut T -40 +KPX Ohungarumlaut Tcaron -40 +KPX Ohungarumlaut Tcommaaccent -40 +KPX Ohungarumlaut V -50 +KPX Ohungarumlaut W -35 +KPX Ohungarumlaut X -40 +KPX Ohungarumlaut Y -50 +KPX Ohungarumlaut Yacute -50 +KPX Ohungarumlaut Ydieresis -50 +KPX Omacron A -35 +KPX Omacron Aacute -35 +KPX Omacron Abreve -35 +KPX Omacron Acircumflex -35 +KPX Omacron Adieresis -35 +KPX Omacron Agrave -35 +KPX Omacron Amacron -35 +KPX Omacron Aogonek -35 +KPX Omacron Aring -35 +KPX Omacron Atilde -35 +KPX Omacron T -40 +KPX Omacron Tcaron -40 +KPX Omacron Tcommaaccent -40 +KPX Omacron V -50 +KPX Omacron W -35 +KPX Omacron X -40 +KPX Omacron Y -50 +KPX Omacron Yacute -50 +KPX Omacron Ydieresis -50 +KPX Oslash A -35 +KPX Oslash Aacute -35 +KPX Oslash Abreve -35 +KPX Oslash Acircumflex -35 +KPX Oslash Adieresis -35 +KPX Oslash Agrave -35 +KPX Oslash Amacron -35 +KPX Oslash Aogonek -35 +KPX Oslash Aring -35 +KPX Oslash Atilde -35 +KPX Oslash T -40 +KPX Oslash Tcaron -40 +KPX Oslash Tcommaaccent -40 +KPX Oslash V -50 +KPX Oslash W -35 +KPX Oslash X -40 +KPX Oslash Y -50 +KPX Oslash Yacute -50 +KPX Oslash Ydieresis -50 +KPX Otilde A -35 +KPX Otilde Aacute -35 +KPX Otilde Abreve -35 +KPX Otilde Acircumflex -35 +KPX Otilde Adieresis -35 +KPX Otilde Agrave -35 +KPX Otilde Amacron -35 +KPX Otilde Aogonek -35 +KPX Otilde Aring -35 +KPX Otilde Atilde -35 +KPX Otilde T -40 +KPX Otilde Tcaron -40 +KPX Otilde Tcommaaccent -40 +KPX Otilde V -50 +KPX Otilde W -35 +KPX Otilde X -40 +KPX Otilde Y -50 +KPX Otilde Yacute -50 +KPX Otilde Ydieresis -50 +KPX P A -92 +KPX P Aacute -92 +KPX P Abreve -92 +KPX P Acircumflex -92 +KPX P Adieresis -92 +KPX P Agrave -92 +KPX P Amacron -92 +KPX P Aogonek -92 +KPX P Aring -92 +KPX P Atilde -92 +KPX P a -15 +KPX P aacute -15 +KPX P abreve -15 +KPX P acircumflex -15 +KPX P adieresis -15 +KPX P agrave -15 +KPX P amacron -15 +KPX P aogonek -15 +KPX P aring -15 +KPX P atilde -15 +KPX P comma -111 +KPX P period -111 +KPX Q U -10 +KPX Q Uacute -10 +KPX Q Ucircumflex -10 +KPX Q Udieresis -10 +KPX Q Ugrave -10 +KPX Q Uhungarumlaut -10 +KPX Q Umacron -10 +KPX Q Uogonek -10 +KPX Q Uring -10 +KPX R O -40 +KPX R Oacute -40 +KPX R Ocircumflex -40 +KPX R Odieresis -40 +KPX R Ograve -40 +KPX R Ohungarumlaut -40 +KPX R Omacron -40 +KPX R Oslash -40 +KPX R Otilde -40 +KPX R T -60 +KPX R Tcaron -60 +KPX R Tcommaaccent -60 +KPX R U -40 +KPX R Uacute -40 +KPX R Ucircumflex -40 +KPX R Udieresis -40 +KPX R Ugrave -40 +KPX R Uhungarumlaut -40 +KPX R Umacron -40 +KPX R Uogonek -40 +KPX R Uring -40 +KPX R V -80 +KPX R W -55 +KPX R Y -65 +KPX R Yacute -65 +KPX R Ydieresis -65 +KPX Racute O -40 +KPX Racute Oacute -40 +KPX Racute Ocircumflex -40 +KPX Racute Odieresis -40 +KPX Racute Ograve -40 +KPX Racute Ohungarumlaut -40 +KPX Racute Omacron -40 +KPX Racute Oslash -40 +KPX Racute Otilde -40 +KPX Racute T -60 +KPX Racute Tcaron -60 +KPX Racute Tcommaaccent -60 +KPX Racute U -40 +KPX Racute Uacute -40 +KPX Racute Ucircumflex -40 +KPX Racute Udieresis -40 +KPX Racute Ugrave -40 +KPX Racute Uhungarumlaut -40 +KPX Racute Umacron -40 +KPX Racute Uogonek -40 +KPX Racute Uring -40 +KPX Racute V -80 +KPX Racute W -55 +KPX Racute Y -65 +KPX Racute Yacute -65 +KPX Racute Ydieresis -65 +KPX Rcaron O -40 +KPX Rcaron Oacute -40 +KPX Rcaron Ocircumflex -40 +KPX Rcaron Odieresis -40 +KPX Rcaron Ograve -40 +KPX Rcaron Ohungarumlaut -40 +KPX Rcaron Omacron -40 +KPX Rcaron Oslash -40 +KPX Rcaron Otilde -40 +KPX Rcaron T -60 +KPX Rcaron Tcaron -60 +KPX Rcaron Tcommaaccent -60 +KPX Rcaron U -40 +KPX Rcaron Uacute -40 +KPX Rcaron Ucircumflex -40 +KPX Rcaron Udieresis -40 +KPX Rcaron Ugrave -40 +KPX Rcaron Uhungarumlaut -40 +KPX Rcaron Umacron -40 +KPX Rcaron Uogonek -40 +KPX Rcaron Uring -40 +KPX Rcaron V -80 +KPX Rcaron W -55 +KPX Rcaron Y -65 +KPX Rcaron Yacute -65 +KPX Rcaron Ydieresis -65 +KPX Rcommaaccent O -40 +KPX Rcommaaccent Oacute -40 +KPX Rcommaaccent Ocircumflex -40 +KPX Rcommaaccent Odieresis -40 +KPX Rcommaaccent Ograve -40 +KPX Rcommaaccent Ohungarumlaut -40 +KPX Rcommaaccent Omacron -40 +KPX Rcommaaccent Oslash -40 +KPX Rcommaaccent Otilde -40 +KPX Rcommaaccent T -60 +KPX Rcommaaccent Tcaron -60 +KPX Rcommaaccent Tcommaaccent -60 +KPX Rcommaaccent U -40 +KPX Rcommaaccent Uacute -40 +KPX Rcommaaccent Ucircumflex -40 +KPX Rcommaaccent Udieresis -40 +KPX Rcommaaccent Ugrave -40 +KPX Rcommaaccent Uhungarumlaut -40 +KPX Rcommaaccent Umacron -40 +KPX Rcommaaccent Uogonek -40 +KPX Rcommaaccent Uring -40 +KPX Rcommaaccent V -80 +KPX Rcommaaccent W -55 +KPX Rcommaaccent Y -65 +KPX Rcommaaccent Yacute -65 +KPX Rcommaaccent Ydieresis -65 +KPX T A -93 +KPX T Aacute -93 +KPX T Abreve -93 +KPX T Acircumflex -93 +KPX T Adieresis -93 +KPX T Agrave -93 +KPX T Amacron -93 +KPX T Aogonek -93 +KPX T Aring -93 +KPX T Atilde -93 +KPX T O -18 +KPX T Oacute -18 +KPX T Ocircumflex -18 +KPX T Odieresis -18 +KPX T Ograve -18 +KPX T Ohungarumlaut -18 +KPX T Omacron -18 +KPX T Oslash -18 +KPX T Otilde -18 +KPX T a -80 +KPX T aacute -80 +KPX T abreve -80 +KPX T acircumflex -80 +KPX T adieresis -40 +KPX T agrave -40 +KPX T amacron -40 +KPX T aogonek -80 +KPX T aring -80 +KPX T atilde -40 +KPX T colon -50 +KPX T comma -74 +KPX T e -70 +KPX T eacute -70 +KPX T ecaron -70 +KPX T ecircumflex -70 +KPX T edieresis -30 +KPX T edotaccent -70 +KPX T egrave -70 +KPX T emacron -30 +KPX T eogonek -70 +KPX T hyphen -92 +KPX T i -35 +KPX T iacute -35 +KPX T iogonek -35 +KPX T o -80 +KPX T oacute -80 +KPX T ocircumflex -80 +KPX T odieresis -80 +KPX T ograve -80 +KPX T ohungarumlaut -80 +KPX T omacron -80 +KPX T oslash -80 +KPX T otilde -80 +KPX T period -74 +KPX T r -35 +KPX T racute -35 +KPX T rcaron -35 +KPX T rcommaaccent -35 +KPX T semicolon -55 +KPX T u -45 +KPX T uacute -45 +KPX T ucircumflex -45 +KPX T udieresis -45 +KPX T ugrave -45 +KPX T uhungarumlaut -45 +KPX T umacron -45 +KPX T uogonek -45 +KPX T uring -45 +KPX T w -80 +KPX T y -80 +KPX T yacute -80 +KPX T ydieresis -80 +KPX Tcaron A -93 +KPX Tcaron Aacute -93 +KPX Tcaron Abreve -93 +KPX Tcaron Acircumflex -93 +KPX Tcaron Adieresis -93 +KPX Tcaron Agrave -93 +KPX Tcaron Amacron -93 +KPX Tcaron Aogonek -93 +KPX Tcaron Aring -93 +KPX Tcaron Atilde -93 +KPX Tcaron O -18 +KPX Tcaron Oacute -18 +KPX Tcaron Ocircumflex -18 +KPX Tcaron Odieresis -18 +KPX Tcaron Ograve -18 +KPX Tcaron Ohungarumlaut -18 +KPX Tcaron Omacron -18 +KPX Tcaron Oslash -18 +KPX Tcaron Otilde -18 +KPX Tcaron a -80 +KPX Tcaron aacute -80 +KPX Tcaron abreve -80 +KPX Tcaron acircumflex -80 +KPX Tcaron adieresis -40 +KPX Tcaron agrave -40 +KPX Tcaron amacron -40 +KPX Tcaron aogonek -80 +KPX Tcaron aring -80 +KPX Tcaron atilde -40 +KPX Tcaron colon -50 +KPX Tcaron comma -74 +KPX Tcaron e -70 +KPX Tcaron eacute -70 +KPX Tcaron ecaron -70 +KPX Tcaron ecircumflex -30 +KPX Tcaron edieresis -30 +KPX Tcaron edotaccent -70 +KPX Tcaron egrave -70 +KPX Tcaron emacron -30 +KPX Tcaron eogonek -70 +KPX Tcaron hyphen -92 +KPX Tcaron i -35 +KPX Tcaron iacute -35 +KPX Tcaron iogonek -35 +KPX Tcaron o -80 +KPX Tcaron oacute -80 +KPX Tcaron ocircumflex -80 +KPX Tcaron odieresis -80 +KPX Tcaron ograve -80 +KPX Tcaron ohungarumlaut -80 +KPX Tcaron omacron -80 +KPX Tcaron oslash -80 +KPX Tcaron otilde -80 +KPX Tcaron period -74 +KPX Tcaron r -35 +KPX Tcaron racute -35 +KPX Tcaron rcaron -35 +KPX Tcaron rcommaaccent -35 +KPX Tcaron semicolon -55 +KPX Tcaron u -45 +KPX Tcaron uacute -45 +KPX Tcaron ucircumflex -45 +KPX Tcaron udieresis -45 +KPX Tcaron ugrave -45 +KPX Tcaron uhungarumlaut -45 +KPX Tcaron umacron -45 +KPX Tcaron uogonek -45 +KPX Tcaron uring -45 +KPX Tcaron w -80 +KPX Tcaron y -80 +KPX Tcaron yacute -80 +KPX Tcaron ydieresis -80 +KPX Tcommaaccent A -93 +KPX Tcommaaccent Aacute -93 +KPX Tcommaaccent Abreve -93 +KPX Tcommaaccent Acircumflex -93 +KPX Tcommaaccent Adieresis -93 +KPX Tcommaaccent Agrave -93 +KPX Tcommaaccent Amacron -93 +KPX Tcommaaccent Aogonek -93 +KPX Tcommaaccent Aring -93 +KPX Tcommaaccent Atilde -93 +KPX Tcommaaccent O -18 +KPX Tcommaaccent Oacute -18 +KPX Tcommaaccent Ocircumflex -18 +KPX Tcommaaccent Odieresis -18 +KPX Tcommaaccent Ograve -18 +KPX Tcommaaccent Ohungarumlaut -18 +KPX Tcommaaccent Omacron -18 +KPX Tcommaaccent Oslash -18 +KPX Tcommaaccent Otilde -18 +KPX Tcommaaccent a -80 +KPX Tcommaaccent aacute -80 +KPX Tcommaaccent abreve -80 +KPX Tcommaaccent acircumflex -80 +KPX Tcommaaccent adieresis -40 +KPX Tcommaaccent agrave -40 +KPX Tcommaaccent amacron -40 +KPX Tcommaaccent aogonek -80 +KPX Tcommaaccent aring -80 +KPX Tcommaaccent atilde -40 +KPX Tcommaaccent colon -50 +KPX Tcommaaccent comma -74 +KPX Tcommaaccent e -70 +KPX Tcommaaccent eacute -70 +KPX Tcommaaccent ecaron -70 +KPX Tcommaaccent ecircumflex -30 +KPX Tcommaaccent edieresis -30 +KPX Tcommaaccent edotaccent -70 +KPX Tcommaaccent egrave -30 +KPX Tcommaaccent emacron -70 +KPX Tcommaaccent eogonek -70 +KPX Tcommaaccent hyphen -92 +KPX Tcommaaccent i -35 +KPX Tcommaaccent iacute -35 +KPX Tcommaaccent iogonek -35 +KPX Tcommaaccent o -80 +KPX Tcommaaccent oacute -80 +KPX Tcommaaccent ocircumflex -80 +KPX Tcommaaccent odieresis -80 +KPX Tcommaaccent ograve -80 +KPX Tcommaaccent ohungarumlaut -80 +KPX Tcommaaccent omacron -80 +KPX Tcommaaccent oslash -80 +KPX Tcommaaccent otilde -80 +KPX Tcommaaccent period -74 +KPX Tcommaaccent r -35 +KPX Tcommaaccent racute -35 +KPX Tcommaaccent rcaron -35 +KPX Tcommaaccent rcommaaccent -35 +KPX Tcommaaccent semicolon -55 +KPX Tcommaaccent u -45 +KPX Tcommaaccent uacute -45 +KPX Tcommaaccent ucircumflex -45 +KPX Tcommaaccent udieresis -45 +KPX Tcommaaccent ugrave -45 +KPX Tcommaaccent uhungarumlaut -45 +KPX Tcommaaccent umacron -45 +KPX Tcommaaccent uogonek -45 +KPX Tcommaaccent uring -45 +KPX Tcommaaccent w -80 +KPX Tcommaaccent y -80 +KPX Tcommaaccent yacute -80 +KPX Tcommaaccent ydieresis -80 +KPX U A -40 +KPX U Aacute -40 +KPX U Abreve -40 +KPX U Acircumflex -40 +KPX U Adieresis -40 +KPX U Agrave -40 +KPX U Amacron -40 +KPX U Aogonek -40 +KPX U Aring -40 +KPX U Atilde -40 +KPX Uacute A -40 +KPX Uacute Aacute -40 +KPX Uacute Abreve -40 +KPX Uacute Acircumflex -40 +KPX Uacute Adieresis -40 +KPX Uacute Agrave -40 +KPX Uacute Amacron -40 +KPX Uacute Aogonek -40 +KPX Uacute Aring -40 +KPX Uacute Atilde -40 +KPX Ucircumflex A -40 +KPX Ucircumflex Aacute -40 +KPX Ucircumflex Abreve -40 +KPX Ucircumflex Acircumflex -40 +KPX Ucircumflex Adieresis -40 +KPX Ucircumflex Agrave -40 +KPX Ucircumflex Amacron -40 +KPX Ucircumflex Aogonek -40 +KPX Ucircumflex Aring -40 +KPX Ucircumflex Atilde -40 +KPX Udieresis A -40 +KPX Udieresis Aacute -40 +KPX Udieresis Abreve -40 +KPX Udieresis Acircumflex -40 +KPX Udieresis Adieresis -40 +KPX Udieresis Agrave -40 +KPX Udieresis Amacron -40 +KPX Udieresis Aogonek -40 +KPX Udieresis Aring -40 +KPX Udieresis Atilde -40 +KPX Ugrave A -40 +KPX Ugrave Aacute -40 +KPX Ugrave Abreve -40 +KPX Ugrave Acircumflex -40 +KPX Ugrave Adieresis -40 +KPX Ugrave Agrave -40 +KPX Ugrave Amacron -40 +KPX Ugrave Aogonek -40 +KPX Ugrave Aring -40 +KPX Ugrave Atilde -40 +KPX Uhungarumlaut A -40 +KPX Uhungarumlaut Aacute -40 +KPX Uhungarumlaut Abreve -40 +KPX Uhungarumlaut Acircumflex -40 +KPX Uhungarumlaut Adieresis -40 +KPX Uhungarumlaut Agrave -40 +KPX Uhungarumlaut Amacron -40 +KPX Uhungarumlaut Aogonek -40 +KPX Uhungarumlaut Aring -40 +KPX Uhungarumlaut Atilde -40 +KPX Umacron A -40 +KPX Umacron Aacute -40 +KPX Umacron Abreve -40 +KPX Umacron Acircumflex -40 +KPX Umacron Adieresis -40 +KPX Umacron Agrave -40 +KPX Umacron Amacron -40 +KPX Umacron Aogonek -40 +KPX Umacron Aring -40 +KPX Umacron Atilde -40 +KPX Uogonek A -40 +KPX Uogonek Aacute -40 +KPX Uogonek Abreve -40 +KPX Uogonek Acircumflex -40 +KPX Uogonek Adieresis -40 +KPX Uogonek Agrave -40 +KPX Uogonek Amacron -40 +KPX Uogonek Aogonek -40 +KPX Uogonek Aring -40 +KPX Uogonek Atilde -40 +KPX Uring A -40 +KPX Uring Aacute -40 +KPX Uring Abreve -40 +KPX Uring Acircumflex -40 +KPX Uring Adieresis -40 +KPX Uring Agrave -40 +KPX Uring Amacron -40 +KPX Uring Aogonek -40 +KPX Uring Aring -40 +KPX Uring Atilde -40 +KPX V A -135 +KPX V Aacute -135 +KPX V Abreve -135 +KPX V Acircumflex -135 +KPX V Adieresis -135 +KPX V Agrave -135 +KPX V Amacron -135 +KPX V Aogonek -135 +KPX V Aring -135 +KPX V Atilde -135 +KPX V G -15 +KPX V Gbreve -15 +KPX V Gcommaaccent -15 +KPX V O -40 +KPX V Oacute -40 +KPX V Ocircumflex -40 +KPX V Odieresis -40 +KPX V Ograve -40 +KPX V Ohungarumlaut -40 +KPX V Omacron -40 +KPX V Oslash -40 +KPX V Otilde -40 +KPX V a -111 +KPX V aacute -111 +KPX V abreve -111 +KPX V acircumflex -71 +KPX V adieresis -71 +KPX V agrave -71 +KPX V amacron -71 +KPX V aogonek -111 +KPX V aring -111 +KPX V atilde -71 +KPX V colon -74 +KPX V comma -129 +KPX V e -111 +KPX V eacute -111 +KPX V ecaron -71 +KPX V ecircumflex -71 +KPX V edieresis -71 +KPX V edotaccent -111 +KPX V egrave -71 +KPX V emacron -71 +KPX V eogonek -111 +KPX V hyphen -100 +KPX V i -60 +KPX V iacute -60 +KPX V icircumflex -20 +KPX V idieresis -20 +KPX V igrave -20 +KPX V imacron -20 +KPX V iogonek -60 +KPX V o -129 +KPX V oacute -129 +KPX V ocircumflex -129 +KPX V odieresis -89 +KPX V ograve -89 +KPX V ohungarumlaut -129 +KPX V omacron -89 +KPX V oslash -129 +KPX V otilde -89 +KPX V period -129 +KPX V semicolon -74 +KPX V u -75 +KPX V uacute -75 +KPX V ucircumflex -75 +KPX V udieresis -75 +KPX V ugrave -75 +KPX V uhungarumlaut -75 +KPX V umacron -75 +KPX V uogonek -75 +KPX V uring -75 +KPX W A -120 +KPX W Aacute -120 +KPX W Abreve -120 +KPX W Acircumflex -120 +KPX W Adieresis -120 +KPX W Agrave -120 +KPX W Amacron -120 +KPX W Aogonek -120 +KPX W Aring -120 +KPX W Atilde -120 +KPX W O -10 +KPX W Oacute -10 +KPX W Ocircumflex -10 +KPX W Odieresis -10 +KPX W Ograve -10 +KPX W Ohungarumlaut -10 +KPX W Omacron -10 +KPX W Oslash -10 +KPX W Otilde -10 +KPX W a -80 +KPX W aacute -80 +KPX W abreve -80 +KPX W acircumflex -80 +KPX W adieresis -80 +KPX W agrave -80 +KPX W amacron -80 +KPX W aogonek -80 +KPX W aring -80 +KPX W atilde -80 +KPX W colon -37 +KPX W comma -92 +KPX W e -80 +KPX W eacute -80 +KPX W ecaron -80 +KPX W ecircumflex -80 +KPX W edieresis -40 +KPX W edotaccent -80 +KPX W egrave -40 +KPX W emacron -40 +KPX W eogonek -80 +KPX W hyphen -65 +KPX W i -40 +KPX W iacute -40 +KPX W iogonek -40 +KPX W o -80 +KPX W oacute -80 +KPX W ocircumflex -80 +KPX W odieresis -80 +KPX W ograve -80 +KPX W ohungarumlaut -80 +KPX W omacron -80 +KPX W oslash -80 +KPX W otilde -80 +KPX W period -92 +KPX W semicolon -37 +KPX W u -50 +KPX W uacute -50 +KPX W ucircumflex -50 +KPX W udieresis -50 +KPX W ugrave -50 +KPX W uhungarumlaut -50 +KPX W umacron -50 +KPX W uogonek -50 +KPX W uring -50 +KPX W y -73 +KPX W yacute -73 +KPX W ydieresis -73 +KPX Y A -120 +KPX Y Aacute -120 +KPX Y Abreve -120 +KPX Y Acircumflex -120 +KPX Y Adieresis -120 +KPX Y Agrave -120 +KPX Y Amacron -120 +KPX Y Aogonek -120 +KPX Y Aring -120 +KPX Y Atilde -120 +KPX Y O -30 +KPX Y Oacute -30 +KPX Y Ocircumflex -30 +KPX Y Odieresis -30 +KPX Y Ograve -30 +KPX Y Ohungarumlaut -30 +KPX Y Omacron -30 +KPX Y Oslash -30 +KPX Y Otilde -30 +KPX Y a -100 +KPX Y aacute -100 +KPX Y abreve -100 +KPX Y acircumflex -100 +KPX Y adieresis -60 +KPX Y agrave -60 +KPX Y amacron -60 +KPX Y aogonek -100 +KPX Y aring -100 +KPX Y atilde -60 +KPX Y colon -92 +KPX Y comma -129 +KPX Y e -100 +KPX Y eacute -100 +KPX Y ecaron -100 +KPX Y ecircumflex -100 +KPX Y edieresis -60 +KPX Y edotaccent -100 +KPX Y egrave -60 +KPX Y emacron -60 +KPX Y eogonek -100 +KPX Y hyphen -111 +KPX Y i -55 +KPX Y iacute -55 +KPX Y iogonek -55 +KPX Y o -110 +KPX Y oacute -110 +KPX Y ocircumflex -110 +KPX Y odieresis -70 +KPX Y ograve -70 +KPX Y ohungarumlaut -110 +KPX Y omacron -70 +KPX Y oslash -110 +KPX Y otilde -70 +KPX Y period -129 +KPX Y semicolon -92 +KPX Y u -111 +KPX Y uacute -111 +KPX Y ucircumflex -111 +KPX Y udieresis -71 +KPX Y ugrave -71 +KPX Y uhungarumlaut -111 +KPX Y umacron -71 +KPX Y uogonek -111 +KPX Y uring -111 +KPX Yacute A -120 +KPX Yacute Aacute -120 +KPX Yacute Abreve -120 +KPX Yacute Acircumflex -120 +KPX Yacute Adieresis -120 +KPX Yacute Agrave -120 +KPX Yacute Amacron -120 +KPX Yacute Aogonek -120 +KPX Yacute Aring -120 +KPX Yacute Atilde -120 +KPX Yacute O -30 +KPX Yacute Oacute -30 +KPX Yacute Ocircumflex -30 +KPX Yacute Odieresis -30 +KPX Yacute Ograve -30 +KPX Yacute Ohungarumlaut -30 +KPX Yacute Omacron -30 +KPX Yacute Oslash -30 +KPX Yacute Otilde -30 +KPX Yacute a -100 +KPX Yacute aacute -100 +KPX Yacute abreve -100 +KPX Yacute acircumflex -100 +KPX Yacute adieresis -60 +KPX Yacute agrave -60 +KPX Yacute amacron -60 +KPX Yacute aogonek -100 +KPX Yacute aring -100 +KPX Yacute atilde -60 +KPX Yacute colon -92 +KPX Yacute comma -129 +KPX Yacute e -100 +KPX Yacute eacute -100 +KPX Yacute ecaron -100 +KPX Yacute ecircumflex -100 +KPX Yacute edieresis -60 +KPX Yacute edotaccent -100 +KPX Yacute egrave -60 +KPX Yacute emacron -60 +KPX Yacute eogonek -100 +KPX Yacute hyphen -111 +KPX Yacute i -55 +KPX Yacute iacute -55 +KPX Yacute iogonek -55 +KPX Yacute o -110 +KPX Yacute oacute -110 +KPX Yacute ocircumflex -110 +KPX Yacute odieresis -70 +KPX Yacute ograve -70 +KPX Yacute ohungarumlaut -110 +KPX Yacute omacron -70 +KPX Yacute oslash -110 +KPX Yacute otilde -70 +KPX Yacute period -129 +KPX Yacute semicolon -92 +KPX Yacute u -111 +KPX Yacute uacute -111 +KPX Yacute ucircumflex -111 +KPX Yacute udieresis -71 +KPX Yacute ugrave -71 +KPX Yacute uhungarumlaut -111 +KPX Yacute umacron -71 +KPX Yacute uogonek -111 +KPX Yacute uring -111 +KPX Ydieresis A -120 +KPX Ydieresis Aacute -120 +KPX Ydieresis Abreve -120 +KPX Ydieresis Acircumflex -120 +KPX Ydieresis Adieresis -120 +KPX Ydieresis Agrave -120 +KPX Ydieresis Amacron -120 +KPX Ydieresis Aogonek -120 +KPX Ydieresis Aring -120 +KPX Ydieresis Atilde -120 +KPX Ydieresis O -30 +KPX Ydieresis Oacute -30 +KPX Ydieresis Ocircumflex -30 +KPX Ydieresis Odieresis -30 +KPX Ydieresis Ograve -30 +KPX Ydieresis Ohungarumlaut -30 +KPX Ydieresis Omacron -30 +KPX Ydieresis Oslash -30 +KPX Ydieresis Otilde -30 +KPX Ydieresis a -100 +KPX Ydieresis aacute -100 +KPX Ydieresis abreve -100 +KPX Ydieresis acircumflex -100 +KPX Ydieresis adieresis -60 +KPX Ydieresis agrave -60 +KPX Ydieresis amacron -60 +KPX Ydieresis aogonek -100 +KPX Ydieresis aring -100 +KPX Ydieresis atilde -100 +KPX Ydieresis colon -92 +KPX Ydieresis comma -129 +KPX Ydieresis e -100 +KPX Ydieresis eacute -100 +KPX Ydieresis ecaron -100 +KPX Ydieresis ecircumflex -100 +KPX Ydieresis edieresis -60 +KPX Ydieresis edotaccent -100 +KPX Ydieresis egrave -60 +KPX Ydieresis emacron -60 +KPX Ydieresis eogonek -100 +KPX Ydieresis hyphen -111 +KPX Ydieresis i -55 +KPX Ydieresis iacute -55 +KPX Ydieresis iogonek -55 +KPX Ydieresis o -110 +KPX Ydieresis oacute -110 +KPX Ydieresis ocircumflex -110 +KPX Ydieresis odieresis -70 +KPX Ydieresis ograve -70 +KPX Ydieresis ohungarumlaut -110 +KPX Ydieresis omacron -70 +KPX Ydieresis oslash -110 +KPX Ydieresis otilde -70 +KPX Ydieresis period -129 +KPX Ydieresis semicolon -92 +KPX Ydieresis u -111 +KPX Ydieresis uacute -111 +KPX Ydieresis ucircumflex -111 +KPX Ydieresis udieresis -71 +KPX Ydieresis ugrave -71 +KPX Ydieresis uhungarumlaut -111 +KPX Ydieresis umacron -71 +KPX Ydieresis uogonek -111 +KPX Ydieresis uring -111 +KPX a v -20 +KPX a w -15 +KPX aacute v -20 +KPX aacute w -15 +KPX abreve v -20 +KPX abreve w -15 +KPX acircumflex v -20 +KPX acircumflex w -15 +KPX adieresis v -20 +KPX adieresis w -15 +KPX agrave v -20 +KPX agrave w -15 +KPX amacron v -20 +KPX amacron w -15 +KPX aogonek v -20 +KPX aogonek w -15 +KPX aring v -20 +KPX aring w -15 +KPX atilde v -20 +KPX atilde w -15 +KPX b period -40 +KPX b u -20 +KPX b uacute -20 +KPX b ucircumflex -20 +KPX b udieresis -20 +KPX b ugrave -20 +KPX b uhungarumlaut -20 +KPX b umacron -20 +KPX b uogonek -20 +KPX b uring -20 +KPX b v -15 +KPX c y -15 +KPX c yacute -15 +KPX c ydieresis -15 +KPX cacute y -15 +KPX cacute yacute -15 +KPX cacute ydieresis -15 +KPX ccaron y -15 +KPX ccaron yacute -15 +KPX ccaron ydieresis -15 +KPX ccedilla y -15 +KPX ccedilla yacute -15 +KPX ccedilla ydieresis -15 +KPX comma quotedblright -70 +KPX comma quoteright -70 +KPX e g -15 +KPX e gbreve -15 +KPX e gcommaaccent -15 +KPX e v -25 +KPX e w -25 +KPX e x -15 +KPX e y -15 +KPX e yacute -15 +KPX e ydieresis -15 +KPX eacute g -15 +KPX eacute gbreve -15 +KPX eacute gcommaaccent -15 +KPX eacute v -25 +KPX eacute w -25 +KPX eacute x -15 +KPX eacute y -15 +KPX eacute yacute -15 +KPX eacute ydieresis -15 +KPX ecaron g -15 +KPX ecaron gbreve -15 +KPX ecaron gcommaaccent -15 +KPX ecaron v -25 +KPX ecaron w -25 +KPX ecaron x -15 +KPX ecaron y -15 +KPX ecaron yacute -15 +KPX ecaron ydieresis -15 +KPX ecircumflex g -15 +KPX ecircumflex gbreve -15 +KPX ecircumflex gcommaaccent -15 +KPX ecircumflex v -25 +KPX ecircumflex w -25 +KPX ecircumflex x -15 +KPX ecircumflex y -15 +KPX ecircumflex yacute -15 +KPX ecircumflex ydieresis -15 +KPX edieresis g -15 +KPX edieresis gbreve -15 +KPX edieresis gcommaaccent -15 +KPX edieresis v -25 +KPX edieresis w -25 +KPX edieresis x -15 +KPX edieresis y -15 +KPX edieresis yacute -15 +KPX edieresis ydieresis -15 +KPX edotaccent g -15 +KPX edotaccent gbreve -15 +KPX edotaccent gcommaaccent -15 +KPX edotaccent v -25 +KPX edotaccent w -25 +KPX edotaccent x -15 +KPX edotaccent y -15 +KPX edotaccent yacute -15 +KPX edotaccent ydieresis -15 +KPX egrave g -15 +KPX egrave gbreve -15 +KPX egrave gcommaaccent -15 +KPX egrave v -25 +KPX egrave w -25 +KPX egrave x -15 +KPX egrave y -15 +KPX egrave yacute -15 +KPX egrave ydieresis -15 +KPX emacron g -15 +KPX emacron gbreve -15 +KPX emacron gcommaaccent -15 +KPX emacron v -25 +KPX emacron w -25 +KPX emacron x -15 +KPX emacron y -15 +KPX emacron yacute -15 +KPX emacron ydieresis -15 +KPX eogonek g -15 +KPX eogonek gbreve -15 +KPX eogonek gcommaaccent -15 +KPX eogonek v -25 +KPX eogonek w -25 +KPX eogonek x -15 +KPX eogonek y -15 +KPX eogonek yacute -15 +KPX eogonek ydieresis -15 +KPX f a -10 +KPX f aacute -10 +KPX f abreve -10 +KPX f acircumflex -10 +KPX f adieresis -10 +KPX f agrave -10 +KPX f amacron -10 +KPX f aogonek -10 +KPX f aring -10 +KPX f atilde -10 +KPX f dotlessi -50 +KPX f f -25 +KPX f i -20 +KPX f iacute -20 +KPX f quoteright 55 +KPX g a -5 +KPX g aacute -5 +KPX g abreve -5 +KPX g acircumflex -5 +KPX g adieresis -5 +KPX g agrave -5 +KPX g amacron -5 +KPX g aogonek -5 +KPX g aring -5 +KPX g atilde -5 +KPX gbreve a -5 +KPX gbreve aacute -5 +KPX gbreve abreve -5 +KPX gbreve acircumflex -5 +KPX gbreve adieresis -5 +KPX gbreve agrave -5 +KPX gbreve amacron -5 +KPX gbreve aogonek -5 +KPX gbreve aring -5 +KPX gbreve atilde -5 +KPX gcommaaccent a -5 +KPX gcommaaccent aacute -5 +KPX gcommaaccent abreve -5 +KPX gcommaaccent acircumflex -5 +KPX gcommaaccent adieresis -5 +KPX gcommaaccent agrave -5 +KPX gcommaaccent amacron -5 +KPX gcommaaccent aogonek -5 +KPX gcommaaccent aring -5 +KPX gcommaaccent atilde -5 +KPX h y -5 +KPX h yacute -5 +KPX h ydieresis -5 +KPX i v -25 +KPX iacute v -25 +KPX icircumflex v -25 +KPX idieresis v -25 +KPX igrave v -25 +KPX imacron v -25 +KPX iogonek v -25 +KPX k e -10 +KPX k eacute -10 +KPX k ecaron -10 +KPX k ecircumflex -10 +KPX k edieresis -10 +KPX k edotaccent -10 +KPX k egrave -10 +KPX k emacron -10 +KPX k eogonek -10 +KPX k o -10 +KPX k oacute -10 +KPX k ocircumflex -10 +KPX k odieresis -10 +KPX k ograve -10 +KPX k ohungarumlaut -10 +KPX k omacron -10 +KPX k oslash -10 +KPX k otilde -10 +KPX k y -15 +KPX k yacute -15 +KPX k ydieresis -15 +KPX kcommaaccent e -10 +KPX kcommaaccent eacute -10 +KPX kcommaaccent ecaron -10 +KPX kcommaaccent ecircumflex -10 +KPX kcommaaccent edieresis -10 +KPX kcommaaccent edotaccent -10 +KPX kcommaaccent egrave -10 +KPX kcommaaccent emacron -10 +KPX kcommaaccent eogonek -10 +KPX kcommaaccent o -10 +KPX kcommaaccent oacute -10 +KPX kcommaaccent ocircumflex -10 +KPX kcommaaccent odieresis -10 +KPX kcommaaccent ograve -10 +KPX kcommaaccent ohungarumlaut -10 +KPX kcommaaccent omacron -10 +KPX kcommaaccent oslash -10 +KPX kcommaaccent otilde -10 +KPX kcommaaccent y -15 +KPX kcommaaccent yacute -15 +KPX kcommaaccent ydieresis -15 +KPX l w -10 +KPX lacute w -10 +KPX lcommaaccent w -10 +KPX lslash w -10 +KPX n v -40 +KPX n y -15 +KPX n yacute -15 +KPX n ydieresis -15 +KPX nacute v -40 +KPX nacute y -15 +KPX nacute yacute -15 +KPX nacute ydieresis -15 +KPX ncaron v -40 +KPX ncaron y -15 +KPX ncaron yacute -15 +KPX ncaron ydieresis -15 +KPX ncommaaccent v -40 +KPX ncommaaccent y -15 +KPX ncommaaccent yacute -15 +KPX ncommaaccent ydieresis -15 +KPX ntilde v -40 +KPX ntilde y -15 +KPX ntilde yacute -15 +KPX ntilde ydieresis -15 +KPX o v -15 +KPX o w -25 +KPX o y -10 +KPX o yacute -10 +KPX o ydieresis -10 +KPX oacute v -15 +KPX oacute w -25 +KPX oacute y -10 +KPX oacute yacute -10 +KPX oacute ydieresis -10 +KPX ocircumflex v -15 +KPX ocircumflex w -25 +KPX ocircumflex y -10 +KPX ocircumflex yacute -10 +KPX ocircumflex ydieresis -10 +KPX odieresis v -15 +KPX odieresis w -25 +KPX odieresis y -10 +KPX odieresis yacute -10 +KPX odieresis ydieresis -10 +KPX ograve v -15 +KPX ograve w -25 +KPX ograve y -10 +KPX ograve yacute -10 +KPX ograve ydieresis -10 +KPX ohungarumlaut v -15 +KPX ohungarumlaut w -25 +KPX ohungarumlaut y -10 +KPX ohungarumlaut yacute -10 +KPX ohungarumlaut ydieresis -10 +KPX omacron v -15 +KPX omacron w -25 +KPX omacron y -10 +KPX omacron yacute -10 +KPX omacron ydieresis -10 +KPX oslash v -15 +KPX oslash w -25 +KPX oslash y -10 +KPX oslash yacute -10 +KPX oslash ydieresis -10 +KPX otilde v -15 +KPX otilde w -25 +KPX otilde y -10 +KPX otilde yacute -10 +KPX otilde ydieresis -10 +KPX p y -10 +KPX p yacute -10 +KPX p ydieresis -10 +KPX period quotedblright -70 +KPX period quoteright -70 +KPX quotedblleft A -80 +KPX quotedblleft Aacute -80 +KPX quotedblleft Abreve -80 +KPX quotedblleft Acircumflex -80 +KPX quotedblleft Adieresis -80 +KPX quotedblleft Agrave -80 +KPX quotedblleft Amacron -80 +KPX quotedblleft Aogonek -80 +KPX quotedblleft Aring -80 +KPX quotedblleft Atilde -80 +KPX quoteleft A -80 +KPX quoteleft Aacute -80 +KPX quoteleft Abreve -80 +KPX quoteleft Acircumflex -80 +KPX quoteleft Adieresis -80 +KPX quoteleft Agrave -80 +KPX quoteleft Amacron -80 +KPX quoteleft Aogonek -80 +KPX quoteleft Aring -80 +KPX quoteleft Atilde -80 +KPX quoteleft quoteleft -74 +KPX quoteright d -50 +KPX quoteright dcroat -50 +KPX quoteright l -10 +KPX quoteright lacute -10 +KPX quoteright lcommaaccent -10 +KPX quoteright lslash -10 +KPX quoteright quoteright -74 +KPX quoteright r -50 +KPX quoteright racute -50 +KPX quoteright rcaron -50 +KPX quoteright rcommaaccent -50 +KPX quoteright s -55 +KPX quoteright sacute -55 +KPX quoteright scaron -55 +KPX quoteright scedilla -55 +KPX quoteright scommaaccent -55 +KPX quoteright space -74 +KPX quoteright t -18 +KPX quoteright tcommaaccent -18 +KPX quoteright v -50 +KPX r comma -40 +KPX r g -18 +KPX r gbreve -18 +KPX r gcommaaccent -18 +KPX r hyphen -20 +KPX r period -55 +KPX racute comma -40 +KPX racute g -18 +KPX racute gbreve -18 +KPX racute gcommaaccent -18 +KPX racute hyphen -20 +KPX racute period -55 +KPX rcaron comma -40 +KPX rcaron g -18 +KPX rcaron gbreve -18 +KPX rcaron gcommaaccent -18 +KPX rcaron hyphen -20 +KPX rcaron period -55 +KPX rcommaaccent comma -40 +KPX rcommaaccent g -18 +KPX rcommaaccent gbreve -18 +KPX rcommaaccent gcommaaccent -18 +KPX rcommaaccent hyphen -20 +KPX rcommaaccent period -55 +KPX space A -55 +KPX space Aacute -55 +KPX space Abreve -55 +KPX space Acircumflex -55 +KPX space Adieresis -55 +KPX space Agrave -55 +KPX space Amacron -55 +KPX space Aogonek -55 +KPX space Aring -55 +KPX space Atilde -55 +KPX space T -18 +KPX space Tcaron -18 +KPX space Tcommaaccent -18 +KPX space V -50 +KPX space W -30 +KPX space Y -90 +KPX space Yacute -90 +KPX space Ydieresis -90 +KPX v a -25 +KPX v aacute -25 +KPX v abreve -25 +KPX v acircumflex -25 +KPX v adieresis -25 +KPX v agrave -25 +KPX v amacron -25 +KPX v aogonek -25 +KPX v aring -25 +KPX v atilde -25 +KPX v comma -65 +KPX v e -15 +KPX v eacute -15 +KPX v ecaron -15 +KPX v ecircumflex -15 +KPX v edieresis -15 +KPX v edotaccent -15 +KPX v egrave -15 +KPX v emacron -15 +KPX v eogonek -15 +KPX v o -20 +KPX v oacute -20 +KPX v ocircumflex -20 +KPX v odieresis -20 +KPX v ograve -20 +KPX v ohungarumlaut -20 +KPX v omacron -20 +KPX v oslash -20 +KPX v otilde -20 +KPX v period -65 +KPX w a -10 +KPX w aacute -10 +KPX w abreve -10 +KPX w acircumflex -10 +KPX w adieresis -10 +KPX w agrave -10 +KPX w amacron -10 +KPX w aogonek -10 +KPX w aring -10 +KPX w atilde -10 +KPX w comma -65 +KPX w o -10 +KPX w oacute -10 +KPX w ocircumflex -10 +KPX w odieresis -10 +KPX w ograve -10 +KPX w ohungarumlaut -10 +KPX w omacron -10 +KPX w oslash -10 +KPX w otilde -10 +KPX w period -65 +KPX x e -15 +KPX x eacute -15 +KPX x ecaron -15 +KPX x ecircumflex -15 +KPX x edieresis -15 +KPX x edotaccent -15 +KPX x egrave -15 +KPX x emacron -15 +KPX x eogonek -15 +KPX y comma -65 +KPX y period -65 +KPX yacute comma -65 +KPX yacute period -65 +KPX ydieresis comma -65 +KPX ydieresis period -65 +EndKernPairs +EndKernData +EndFontMetrics addfile ./Core14_AFMs/ZapfDingbats.afm hunk ./Core14_AFMs/ZapfDingbats.afm 1 +StartFontMetrics 4.1 +Comment Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 15:14:13 1997 +Comment UniqueID 43082 +Comment VMusage 45775 55535 +FontName ZapfDingbats +FullName ITC Zapf Dingbats +FamilyName ZapfDingbats +Weight Medium +ItalicAngle 0 +IsFixedPitch false +CharacterSet Special +FontBBox -1 -143 981 820 +UnderlinePosition -100 +UnderlineThickness 50 +Version 002.000 +Notice Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved.ITC Zapf Dingbats is a registered trademark of International Typeface Corporation. +EncodingScheme FontSpecific +StdHW 28 +StdVW 90 +StartCharMetrics 202 +C 32 ; WX 278 ; N space ; B 0 0 0 0 ; +C 33 ; WX 974 ; N a1 ; B 35 72 939 621 ; +C 34 ; WX 961 ; N a2 ; B 35 81 927 611 ; +C 35 ; WX 974 ; N a202 ; B 35 72 939 621 ; +C 36 ; WX 980 ; N a3 ; B 35 0 945 692 ; +C 37 ; WX 719 ; N a4 ; B 34 139 685 566 ; +C 38 ; WX 789 ; N a5 ; B 35 -14 755 705 ; +C 39 ; WX 790 ; N a119 ; B 35 -14 755 705 ; +C 40 ; WX 791 ; N a118 ; B 35 -13 761 705 ; +C 41 ; WX 690 ; N a117 ; B 34 138 655 553 ; +C 42 ; WX 960 ; N a11 ; B 35 123 925 568 ; +C 43 ; WX 939 ; N a12 ; B 35 134 904 559 ; +C 44 ; WX 549 ; N a13 ; B 29 -11 516 705 ; +C 45 ; WX 855 ; N a14 ; B 34 59 820 632 ; +C 46 ; WX 911 ; N a15 ; B 35 50 876 642 ; +C 47 ; WX 933 ; N a16 ; B 35 139 899 550 ; +C 48 ; WX 911 ; N a105 ; B 35 50 876 642 ; +C 49 ; WX 945 ; N a17 ; B 35 139 909 553 ; +C 50 ; WX 974 ; N a18 ; B 35 104 938 587 ; +C 51 ; WX 755 ; N a19 ; B 34 -13 721 705 ; +C 52 ; WX 846 ; N a20 ; B 36 -14 811 705 ; +C 53 ; WX 762 ; N a21 ; B 35 0 727 692 ; +C 54 ; WX 761 ; N a22 ; B 35 0 727 692 ; +C 55 ; WX 571 ; N a23 ; B -1 -68 571 661 ; +C 56 ; WX 677 ; N a24 ; B 36 -13 642 705 ; +C 57 ; WX 763 ; N a25 ; B 35 0 728 692 ; +C 58 ; WX 760 ; N a26 ; B 35 0 726 692 ; +C 59 ; WX 759 ; N a27 ; B 35 0 725 692 ; +C 60 ; WX 754 ; N a28 ; B 35 0 720 692 ; +C 61 ; WX 494 ; N a6 ; B 35 0 460 692 ; +C 62 ; WX 552 ; N a7 ; B 35 0 517 692 ; +C 63 ; WX 537 ; N a8 ; B 35 0 503 692 ; +C 64 ; WX 577 ; N a9 ; B 35 96 542 596 ; +C 65 ; WX 692 ; N a10 ; B 35 -14 657 705 ; +C 66 ; WX 786 ; N a29 ; B 35 -14 751 705 ; +C 67 ; WX 788 ; N a30 ; B 35 -14 752 705 ; +C 68 ; WX 788 ; N a31 ; B 35 -14 753 705 ; +C 69 ; WX 790 ; N a32 ; B 35 -14 756 705 ; +C 70 ; WX 793 ; N a33 ; B 35 -13 759 705 ; +C 71 ; WX 794 ; N a34 ; B 35 -13 759 705 ; +C 72 ; WX 816 ; N a35 ; B 35 -14 782 705 ; +C 73 ; WX 823 ; N a36 ; B 35 -14 787 705 ; +C 74 ; WX 789 ; N a37 ; B 35 -14 754 705 ; +C 75 ; WX 841 ; N a38 ; B 35 -14 807 705 ; +C 76 ; WX 823 ; N a39 ; B 35 -14 789 705 ; +C 77 ; WX 833 ; N a40 ; B 35 -14 798 705 ; +C 78 ; WX 816 ; N a41 ; B 35 -13 782 705 ; +C 79 ; WX 831 ; N a42 ; B 35 -14 796 705 ; +C 80 ; WX 923 ; N a43 ; B 35 -14 888 705 ; +C 81 ; WX 744 ; N a44 ; B 35 0 710 692 ; +C 82 ; WX 723 ; N a45 ; B 35 0 688 692 ; +C 83 ; WX 749 ; N a46 ; B 35 0 714 692 ; +C 84 ; WX 790 ; N a47 ; B 34 -14 756 705 ; +C 85 ; WX 792 ; N a48 ; B 35 -14 758 705 ; +C 86 ; WX 695 ; N a49 ; B 35 -14 661 706 ; +C 87 ; WX 776 ; N a50 ; B 35 -6 741 699 ; +C 88 ; WX 768 ; N a51 ; B 35 -7 734 699 ; +C 89 ; WX 792 ; N a52 ; B 35 -14 757 705 ; +C 90 ; WX 759 ; N a53 ; B 35 0 725 692 ; +C 91 ; WX 707 ; N a54 ; B 35 -13 672 704 ; +C 92 ; WX 708 ; N a55 ; B 35 -14 672 705 ; +C 93 ; WX 682 ; N a56 ; B 35 -14 647 705 ; +C 94 ; WX 701 ; N a57 ; B 35 -14 666 705 ; +C 95 ; WX 826 ; N a58 ; B 35 -14 791 705 ; +C 96 ; WX 815 ; N a59 ; B 35 -14 780 705 ; +C 97 ; WX 789 ; N a60 ; B 35 -14 754 705 ; +C 98 ; WX 789 ; N a61 ; B 35 -14 754 705 ; +C 99 ; WX 707 ; N a62 ; B 34 -14 673 705 ; +C 100 ; WX 687 ; N a63 ; B 36 0 651 692 ; +C 101 ; WX 696 ; N a64 ; B 35 0 661 691 ; +C 102 ; WX 689 ; N a65 ; B 35 0 655 692 ; +C 103 ; WX 786 ; N a66 ; B 34 -14 751 705 ; +C 104 ; WX 787 ; N a67 ; B 35 -14 752 705 ; +C 105 ; WX 713 ; N a68 ; B 35 -14 678 705 ; +C 106 ; WX 791 ; N a69 ; B 35 -14 756 705 ; +C 107 ; WX 785 ; N a70 ; B 36 -14 751 705 ; +C 108 ; WX 791 ; N a71 ; B 35 -14 757 705 ; +C 109 ; WX 873 ; N a72 ; B 35 -14 838 705 ; +C 110 ; WX 761 ; N a73 ; B 35 0 726 692 ; +C 111 ; WX 762 ; N a74 ; B 35 0 727 692 ; +C 112 ; WX 762 ; N a203 ; B 35 0 727 692 ; +C 113 ; WX 759 ; N a75 ; B 35 0 725 692 ; +C 114 ; WX 759 ; N a204 ; B 35 0 725 692 ; +C 115 ; WX 892 ; N a76 ; B 35 0 858 705 ; +C 116 ; WX 892 ; N a77 ; B 35 -14 858 692 ; +C 117 ; WX 788 ; N a78 ; B 35 -14 754 705 ; +C 118 ; WX 784 ; N a79 ; B 35 -14 749 705 ; +C 119 ; WX 438 ; N a81 ; B 35 -14 403 705 ; +C 120 ; WX 138 ; N a82 ; B 35 0 104 692 ; +C 121 ; WX 277 ; N a83 ; B 35 0 242 692 ; +C 122 ; WX 415 ; N a84 ; B 35 0 380 692 ; +C 123 ; WX 392 ; N a97 ; B 35 263 357 705 ; +C 124 ; WX 392 ; N a98 ; B 34 263 357 705 ; +C 125 ; WX 668 ; N a99 ; B 35 263 633 705 ; +C 126 ; WX 668 ; N a100 ; B 36 263 634 705 ; +C 128 ; WX 390 ; N a89 ; B 35 -14 356 705 ; +C 129 ; WX 390 ; N a90 ; B 35 -14 355 705 ; +C 130 ; WX 317 ; N a93 ; B 35 0 283 692 ; +C 131 ; WX 317 ; N a94 ; B 35 0 283 692 ; +C 132 ; WX 276 ; N a91 ; B 35 0 242 692 ; +C 133 ; WX 276 ; N a92 ; B 35 0 242 692 ; +C 134 ; WX 509 ; N a205 ; B 35 0 475 692 ; +C 135 ; WX 509 ; N a85 ; B 35 0 475 692 ; +C 136 ; WX 410 ; N a206 ; B 35 0 375 692 ; +C 137 ; WX 410 ; N a86 ; B 35 0 375 692 ; +C 138 ; WX 234 ; N a87 ; B 35 -14 199 705 ; +C 139 ; WX 234 ; N a88 ; B 35 -14 199 705 ; +C 140 ; WX 334 ; N a95 ; B 35 0 299 692 ; +C 141 ; WX 334 ; N a96 ; B 35 0 299 692 ; +C 161 ; WX 732 ; N a101 ; B 35 -143 697 806 ; +C 162 ; WX 544 ; N a102 ; B 56 -14 488 706 ; +C 163 ; WX 544 ; N a103 ; B 34 -14 508 705 ; +C 164 ; WX 910 ; N a104 ; B 35 40 875 651 ; +C 165 ; WX 667 ; N a106 ; B 35 -14 633 705 ; +C 166 ; WX 760 ; N a107 ; B 35 -14 726 705 ; +C 167 ; WX 760 ; N a108 ; B 0 121 758 569 ; +C 168 ; WX 776 ; N a112 ; B 35 0 741 705 ; +C 169 ; WX 595 ; N a111 ; B 34 -14 560 705 ; +C 170 ; WX 694 ; N a110 ; B 35 -14 659 705 ; +C 171 ; WX 626 ; N a109 ; B 34 0 591 705 ; +C 172 ; WX 788 ; N a120 ; B 35 -14 754 705 ; +C 173 ; WX 788 ; N a121 ; B 35 -14 754 705 ; +C 174 ; WX 788 ; N a122 ; B 35 -14 754 705 ; +C 175 ; WX 788 ; N a123 ; B 35 -14 754 705 ; +C 176 ; WX 788 ; N a124 ; B 35 -14 754 705 ; +C 177 ; WX 788 ; N a125 ; B 35 -14 754 705 ; +C 178 ; WX 788 ; N a126 ; B 35 -14 754 705 ; +C 179 ; WX 788 ; N a127 ; B 35 -14 754 705 ; +C 180 ; WX 788 ; N a128 ; B 35 -14 754 705 ; +C 181 ; WX 788 ; N a129 ; B 35 -14 754 705 ; +C 182 ; WX 788 ; N a130 ; B 35 -14 754 705 ; +C 183 ; WX 788 ; N a131 ; B 35 -14 754 705 ; +C 184 ; WX 788 ; N a132 ; B 35 -14 754 705 ; +C 185 ; WX 788 ; N a133 ; B 35 -14 754 705 ; +C 186 ; WX 788 ; N a134 ; B 35 -14 754 705 ; +C 187 ; WX 788 ; N a135 ; B 35 -14 754 705 ; +C 188 ; WX 788 ; N a136 ; B 35 -14 754 705 ; +C 189 ; WX 788 ; N a137 ; B 35 -14 754 705 ; +C 190 ; WX 788 ; N a138 ; B 35 -14 754 705 ; +C 191 ; WX 788 ; N a139 ; B 35 -14 754 705 ; +C 192 ; WX 788 ; N a140 ; B 35 -14 754 705 ; +C 193 ; WX 788 ; N a141 ; B 35 -14 754 705 ; +C 194 ; WX 788 ; N a142 ; B 35 -14 754 705 ; +C 195 ; WX 788 ; N a143 ; B 35 -14 754 705 ; +C 196 ; WX 788 ; N a144 ; B 35 -14 754 705 ; +C 197 ; WX 788 ; N a145 ; B 35 -14 754 705 ; +C 198 ; WX 788 ; N a146 ; B 35 -14 754 705 ; +C 199 ; WX 788 ; N a147 ; B 35 -14 754 705 ; +C 200 ; WX 788 ; N a148 ; B 35 -14 754 705 ; +C 201 ; WX 788 ; N a149 ; B 35 -14 754 705 ; +C 202 ; WX 788 ; N a150 ; B 35 -14 754 705 ; +C 203 ; WX 788 ; N a151 ; B 35 -14 754 705 ; +C 204 ; WX 788 ; N a152 ; B 35 -14 754 705 ; +C 205 ; WX 788 ; N a153 ; B 35 -14 754 705 ; +C 206 ; WX 788 ; N a154 ; B 35 -14 754 705 ; +C 207 ; WX 788 ; N a155 ; B 35 -14 754 705 ; +C 208 ; WX 788 ; N a156 ; B 35 -14 754 705 ; +C 209 ; WX 788 ; N a157 ; B 35 -14 754 705 ; +C 210 ; WX 788 ; N a158 ; B 35 -14 754 705 ; +C 211 ; WX 788 ; N a159 ; B 35 -14 754 705 ; +C 212 ; WX 894 ; N a160 ; B 35 58 860 634 ; +C 213 ; WX 838 ; N a161 ; B 35 152 803 540 ; +C 214 ; WX 1016 ; N a163 ; B 34 152 981 540 ; +C 215 ; WX 458 ; N a164 ; B 35 -127 422 820 ; +C 216 ; WX 748 ; N a196 ; B 35 94 698 597 ; +C 217 ; WX 924 ; N a165 ; B 35 140 890 552 ; +C 218 ; WX 748 ; N a192 ; B 35 94 698 597 ; +C 219 ; WX 918 ; N a166 ; B 35 166 884 526 ; +C 220 ; WX 927 ; N a167 ; B 35 32 892 660 ; +C 221 ; WX 928 ; N a168 ; B 35 129 891 562 ; +C 222 ; WX 928 ; N a169 ; B 35 128 893 563 ; +C 223 ; WX 834 ; N a170 ; B 35 155 799 537 ; +C 224 ; WX 873 ; N a171 ; B 35 93 838 599 ; +C 225 ; WX 828 ; N a172 ; B 35 104 791 588 ; +C 226 ; WX 924 ; N a173 ; B 35 98 889 594 ; +C 227 ; WX 924 ; N a162 ; B 35 98 889 594 ; +C 228 ; WX 917 ; N a174 ; B 35 0 882 692 ; +C 229 ; WX 930 ; N a175 ; B 35 84 896 608 ; +C 230 ; WX 931 ; N a176 ; B 35 84 896 608 ; +C 231 ; WX 463 ; N a177 ; B 35 -99 429 791 ; +C 232 ; WX 883 ; N a178 ; B 35 71 848 623 ; +C 233 ; WX 836 ; N a179 ; B 35 44 802 648 ; +C 234 ; WX 836 ; N a193 ; B 35 44 802 648 ; +C 235 ; WX 867 ; N a180 ; B 35 101 832 591 ; +C 236 ; WX 867 ; N a199 ; B 35 101 832 591 ; +C 237 ; WX 696 ; N a181 ; B 35 44 661 648 ; +C 238 ; WX 696 ; N a200 ; B 35 44 661 648 ; +C 239 ; WX 874 ; N a182 ; B 35 77 840 619 ; +C 241 ; WX 874 ; N a201 ; B 35 73 840 615 ; +C 242 ; WX 760 ; N a183 ; B 35 0 725 692 ; +C 243 ; WX 946 ; N a184 ; B 35 160 911 533 ; +C 244 ; WX 771 ; N a197 ; B 34 37 736 655 ; +C 245 ; WX 865 ; N a185 ; B 35 207 830 481 ; +C 246 ; WX 771 ; N a194 ; B 34 37 736 655 ; +C 247 ; WX 888 ; N a198 ; B 34 -19 853 712 ; +C 248 ; WX 967 ; N a186 ; B 35 124 932 568 ; +C 249 ; WX 888 ; N a195 ; B 34 -19 853 712 ; +C 250 ; WX 831 ; N a187 ; B 35 113 796 579 ; +C 251 ; WX 873 ; N a188 ; B 36 118 838 578 ; +C 252 ; WX 927 ; N a189 ; B 35 150 891 542 ; +C 253 ; WX 970 ; N a190 ; B 35 76 931 616 ; +C 254 ; WX 918 ; N a191 ; B 34 99 884 593 ; +EndCharMetrics +EndFontMetrics hunk ./Graphics/PDF/Text.hs 56 -foreign import ccall "ctext.h c_getHeight" cgetHeight :: Int hunk ./Graphics/PDF/Text.hs 61 -trueSize fontSize textSize = (fromIntegral (textSize*fontSize)) / 2408.0 +trueSize fontSize textSize = (fromIntegral (textSize*fontSize)) / 2048.0 hunk ./Graphics/PDF/Text.hs 67 -getHeight (PDFFont _ s) = trueSize s cgetHeight +getHeight (PDFFont _ s) = trueSize s getLeading addfile ./Test/AFMParser.hs hunk ./Test/AFMParser.hs 1 - +module Main where + +import Text.ParserCombinators.Parsec +import Text.ParserCombinators.Parsec.Prim +import Text.ParserCombinators.Parsec.Char +import Data.Char(toUpper) + +capitalize :: String -> String +capitalize [] = [] +capitalize (h:t) = toUpper h : t + +line :: Parser () +line = do string "\r\n" + return () + +toEndOfLine :: Parser () +toEndOfLine = do many1 (noneOf "\r\n") + line + return () + +getString :: String -> Parser String +getString s = do + string s + spaces + c <- many1 (alphaNum <|> oneOf "-+") + line + return c + +getInt :: String -> Parser Int +getInt s = do c <- getString s + return $ read c + +getBool :: String -> Parser Bool +getBool s = do c <- getString s + return $ read (capitalize c) + +data CharacterSet = ExtendedRoman + deriving(Eq,Read,Show) + +data Weight = Medium + deriving(Eq,Read,Show) + +getCharacterSet :: String -> Parser CharacterSet +getCharacterSet s = do c <- getString s + return $ read c + +getWeigth :: String -> Parser Weight +getWeigth s = do c <- getString s + return $ read c + + +array :: Parser [String] +array = sepEndBy (many1 (oneOf "-+0123456789")) (many1 (oneOf " ")) + +getArray :: String -> Parser [Double] +getArray s = do string s + spaces + c <- array + line + return . map read $ c + +comment :: String -> Parser () +comment s = do string s + toEndOfLine + +comments :: Parser () +comments = do many1 (comment "Comment") + return () + +data EncodingScheme = AdobeStandardEncoding + deriving(Eq,Read,Show) + +getEncoding :: String -> Parser EncodingScheme +getEncoding s = do c <- getString s + return $ read c + +number :: Parser Int +number = do c <- many1 (oneOf "-+0123456789") + return $ read c + +data Elem = C Int + | WX Int + | N String + | B [Int] + | L + deriving(Eq,Read,Show) + +metricElem :: Parser Elem +metricElem = do char 'C' + spaces + c <- number + return $ C c + <|> + do string "WX" + spaces + c <- number + return $ WX c + <|> + do char 'N' + spaces + c <- many1 alphaNum + return $ N c + <|> + do char 'B' + spaces + c <- array + return . B . map read $ c + <|> + do char 'L' + spaces + many1 letter + spaces + many1 letter + return L + +charMetric :: Parser () +charMetric = do + sepEndBy metricElem (many1 (oneOf "; ")) + line + return () + +afm :: Parser [Double] +afm = do { string "StartFontMetrics" ; toEndOfLine + ; comments + ; fontName <- getString "FontName" + ; fullName <- getString "FullName" + ; familyName <- getString "FamilyName" + ; weight <- getWeigth "Weight" + ; italicAngle <- getInt "ItalicAngle" + ; isFixedPitch <- getBool "IsFixedPitch" + ; characterSet <- getCharacterSet "CharacterSet" + ; bbox <- getArray "FontBBox" + ; underlinePosition <- getInt "UnderlinePosition" + ; underlineThickness <- getInt "UnderlineThickness" + ; comment "Version" + ; comment "Notice" + ; encodingScheme <- getEncoding "EncodingScheme" + ; capHeight <- getInt "CapHeight" + ; xHeight <- getInt "XHeight" + ; ascender <- getInt "Ascender" + ; descender <- getInt "Descender" + ; stdHW <- getInt "StdHW" + ; stdVW <- getInt "StdVW" + ; startCharMetrics <- getInt "StartCharMetrics" + ; charMetrics <- many1 charMetric + ; getString "EndCharMetrics" + ; return bbox + } + +main :: IO () +main = do + l <- parseFromFile afm "../Core14_AFMs/Helvetica.afm" + print l hunk ./Test/Makefile 10 + +buildafm: + ghc -o afm --make AFMParser.hs hunk ./Test/Makefile 16 + rm -f afm hunk ./Test/test.hs 102 +f = PDFFont Times_Roman 48 +t = toPDFString "This is a test éèçàù" + hunk ./Test/test.hs 115 - t = toPDFString "This is a test éèçàù" + t = toPDFString "AAAAAAAAA¡" hunk ./Test/test.hs 120 + leading $ getHeight f hunk ./Test/test.hs 123 + startNewLine + displayText $ toPDFString "Another little test" hunk ./Test/test.hs 128 - stroke $ Rectangle 10 (400.0 - (getDescent f)) (10.0 + textWidth f t) (400.0 - getDescent f + getHeight f) - + stroke $ Rectangle 10 (400.0 - (getDescent f)) (10.0 + textWidth f t) (400.0 - getDescent f + getHeight f) hunk ./c/ctext.h 6 -extern unsigned short c_getHeight(void); hunk ./c/metrics.c 19 -unsigned short c_getHeight(void) -{ - return(fmetric[1]); -} binary ./c/metrics.h oldhex *2369666e646566205f4d4554524943535f485f0a23646566696e65205f4d4554524943535f485f *0a2f2a4e6220666163657320320a48656c76657469636120526567756c6172202a2f0a2f2a2063 *6861726d6170203a20756e6963202a2f0a2f2a20636861726d6170203a2061726d6e202a2f0a2f *2a20636861726d6170203a2061726d6e202a2f0a2f2a20636861726d6170203a2061726d6e202a *2f0a2f2a20636861726d6170203a2061726d6e202a2f0a2f2a20636861726d6170203a2061726d *6e202a2f0a2f2a20636861726d6170203a2061726d6e202a2f0a2f2a20636861726d6170203a20 *61726d6e202a2f0a2f2a20636861726d6170203a2000000000202a2f0a2f2a20636861726d6170 *203a2000000000202a2f0a73746174696320636f6e737420756e7369676e6564206c6f6e672067 *6d65747269635b5d3d7b0a2f2a2043686172636f64652030202a2f0a30202f2a20776964746820 *2a2f0a2c30202f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a *2f0a2c30202f2a20686f726942656172696e6759202a2f200a2c30202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f64652038202a2f0a2c30202f2a207769647468202a2f0a *2c30202f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c *30202f2a20686f726942656172696e6759202a2f200a2c30202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f64652039202a2f0a2c30202f2a207769647468202a2f0a2c3020 *2f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f *2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f6465203130202a2f0a2c30202f2a207769647468202a2f0a2c3020 *2f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f *2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f6465203133202a2f0a2c30202f2a207769647468202a2f0a2c3020 *2f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f *2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f6465203239202a2f0a2c30202f2a207769647468202a2f0a2c3020 *2f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f *2a20686f726942656172696e6759202a2f200a2c30202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203332202a2f0a2c30202f2a207769647468202a2f0a2c30202f2a *20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f2a20 *686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203333202a2f0a2c323033202f2a207769647468202a2f0a2c3134 *3639202f2a20686569676874202a2f0a2c323337202f2a20686f726942656172696e6758202a2f *0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f6465203334202a2f0a2c353234202f2a207769 *647468202a2f0a2c353838202f2a20686569676874202a2f0a2c313034202f2a20686f72694265 *6172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c3732 *37202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203335202a2f0a2c *31313337202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3020 *2f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e67 *59202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *6465203336202a2f0a2c393937202f2a207769647468202a2f0a2c31383235202f2a2068656967 *6874202a2f0a2c3634202f2a20686f726942656172696e6758202a2f0a2c31353838202f2a2068 *6f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203337202a2f0a2c31363738202f2a207769647468202a2f0a2c31 *343634202f2a20686569676874202a2f0a2c3636202f2a20686f726942656172696e6758202a2f *0a2c31343236202f2a20686f726942656172696e6759202a2f200a2c31383231202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f6465203338202a2f0a2c31323331202f2a20 *7769647468202a2f0a2c31353031202f2a20686569676874202a2f0a2c3839202f2a20686f7269 *42656172696e6758202a2f0a2c31343637202f2a20686f726942656172696e6759202a2f200a2c *31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203339202a *2f0a2c313832202f2a207769647468202a2f0a2c353838202f2a20686569676874202a2f0a2c31 *3031202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172 *696e6759202a2f200a2c333931202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f6465203430202a2f0a2c343637202f2a207769647468202a2f0a2c31393131202f2a206865 *69676874202a2f0a2c313432202f2a20686f726942656172696e6758202a2f0a2c31343933202f *2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f6465203431202a2f0a2c343637202f2a207769647468202a2f0a2c *31393131202f2a20686569676874202a2f0a2c3638202f2a20686f726942656172696e6758202a *2f0a2c31343933202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f6465203432202a2f0a2c363330202f2a2077 *69647468202a2f0a2c353838202f2a20686569676874202a2f0a2c3738202f2a20686f72694265 *6172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c3739 *37202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203433202a2f0a2c *31303433202f2a207769647468202a2f0a2c31303435202f2a20686569676874202a2f0a2c3736 *202f2a20686f726942656172696e6758202a2f0a2c31303435202f2a20686f726942656172696e *6759202a2f200a2c31313936202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f6465203434202a2f0a2c323134202f2a207769647468202a2f0a2c353232202f2a2068656967 *6874202a2f0a2c313730202f2a20686f726942656172696e6758202a2f0a2c323138202f2a2068 *6f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f6465203435202a2f0a2c353032202f2a207769647468202a2f0a2c313835 *202f2a20686569676874202a2f0a2c3835202f2a20686f726942656172696e6758202a2f0a2c36 *3633202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f6465203436202a2f0a2c323039202f2a20776964746820 *2a2f0a2c323138202f2a20686569676874202a2f0a2c313735202f2a20686f726942656172696e *6758202a2f0a2c323138202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f6465203437202a2f0a2c363138202f *2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c30202f2a20686f72 *6942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a *2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203438202a *2f0a2c393838202f2a207769647468202a2f0a2c31343731202f2a20686569676874202a2f0a2c *3634202f2a20686f726942656172696e6758202a2f0a2c31343332202f2a20686f726942656172 *696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f6465203439202a2f0a2c353239202f2a207769647468202a2f0a2c31343236202f2a2068 *6569676874202a2f0a2c313936202f2a20686f726942656172696e6758202a2f0a2c3134323620 *2f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f6465203530202a2f0a2c393930202f2a207769647468202a2f *0a2c31343337202f2a20686569676874202a2f0a2c3634202f2a20686f726942656172696e6758 *202a2f0a2c31343337202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f6465203531202a2f0a2c3130303120 *2f2a207769647468202a2f0a2c31343733202f2a20686569676874202a2f0a2c3439202f2a2068 *6f726942656172696e6758202a2f0a2c31343334202f2a20686f726942656172696e6759202a2f *200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652035 *32202a2f0a2c31303139202f2a207769647468202a2f0a2c31343336202f2a2068656967687420 *2a2f0a2c3532202f2a20686f726942656172696e6758202a2f0a2c31343336202f2a20686f7269 *42656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a *2043686172636f6465203533202a2f0a2c393836202f2a207769647468202a2f0a2c3134343420 *2f2a20686569676874202a2f0a2c3636202f2a20686f726942656172696e6758202a2f0a2c3134 *3038202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f6465203534202a2f0a2c393832202f2a207769647468 *202a2f0a2c31343735202f2a20686569676874202a2f0a2c3737202f2a20686f72694265617269 *6e6758202a2f0a2c31343338202f2a20686f726942656172696e6759202a2f200a2c3131333920 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203535202a2f0a2c3939 *36202f2a207769647468202a2f0a2c31343038202f2a20686569676874202a2f0a2c3735202f2a *20686f726942656172696e6758202a2f0a2c31343038202f2a20686f726942656172696e675920 *2a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *203536202a2f0a2c393834202f2a207769647468202a2f0a2c31343737202f2a20686569676874 *202a2f0a2c3636202f2a20686f726942656172696e6758202a2f0a2c31343336202f2a20686f72 *6942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f6465203537202a2f0a2c393638202f2a207769647468202a2f0a2c31343734 *202f2a20686569676874202a2f0a2c3733202f2a20686f726942656172696e6758202a2f0a2c31 *343334202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f6465203538202a2f0a2c323039202f2a2077696474 *68202a2f0a2c31303537202f2a20686569676874202a2f0a2c323237202f2a20686f7269426561 *72696e6758202a2f0a2c31303537202f2a20686f726942656172696e6759202a2f200a2c353639 *202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203539202a2f0a2c32 *3133202f2a207769647468202a2f0a2c31333631202f2a20686569676874202a2f0a2c32323720 *2f2a20686f726942656172696e6758202a2f0a2c31303537202f2a20686f726942656172696e67 *59202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64 *65203630202a2f0a2c31313639202f2a207769647468202a2f0a2c31303833202f2a2068656967 *6874202a2f0a2c3134202f2a20686f726942656172696e6758202a2f0a2c31303634202f2a2068 *6f726942656172696e6759202a2f200a2c31313936202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203631202a2f0a2c31303433202f2a207769647468202a2f0a2c36 *3030202f2a20686569676874202a2f0a2c3736202f2a20686f726942656172696e6758202a2f0a *2c383232202f2a20686f726942656172696e6759202a2f200a2c31313936202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f6465203632202a2f0a2c31313639202f2a207769 *647468202a2f0a2c31303833202f2a20686569676874202a2f0a2c3134202f2a20686f72694265 *6172696e6758202a2f0a2c31303634202f2a20686f726942656172696e6759202a2f200a2c3131 *3936202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203633202a2f0a *2c383931202f2a207769647468202a2f0a2c31343838202f2a20686569676874202a2f0a2c3135 *36202f2a20686f726942656172696e6758202a2f0a2c31343838202f2a20686f72694265617269 *6e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f6465203634202a2f0a2c31363236202f2a207769647468202a2f0a2c31353532202f2a2068 *6569676874202a2f0a2c323235202f2a20686f726942656172696e6758202a2f0a2c3135303920 *2f2a20686f726942656172696e6759202a2f200a2c32303739202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f6465203635202a2f0a2c31333131202f2a207769647468202a *2f0a2c31343639202f2a20686569676874202a2f0a2c3330202f2a20686f726942656172696e67 *58202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203636202a2f0a2c31313333 *202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313531202f2a *20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e675920 *2a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *203637202a2f0a2c31333033202f2a207769647468202a2f0a2c31353437202f2a206865696768 *74202a2f0a2c3930202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a20686f *726942656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f6465203638202a2f0a2c31323134202f2a207769647468202a2f0a2c3134 *3639202f2a20686569676874202a2f0a2c313635202f2a20686f726942656172696e6758202a2f *0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f6465203639202a2f0a2c31303836202f2a20 *7769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313735202f2a20686f72 *6942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a *2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520373020 *2a2f0a2c31303139202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f *0a2c313735202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942 *656172696e6759202a2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f6465203731202a2f0a2c31333432202f2a207769647468202a2f0a2c3135343820 *2f2a20686569676874202a2f0a2c3939202f2a20686f726942656172696e6758202a2f0a2c3135 *3039202f2a20686f726942656172696e6759202a2f200a2c31353933202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f6465203732202a2f0a2c31313636202f2a2077696474 *68202a2f0a2c31343639202f2a20686569676874202a2f0a2c313631202f2a20686f7269426561 *72696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c313437 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203733202a2f0a2c *323031202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c323031 *202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e *6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *6465203734202a2f0a2c383432202f2a207769647468202a2f0a2c31353038202f2a2068656967 *6874202a2f0a2c3335202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a2068 *6f726942656172696e6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203735202a2f0a2c31323032202f2a207769647468202a2f0a2c31 *343639202f2a20686569676874202a2f0a2c313536202f2a20686f726942656172696e6758202a *2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f *7269416476616e6365202a2f0a2f2a2043686172636f6465203736202a2f0a2c393433202f2a20 *7769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313536202f2a20686f72 *6942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a *2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520373720 *2a2f0a2c31343038202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f *0a2c313531202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942 *656172696e6759202a2f200a2c31373036202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f6465203738202a2f0a2c31313636202f2a207769647468202a2f0a2c3134363920 *2f2a20686569676874202a2f0a2c313536202f2a20686f726942656172696e6758202a2f0a2c31 *343639202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f6465203739202a2f0a2c31343332202f2a20776964 *7468202a2f0a2c31353532202f2a20686569676874202a2f0a2c3830202f2a20686f7269426561 *72696e6758202a2f0a2c31353039202f2a20686f726942656172696e6759202a2f200a2c313539 *33202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203830202a2f0a2c *31303937202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3137 *35202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f72694265617269 *6e6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f6465203831202a2f0a2c31343332202f2a207769647468202a2f0a2c31363236202f2a2068 *6569676874202a2f0a2c3830202f2a20686f726942656172696e6758202a2f0a2c31353039202f *2a20686f726942656172696e6759202a2f200a2c31353933202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f6465203832202a2f0a2c31323230202f2a207769647468202a2f *0a2c31343639202f2a20686569676874202a2f0a2c313830202f2a20686f726942656172696e67 *58202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203833202a2f0a2c31313734 *202f2a207769647468202a2f0a2c31353532202f2a20686569676874202a2f0a2c3936202f2a20 *686f726942656172696e6758202a2f0a2c31353039202f2a20686f726942656172696e6759202a *2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *3834202a2f0a2c31313932202f2a207769647468202a2f0a2c31343639202f2a20686569676874 *202a2f0a2c3333202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f72 *6942656172696e6759202a2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f6465203835202a2f0a2c31313537202f2a207769647468202a2f0a2c313530 *38202f2a20686569676874202a2f0a2c313730202f2a20686f726942656172696e6758202a2f0a *2c31343639202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f6465203836202a2f0a2c31323832202f2a2077 *69647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3532202f2a20686f726942 *656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31 *333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203837202a2f *0a2c31383638202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c *3337202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172 *696e6759202a2f200a2c31393333202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f6465203838202a2f0a2c31323930202f2a207769647468202a2f0a2c31343639202f2a20 *686569676874202a2f0a2c3432202f2a20686f726942656172696e6758202a2f0a2c3134363920 *2f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f6465203839202a2f0a2c31333039202f2a207769647468202a *2f0a2c31343639202f2a20686569676874202a2f0a2c3432202f2a20686f726942656172696e67 *58202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203930202a2f0a2c31313537 *202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3437202f2a20 *686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a *2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *3931202a2f0a2c333834202f2a207769647468202a2f0a2c31383832202f2a2068656967687420 *2a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31343739202f2a20686f72 *6942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a *2043686172636f6465203932202a2f0a2c373237202f2a207769647468202a2f0a2c3134363920 *2f2a20686569676874202a2f0a2c2d3639202f2a20686f726942656172696e6758202a2f0a2c31 *343639202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f6465203933202a2f0a2c333834202f2a207769647468 *202a2f0a2c31383832202f2a20686569676874202a2f0a2c3437202f2a20686f72694265617269 *6e6758202a2f0a2c31343739202f2a20686f726942656172696e6759202a2f200a2c353639202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203934202a2f0a2c383538 *202f2a207769647468202a2f0a2c383633202f2a20686569676874202a2f0a2c3531202f2a2068 *6f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f *200a2c393631202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203935 *202a2f0a2c31313339202f2a207769647468202a2f0a2c313031202f2a20686569676874202a2f *0a2c30202f2a20686f726942656172696e6758202a2f0a2c2d313535202f2a20686f7269426561 *72696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a204368 *6172636f6465203936202a2f0a2c343035202f2a207769647468202a2f0a2c343035202f2a2068 *6569676874202a2f0a2c3538202f2a20686f726942656172696e6758202a2f0a2c31353032202f *2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f6465203937202a2f0a2c31303133202f2a207769647468202a2f0a *2c31313333202f2a20686569676874202a2f0a2c3832202f2a20686f726942656172696e675820 *2a2f0a2c31303937202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f6465203938202a2f0a2c393433202f2a *207769647468202a2f0a2c31353038202f2a20686569676874202a2f0a2c313138202f2a20686f *726942656172696e6758202a2f0a2c31343734202f2a20686f726942656172696e6759202a2f20 *0a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203939 *202a2f0a2c393137202f2a207769647468202a2f0a2c31313333202f2a20686569676874202a2f *0a2c3539202f2a20686f726942656172696e6758202a2f0a2c31313032202f2a20686f72694265 *6172696e6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a2f2a2043 *686172636f646520313030202a2f0a2c393439202f2a207769647468202a2f0a2c31353132202f *2a20686569676874202a2f0a2c3536202f2a20686f726942656172696e6758202a2f0a2c313437 *34202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520313031202a2f0a2c393738202f2a207769647468 *202a2f0a2c31313335202f2a20686569676874202a2f0a2c3732202f2a20686f72694265617269 *6e6758202a2f0a2c31303937202f2a20686f726942656172696e6759202a2f200a2c3131333920 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313032202a2f0a2c35 *3037202f2a207769647468202a2f0a2c31343930202f2a20686569676874202a2f0a2c3238202f *2a20686f726942656172696e6758202a2f0a2c31343930202f2a20686f726942656172696e6759 *202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *20313033202a2f0a2c393339202f2a207769647468202a2f0a2c31353530202f2a206865696768 *74202a2f0a2c3631202f2a20686f726942656172696e6758202a2f0a2c31303937202f2a20686f *726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520313034202a2f0a2c383733202f2a207769647468202a2f0a2c3134 *3734202f2a20686569676874202a2f0a2c313332202f2a20686f726942656172696e6758202a2f *0a2c31343734202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f646520313035202a2f0a2c313833202f2a20 *7769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313332202f2a20686f72 *6942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a *2c343535202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031303620 *2a2f0a2c333530202f2a207769647468202a2f0a2c31393031202f2a20686569676874202a2f0a *2c2d3338202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f72694265 *6172696e6759202a2f200a2c343535202f2a20686f7269416476616e6365202a2f0a2f2a204368 *6172636f646520313037202a2f0a2c383838202f2a207769647468202a2f0a2c31343639202f2a *20686569676874202a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c313436 *39202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520313038202a2f0a2c313830202f2a207769647468 *202a2f0a2c31343639202f2a20686569676874202a2f0a2c313337202f2a20686f726942656172 *696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c34353520 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313039202a2f0a2c31 *343431202f2a207769647468202a2f0a2c31303935202f2a20686569676874202a2f0a2c313332 *202f2a20686f726942656172696e6758202a2f0a2c31303935202f2a20686f726942656172696e *6759202a2f200a2c31373036202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520313130202a2f0a2c383733202f2a207769647468202a2f0a2c31303937202f2a206865 *69676874202a2f0a2c313332202f2a20686f726942656172696e6758202a2f0a2c31303937202f *2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520313131202a2f0a2c393938202f2a207769647468202a2f *0a2c31313431202f2a20686569676874202a2f0a2c3539202f2a20686f726942656172696e6758 *202a2f0a2c31313032202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f646520313132202a2f0a2c39343320 *2f2a207769647468202a2f0a2c31353234202f2a20686569676874202a2f0a2c313138202f2a20 *686f726942656172696e6758202a2f0a2c31303937202f2a20686f726942656172696e6759202a *2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *313133202a2f0a2c393435202f2a207769647468202a2f0a2c31353232202f2a20686569676874 *202a2f0a2c3630202f2a20686f726942656172696e6758202a2f0a2c31303935202f2a20686f72 *6942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520313134202a2f0a2c353231202f2a207769647468202a2f0a2c313039 *35202f2a20686569676874202a2f0a2c313337202f2a20686f726942656172696e6758202a2f0a *2c31303935202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520313135202a2f0a2c383834202f2a207769 *647468202a2f0a2c31313430202f2a20686569676874202a2f0a2c3636202f2a20686f72694265 *6172696e6758202a2f0a2c31303939202f2a20686f726942656172696e6759202a2f200a2c3130 *3234202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313136202a2f *0a2c343938202f2a207769647468202a2f0a2c31333837202f2a20686569676874202a2f0a2c32 *33202f2a20686f726942656172696e6758202a2f0a2c31333730202f2a20686f72694265617269 *6e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520313137202a2f0a2c383632202f2a207769647468202a2f0a2c31313236202f2a206865 *69676874202a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31303937202f *2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520313138202a2f0a2c393931202f2a207769647468202a2f *0a2c31303731202f2a20686569676874202a2f0a2c3131202f2a20686f726942656172696e6758 *202a2f0a2c31303731202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f646520313139202a2f0a2c31343233 *202f2a207769647468202a2f0a2c31303731202f2a20686569676874202a2f0a2c3138202f2a20 *686f726942656172696e6758202a2f0a2c31303731202f2a20686f726942656172696e6759202a *2f200a2c31343739202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *313230202a2f0a2c393832202f2a207769647468202a2f0a2c31303731202f2a20686569676874 *202a2f0a2c3131202f2a20686f726942656172696e6758202a2f0a2c31303731202f2a20686f72 *6942656172696e6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520313231202a2f0a2c393739202f2a207769647468202a2f0a2c313533 *36202f2a20686569676874202a2f0a2c3231202f2a20686f726942656172696e6758202a2f0a2c *31303937202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520313232202a2f0a2c383936202f2a207769 *647468202a2f0a2c31303937202f2a20686569676874202a2f0a2c3532202f2a20686f72694265 *6172696e6758202a2f0a2c31303937202f2a20686f726942656172696e6759202a2f200a2c3130 *3234202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313233202a2f *0a2c363833202f2a207769647468202a2f0a2c31393133202f2a20686569676874202a2f0a2c2d *3433202f2a20686f726942656172696e6758202a2f0a2c31343935202f2a20686f726942656172 *696e6759202a2f200a2c363834202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520313234202a2f0a2c313731202f2a207769647468202a2f0a2c31343930202f2a2068 *6569676874202a2f0a2c313832202f2a20686f726942656172696e6758202a2f0a2c3134393020 *2f2a20686f726942656172696e6759202a2f200a2c353332202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520313235202a2f0a2c363833202f2a207769647468202a2f *0a2c31393133202f2a20686569676874202a2f0a2c3432202f2a20686f726942656172696e6758 *202a2f0a2c31343935202f2a20686f726942656172696e6759202a2f200a2c363834202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520313236202a2f0a2c3131393020 *2f2a207769647468202a2f0a2c343035202f2a20686569676874202a2f0a2c32202f2a20686f72 *6942656172696e6758202a2f0a2c373235202f2a20686f726942656172696e6759202a2f200a2c *31313936202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031363020 *2a2f0a2c30202f2a207769647468202a2f0a2c30202f2a20686569676874202a2f0a2c30202f2a *20686f726942656172696e6758202a2f0a2c30202f2a20686f726942656172696e6759202a2f20 *0a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313631 *202a2f0a2c323034202f2a207769647468202a2f0a2c31343730202f2a20686569676874202a2f *0a2c323332202f2a20686f726942656172696e6758202a2f0a2c31303731202f2a20686f726942 *656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043 *686172636f646520313632202a2f0a2c393436202f2a207769647468202a2f0a2c31353132202f *2a20686569676874202a2f0a2c313034202f2a20686f726942656172696e6758202a2f0a2c3132 *3735202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f646520313633202a2f0a2c31303336202f2a20776964 *7468202a2f0a2c31353033202f2a20686569676874202a2f0a2c3536202f2a20686f7269426561 *72696e6758202a2f0a2c31343637202f2a20686f726942656172696e6759202a2f200a2c313133 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313634202a2f0a *2c393730202f2a207769647468202a2f0a2c393731202f2a20686569676874202a2f0a2c373520 *2f2a20686f726942656172696e6758202a2f0a2c31313839202f2a20686f726942656172696e67 *59202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *646520313635202a2f0a2c31313738202f2a207769647468202a2f0a2c31343035202f2a206865 *69676874202a2f0a2c2d3331202f2a20686f726942656172696e6758202a2f0a2c31343035202f *2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520313636202a2f0a2c313731202f2a207769647468202a2f *0a2c31343930202f2a20686569676874202a2f0a2c313832202f2a20686f726942656172696e67 *58202a2f0a2c31343930202f2a20686f726942656172696e6759202a2f200a2c353332202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f646520313637202a2f0a2c39373020 *2f2a207769647468202a2f0a2c31393032202f2a20686569676874202a2f0a2c3735202f2a2068 *6f726942656172696e6758202a2f0a2c31343730202f2a20686f726942656172696e6759202a2f *200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031 *3638202a2f0a2c353137202f2a207769647468202a2f0a2c333438202f2a20686569676874202a *2f0a2c3732202f2a20686f726942656172696e6758202a2f0a2c31343435202f2a20686f726942 *656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043 *686172636f646520313639202a2f0a2c31343730202f2a207769647468202a2f0a2c3134363920 *2f2a20686569676874202a2f0a2c3139202f2a20686f726942656172696e6758202a2f0a2c3134 *3639202f2a20686f726942656172696e6759202a2f200a2c31353039202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f646520313730202a2f0a2c363539202f2a2077696474 *68202a2f0a2c363832202f2a20686569676874202a2f0a2c3539202f2a20686f72694265617269 *6e6758202a2f0a2c31353039202f2a20686f726942656172696e6759202a2f200a2c373538202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313731202a2f0a2c3734 *32202f2a207769647468202a2f0a2c363932202f2a20686569676874202a2f0a2c313934202f2a *20686f726942656172696e6758202a2f0a2c393035202f2a20686f726942656172696e6759202a *2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *313732202a2f0a2c31303433202f2a207769647468202a2f0a2c363030202f2a20686569676874 *202a2f0a2c3736202f2a20686f726942656172696e6758202a2f0a2c383232202f2a20686f7269 *42656172696e6759202a2f200a2c31313936202f2a20686f7269416476616e6365202a2f0a2f2a *2043686172636f646520313733202a2f0a2c353032202f2a207769647468202a2f0a2c31383520 *2f2a20686569676874202a2f0a2c3835202f2a20686f726942656172696e6758202a2f0a2c3636 *33202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e *6365202a2f0a2f2a2043686172636f646520313734202a2f0a2c31343637202f2a207769647468 *202a2f0a2c31343639202f2a20686569676874202a2f0a2c3231202f2a20686f72694265617269 *6e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c3135303920 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313735202a2f0a2c36 *3430202f2a207769647468202a2f0a2c313138202f2a20686569676874202a2f0a2c38202f2a20 *686f726942656172696e6758202a2f0a2c31343030202f2a20686f726942656172696e6759202a *2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031 *3736202a2f0a2c363034202f2a207769647468202a2f0a2c363034202f2a20686569676874202a *2f0a2c313131202f2a20686f726942656172696e6758202a2f0a2c31343331202f2a20686f7269 *42656172696e6759202a2f200a2c383139202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f646520313737202a2f0a2c31303433202f2a207769647468202a2f0a2c31303435 *202f2a20686569676874202a2f0a2c3430202f2a20686f726942656172696e6758202a2f0a2c31 *303435202f2a20686f726942656172696e6759202a2f200a2c31313234202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f646520313738202a2f0a2c363430202f2a20776964 *7468202a2f0a2c383631202f2a20686569676874202a2f0a2c3131202f2a20686f726942656172 *696e6758202a2f0a2c31343332202f2a20686f726942656172696e6759202a2f200a2c36383220 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313739202a2f0a2c36 *3437202f2a207769647468202a2f0a2c383839202f2a20686569676874202a2f0a2c37202f2a20 *686f726942656172696e6758202a2f0a2c31343331202f2a20686f726942656172696e6759202a *2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031 *3830202a2f0a2c343035202f2a207769647468202a2f0a2c343035202f2a20686569676874202a *2f0a2c313933202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f7269 *42656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f646520313831202a2f0a2c31313738202f2a207769647468202a2f0a2c31343931 *202f2a20686569676874202a2f0a2c2d3535202f2a20686f726942656172696e6758202a2f0a2c *31303639202f2a20686f726942656172696e6759202a2f200a2c31313830202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520313832202a2f0a2c31303736202f2a2077 *69647468202a2f0a2c31383332202f2a20686569676874202a2f0a2c2d3131202f2a20686f7269 *42656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c *31313030202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031383320 *2a2f0a2c323536202f2a207769647468202a2f0a2c323536202f2a20686569676874202a2f0a2c *313531202f2a20686f726942656172696e6758202a2f0a2c383239202f2a20686f726942656172 *696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520313834202a2f0a2c343430202f2a207769647468202a2f0a2c343631202f2a206865 *69676874202a2f0a2c313031202f2a20686f726942656172696e6758202a2f0a2c30202f2a2068 *6f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520313835202a2f0a2c333832202f2a207769647468202a2f0a2c3835 *35202f2a20686569676874202a2f0a2c3837202f2a20686f726942656172696e6758202a2f0a2c *31343236202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f646520313836202a2f0a2c363532202f2a20776964 *7468202a2f0a2c363832202f2a20686569676874202a2f0a2c3439202f2a20686f726942656172 *696e6758202a2f0a2c31353039202f2a20686f726942656172696e6759202a2f200a2c37343820 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313837202a2f0a2c37 *3432202f2a207769647468202a2f0a2c363932202f2a20686569676874202a2f0a2c313934202f *2a20686f726942656172696e6758202a2f0a2c393035202f2a20686f726942656172696e675920 *2a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *20313838202a2f0a2c31343633202f2a207769647468202a2f0a2c31343639202f2a2068656967 *6874202a2f0a2c313633202f2a20686f726942656172696e6758202a2f0a2c31343331202f2a20 *686f726942656172696e6759202a2f200a2c31373038202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f646520313839202a2f0a2c31353030202f2a207769647468202a2f0a *2c31343639202f2a20686569676874202a2f0a2c3930202f2a20686f726942656172696e675820 *2a2f0a2c31343331202f2a20686f726942656172696e6759202a2f200a2c31373038202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520313930202a2f0a2c3135373020 *2f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3735202f2a2068 *6f726942656172696e6758202a2f0a2c31343331202f2a20686f726942656172696e6759202a2f *200a2c31373038202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031 *3931202a2f0a2c383934202f2a207769647468202a2f0a2c31343839202f2a2068656967687420 *2a2f0a2c313836202f2a20686f726942656172696e6758202a2f0a2c31303736202f2a20686f72 *6942656172696e6759202a2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520313932202a2f0a2c31333131202f2a207769647468202a2f0a2c3138 *3734202f2a20686569676874202a2f0a2c3330202f2a20686f726942656172696e6758202a2f0a *2c31383734202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520313933202a2f0a2c31333131202f2a20 *7769647468202a2f0a2c31383734202f2a20686569676874202a2f0a2c3330202f2a20686f7269 *42656172696e6758202a2f0a2c31383734202f2a20686f726942656172696e6759202a2f200a2c *31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031393420 *2a2f0a2c31333131202f2a207769647468202a2f0a2c31383734202f2a20686569676874202a2f *0a2c3330202f2a20686f726942656172696e6758202a2f0a2c31383734202f2a20686f72694265 *6172696e6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043 *686172636f646520313935202a2f0a2c31333131202f2a207769647468202a2f0a2c3138343120 *2f2a20686569676874202a2f0a2c3330202f2a20686f726942656172696e6758202a2f0a2c3138 *3431202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f646520313936202a2f0a2c31333131202f2a20776964 *7468202a2f0a2c31383137202f2a20686569676874202a2f0a2c3330202f2a20686f7269426561 *72696e6758202a2f0a2c31383137202f2a20686f726942656172696e6759202a2f200a2c313336 *36202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313937202a2f0a *2c31333131202f2a207769647468202a2f0a2c31393436202f2a20686569676874202a2f0a2c33 *30202f2a20686f726942656172696e6758202a2f0a2c31393436202f2a20686f72694265617269 *6e6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520313938202a2f0a2c31393332202f2a207769647468202a2f0a2c31343639202f2a20 *686569676874202a2f0a2c3136202f2a20686f726942656172696e6758202a2f0a2c3134363920 *2f2a20686f726942656172696e6759202a2f200a2c32303438202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f646520313939202a2f0a2c31333033202f2a20776964746820 *2a2f0a2c31393730202f2a20686569676874202a2f0a2c3930202f2a20686f726942656172696e *6758202a2f0a2c31353039202f2a20686f726942656172696e6759202a2f200a2c31343739202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323030202a2f0a2c3130 *3836202f2a207769647468202a2f0a2c31383734202f2a20686569676874202a2f0a2c31373520 *2f2a20686f726942656172696e6758202a2f0a2c31383734202f2a20686f726942656172696e67 *59202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *646520323031202a2f0a2c31303836202f2a207769647468202a2f0a2c31383734202f2a206865 *69676874202a2f0a2c313735202f2a20686f726942656172696e6758202a2f0a2c31383734202f *2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520323032202a2f0a2c31303836202f2a207769647468202a *2f0a2c31383734202f2a20686569676874202a2f0a2c313735202f2a20686f726942656172696e *6758202a2f0a2c31383734202f2a20686f726942656172696e6759202a2f200a2c31333636202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323033202a2f0a2c3130 *3836202f2a207769647468202a2f0a2c31383137202f2a20686569676874202a2f0a2c31373520 *2f2a20686f726942656172696e6758202a2f0a2c31383137202f2a20686f726942656172696e67 *59202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *646520323034202a2f0a2c343035202f2a207769647468202a2f0a2c31383733202f2a20686569 *676874202a2f0a2c32202f2a20686f726942656172696e6758202a2f0a2c31383733202f2a2068 *6f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520323035202a2f0a2c343035202f2a207769647468202a2f0a2c3138 *3730202f2a20686569676874202a2f0a2c313337202f2a20686f726942656172696e6758202a2f *0a2c31383730202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520323036202a2f0a2c353937202f2a2077 *69647468202a2f0a2c31383738202f2a20686569676874202a2f0a2c2d3236202f2a20686f7269 *42656172696e6758202a2f0a2c31383738202f2a20686f726942656172696e6759202a2f200a2c *353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323037202a *2f0a2c353137202f2a207769647468202a2f0a2c31383133202f2a20686569676874202a2f0a2c *3136202f2a20686f726942656172696e6758202a2f0a2c31383133202f2a20686f726942656172 *696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520323038202a2f0a2c31333436202f2a207769647468202a2f0a2c31343639202f2a20 *686569676874202a2f0a2c3333202f2a20686f726942656172696e6758202a2f0a2c3134363920 *2f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f646520323039202a2f0a2c31313636202f2a20776964746820 *2a2f0a2c31383431202f2a20686569676874202a2f0a2c313536202f2a20686f72694265617269 *6e6758202a2f0a2c31383431202f2a20686f726942656172696e6759202a2f200a2c3134373920 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323130202a2f0a2c31 *343332202f2a207769647468202a2f0a2c31393537202f2a20686569676874202a2f0a2c383020 *2f2a20686f726942656172696e6758202a2f0a2c31393134202f2a20686f726942656172696e67 *59202a2f200a2c31353933202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *646520323131202a2f0a2c31343332202f2a207769647468202a2f0a2c31393537202f2a206865 *69676874202a2f0a2c3830202f2a20686f726942656172696e6758202a2f0a2c31393134202f2a *20686f726942656172696e6759202a2f200a2c31353933202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f646520323132202a2f0a2c31343332202f2a207769647468202a2f *0a2c31393537202f2a20686569676874202a2f0a2c3830202f2a20686f726942656172696e6758 *202a2f0a2c31393134202f2a20686f726942656172696e6759202a2f200a2c31353933202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f646520323133202a2f0a2c31343332 *202f2a207769647468202a2f0a2c31393234202f2a20686569676874202a2f0a2c3830202f2a20 *686f726942656172696e6758202a2f0a2c31383831202f2a20686f726942656172696e6759202a *2f200a2c31353933202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *323134202a2f0a2c31343332202f2a207769647468202a2f0a2c31393030202f2a206865696768 *74202a2f0a2c3830202f2a20686f726942656172696e6758202a2f0a2c31383537202f2a20686f *726942656172696e6759202a2f200a2c31353933202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520323135202a2f0a2c393938202f2a207769647468202a2f0a2c3939 *38202f2a20686569676874202a2f0a2c313030202f2a20686f726942656172696e6758202a2f0a *2c31303231202f2a20686f726942656172696e6759202a2f200a2c31313936202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520323136202a2f0a2c31343436202f2a20 *7769647468202a2f0a2c31353533202f2a20686569676874202a2f0a2c3636202f2a20686f7269 *42656172696e6758202a2f0a2c31353130202f2a20686f726942656172696e6759202a2f200a2c *31353933202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032313720 *2a2f0a2c31313537202f2a207769647468202a2f0a2c31393133202f2a20686569676874202a2f *0a2c313730202f2a20686f726942656172696e6758202a2f0a2c31383734202f2a20686f726942 *656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f646520323138202a2f0a2c31313537202f2a207769647468202a2f0a2c31393133 *202f2a20686569676874202a2f0a2c313730202f2a20686f726942656172696e6758202a2f0a2c *31383734202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520323139202a2f0a2c31313537202f2a2077 *69647468202a2f0a2c31393133202f2a20686569676874202a2f0a2c313730202f2a20686f7269 *42656172696e6758202a2f0a2c31383734202f2a20686f726942656172696e6759202a2f200a2c *31343739202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032323020 *2a2f0a2c31313537202f2a207769647468202a2f0a2c31383536202f2a20686569676874202a2f *0a2c313730202f2a20686f726942656172696e6758202a2f0a2c31383137202f2a20686f726942 *656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f646520323231202a2f0a2c31333039202f2a207769647468202a2f0a2c31383734 *202f2a20686569676874202a2f0a2c3432202f2a20686f726942656172696e6758202a2f0a2c31 *383734202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f646520323232202a2f0a2c31303938202f2a207769 *647468202a2f0a2c31343637202f2a20686569676874202a2f0a2c313734202f2a20686f726942 *656172696e6758202a2f0a2c31343637202f2a20686f726942656172696e6759202a2f200a2c31 *333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323233202a *2f0a2c393037202f2a207769647468202a2f0a2c31353230202f2a20686569676874202a2f0a2c *313939202f2a20686f726942656172696e6758202a2f0a2c31343931202f2a20686f7269426561 *72696e6759202a2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f2a204368 *6172636f646520323234202a2f0a2c31303133202f2a207769647468202a2f0a2c31353338202f *2a20686569676874202a2f0a2c3832202f2a20686f726942656172696e6758202a2f0a2c313530 *32202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520323235202a2f0a2c31303133202f2a2077696474 *68202a2f0a2c31353338202f2a20686569676874202a2f0a2c3832202f2a20686f726942656172 *696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c31313339 *202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323236202a2f0a2c *31303133202f2a207769647468202a2f0a2c31353338202f2a20686569676874202a2f0a2c3832 *202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e *6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520323237202a2f0a2c31303133202f2a207769647468202a2f0a2c31353035202f2a2068 *6569676874202a2f0a2c3832202f2a20686f726942656172696e6758202a2f0a2c31343639202f *2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520323238202a2f0a2c31303133202f2a207769647468202a *2f0a2c31343831202f2a20686569676874202a2f0a2c3832202f2a20686f726942656172696e67 *58202a2f0a2c31343435202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323239202a2f0a2c313031 *33202f2a207769647468202a2f0a2c31363632202f2a20686569676874202a2f0a2c3832202f2a *20686f726942656172696e6758202a2f0a2c31363236202f2a20686f726942656172696e675920 *2a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *20323330202a2f0a2c31363632202f2a207769647468202a2f0a2c31313333202f2a2068656967 *6874202a2f0a2c3733202f2a20686f726942656172696e6758202a2f0a2c31303937202f2a2068 *6f726942656172696e6759202a2f200a2c31383231202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f646520323331202a2f0a2c393137202f2a207769647468202a2f0a2c31 *353633202f2a20686569676874202a2f0a2c3539202f2a20686f726942656172696e6758202a2f *0a2c31313032202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f646520323332202a2f0a2c393738202f2a20 *7769647468202a2f0a2c31353430202f2a20686569676874202a2f0a2c3732202f2a20686f7269 *42656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c *31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032333320 *2a2f0a2c393738202f2a207769647468202a2f0a2c31353430202f2a20686569676874202a2f0a *2c3732202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f7269426561 *72696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a204368 *6172636f646520323334202a2f0a2c393738202f2a207769647468202a2f0a2c31353430202f2a *20686569676874202a2f0a2c3732202f2a20686f726942656172696e6758202a2f0a2c31353032 *202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e *6365202a2f0a2f2a2043686172636f646520323335202a2f0a2c393738202f2a20776964746820 *2a2f0a2c31343833202f2a20686569676874202a2f0a2c3732202f2a20686f726942656172696e *6758202a2f0a2c31343435202f2a20686f726942656172696e6759202a2f200a2c31313339202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323336202a2f0a2c3430 *35202f2a207769647468202a2f0a2c31353032202f2a20686569676874202a2f0a2c3133202f2a *20686f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e675920 *2a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *323337202a2f0a2c343035202f2a207769647468202a2f0a2c31353032202f2a20686569676874 *202a2f0a2c313433202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f *726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520323338202a2f0a2c353937202f2a207769647468202a2f0a2c313530 *32202f2a20686569676874202a2f0a2c2d3137202f2a20686f726942656172696e6758202a2f0a *2c31353032202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520323339202a2f0a2c353137202f2a207769 *647468202a2f0a2c31343435202f2a20686569676874202a2f0a2c3232202f2a20686f72694265 *6172696e6758202a2f0a2c31343435202f2a20686f726942656172696e6759202a2f200a2c3536 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323430202a2f0a *2c31303030202f2a207769647468202a2f0a2c31363630202f2a20686569676874202a2f0a2c36 *31202f2a20686f726942656172696e6758202a2f0a2c31363233202f2a20686f72694265617269 *6e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520323431202a2f0a2c383733202f2a207769647468202a2f0a2c31343639202f2a2068 *6569676874202a2f0a2c313332202f2a20686f726942656172696e6758202a2f0a2c3134363920 *2f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f646520323432202a2f0a2c393938202f2a207769647468202a *2f0a2c31353431202f2a20686569676874202a2f0a2c3539202f2a20686f726942656172696e67 *58202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323433202a2f0a2c393938 *202f2a207769647468202a2f0a2c31353431202f2a20686569676874202a2f0a2c3539202f2a20 *686f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a *2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *323434202a2f0a2c393938202f2a207769647468202a2f0a2c31353431202f2a20686569676874 *202a2f0a2c3539202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f72 *6942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520323435202a2f0a2c393938202f2a207769647468202a2f0a2c313530 *38202f2a20686569676874202a2f0a2c3539202f2a20686f726942656172696e6758202a2f0a2c *31343639202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520323436202a2f0a2c393938202f2a207769 *647468202a2f0a2c31343834202f2a20686569676874202a2f0a2c3539202f2a20686f72694265 *6172696e6758202a2f0a2c31343435202f2a20686f726942656172696e6759202a2f200a2c3131 *3339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323437202a2f *0a2c31303433202f2a207769647468202a2f0a2c31303033202f2a20686569676874202a2f0a2c *3430202f2a20686f726942656172696e6758202a2f0a2c31303234202f2a20686f726942656172 *696e6759202a2f200a2c31313234202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f646520323438202a2f0a2c31303435202f2a207769647468202a2f0a2c31313539202f2a *20686569676874202a2f0a2c3932202f2a20686f726942656172696e6758202a2f0a2c31313131 *202f2a20686f726942656172696e6759202a2f200a2c31323531202f2a20686f7269416476616e *6365202a2f0a2f2a2043686172636f646520323439202a2f0a2c383632202f2a20776964746820 *2a2f0a2c31353331202f2a20686569676874202a2f0a2c313238202f2a20686f72694265617269 *6e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c3131333920 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323530202a2f0a2c38 *3632202f2a207769647468202a2f0a2c31353331202f2a20686569676874202a2f0a2c31323820 *2f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e67 *59202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *646520323531202a2f0a2c383632202f2a207769647468202a2f0a2c31353331202f2a20686569 *676874202a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a *20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f646520323532202a2f0a2c383632202f2a207769647468202a2f0a *2c31343734202f2a20686569676874202a2f0a2c313238202f2a20686f726942656172696e6758 *202a2f0a2c31343435202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f646520323533202a2f0a2c39373920 *2f2a207769647468202a2f0a2c31393431202f2a20686569676874202a2f0a2c3231202f2a2068 *6f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f *200a2c31303234202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032 *3534202a2f0a2c393337202f2a207769647468202a2f0a2c31383932202f2a2068656967687420 *2a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31343535202f2a20686f72 *6942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520323535202a2f0a2c393739202f2a207769647468202a2f0a2c313838 *34202f2a20686569676874202a2f0a2c3231202f2a20686f726942656172696e6758202a2f0a2c *31343435202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a20686f726941 *6476616e6365202a2f0a7d3b0a73746174696320636f6e737420756e7369676e6564206c6f6e67 *20666d65747269635b5d3d7b0a31393332202f2a206d61785f7769647468202a2f0a2c31393730 *202f2a206d61785f686569676874202a2f0a2c323337202f2a206d61785f686f72694265617269 *6e6758202a2f0a2c31393436202f2a206d61785f686f726942656172696e6759202a2f0a2c3230 *3739202f2a206d61785f686f7269416476616e6365202a2f0a7d3b0a23656e6469660a newhex *2369666e646566205f4d4554524943535f485f0a23646566696e65205f4d4554524943535f485f *0a2f2a4e6220666163657320320a48656c76657469636120526567756c6172202a2f0a2f2a2063 *6861726d6170203a20756e6963202a2f0a2f2a20636861726d6170203a2061726d6e202a2f0a2f *2a20636861726d6170203a2061726d6e202a2f0a2f2a20636861726d6170203a2061726d6e202a *2f0a2f2a20636861726d6170203a2061726d6e202a2f0a2f2a20636861726d6170203a2061726d *6e202a2f0a2f2a20636861726d6170203a2061726d6e202a2f0a2f2a20636861726d6170203a20 *61726d6e202a2f0a2f2a20636861726d6170203a2000000000202a2f0a2f2a20636861726d6170 *203a2000000000202a2f0a73746174696320636f6e737420756e7369676e6564206c6f6e672067 *6d65747269635b5d3d7b0a2f2a2043686172636f64652030202a2f0a30202f2a20776964746820 *2a2f0a2c30202f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a *2f0a2c30202f2a20686f726942656172696e6759202a2f200a2c30202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f64652031202a2f0a2c300a2c300a2c300a2c300a2c300a *2f2a2043686172636f64652032202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172 *636f64652033202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203420 *2a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f64652035202a2f0a2c300a2c *300a2c300a2c300a2c300a2f2a2043686172636f64652036202a2f0a2c300a2c300a2c300a2c30 *0a2c300a2f2a2043686172636f64652037202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a20 *43686172636f64652038202a2f0a2c30202f2a207769647468202a2f0a2c30202f2a2068656967 *6874202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f2a20686f726942 *656172696e6759202a2f200a2c30202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f64652039202a2f0a2c30202f2a207769647468202a2f0a2c30202f2a2068656967687420 *2a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f2a20686f726942656172 *696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f6465203130202a2f0a2c30202f2a207769647468202a2f0a2c30202f2a2068656967687420 *2a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f2a20686f726942656172 *696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f6465203131202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f64652031 *32202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203133202a2f0a2c *30202f2a207769647468202a2f0a2c30202f2a20686569676874202a2f0a2c30202f2a20686f72 *6942656172696e6758202a2f0a2c30202f2a20686f726942656172696e6759202a2f200a2c3536 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203134202a2f0a2c *300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203135202a2f0a2c300a2c300a2c *300a2c300a2c300a2f2a2043686172636f6465203136202a2f0a2c300a2c300a2c300a2c300a2c *300a2f2a2043686172636f6465203137202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043 *686172636f6465203138202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f64 *65203139202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203230202a *2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203231202a2f0a2c300a2c *300a2c300a2c300a2c300a2f2a2043686172636f6465203232202a2f0a2c300a2c300a2c300a2c *300a2c300a2f2a2043686172636f6465203233202a2f0a2c300a2c300a2c300a2c300a2c300a2f *2a2043686172636f6465203234202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172 *636f6465203235202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f64652032 *36202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203237202a2f0a2c *300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203238202a2f0a2c300a2c300a2c *300a2c300a2c300a2f2a2043686172636f6465203239202a2f0a2c30202f2a207769647468202a *2f0a2c30202f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f *0a2c30202f2a20686f726942656172696e6759202a2f200a2c30202f2a20686f7269416476616e *6365202a2f0a2f2a2043686172636f6465203330202a2f0a2c300a2c300a2c300a2c300a2c300a *2f2a2043686172636f6465203331202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a20436861 *72636f6465203332202a2f0a2c30202f2a207769647468202a2f0a2c30202f2a20686569676874 *202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f2a20686f7269426561 *72696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f6465203333202a2f0a2c323033202f2a207769647468202a2f0a2c31343639202f2a2068 *6569676874202a2f0a2c323337202f2a20686f726942656172696e6758202a2f0a2c3134363920 *2f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f6465203334202a2f0a2c353234202f2a207769647468202a2f0a *2c353838202f2a20686569676874202a2f0a2c313034202f2a20686f726942656172696e675820 *2a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c373237202f2a20686f *7269416476616e6365202a2f0a2f2a2043686172636f6465203335202a2f0a2c31313337202f2a *207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c30202f2a20686f7269 *42656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c *31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203336202a *2f0a2c393937202f2a207769647468202a2f0a2c31383235202f2a20686569676874202a2f0a2c *3634202f2a20686f726942656172696e6758202a2f0a2c31353838202f2a20686f726942656172 *696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f6465203337202a2f0a2c31363738202f2a207769647468202a2f0a2c31343634202f2a20 *686569676874202a2f0a2c3636202f2a20686f726942656172696e6758202a2f0a2c3134323620 *2f2a20686f726942656172696e6759202a2f200a2c31383231202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f6465203338202a2f0a2c31323331202f2a207769647468202a *2f0a2c31353031202f2a20686569676874202a2f0a2c3839202f2a20686f726942656172696e67 *58202a2f0a2c31343637202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203339202a2f0a2c31383220 *2f2a207769647468202a2f0a2c353838202f2a20686569676874202a2f0a2c313031202f2a2068 *6f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f *200a2c333931202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203430 *202a2f0a2c343637202f2a207769647468202a2f0a2c31393131202f2a20686569676874202a2f *0a2c313432202f2a20686f726942656172696e6758202a2f0a2c31343933202f2a20686f726942 *656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043 *686172636f6465203431202a2f0a2c343637202f2a207769647468202a2f0a2c31393131202f2a *20686569676874202a2f0a2c3638202f2a20686f726942656172696e6758202a2f0a2c31343933 *202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f6465203432202a2f0a2c363330202f2a207769647468202a2f *0a2c353838202f2a20686569676874202a2f0a2c3738202f2a20686f726942656172696e675820 *2a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c373937202f2a20686f *7269416476616e6365202a2f0a2f2a2043686172636f6465203433202a2f0a2c31303433202f2a *207769647468202a2f0a2c31303435202f2a20686569676874202a2f0a2c3736202f2a20686f72 *6942656172696e6758202a2f0a2c31303435202f2a20686f726942656172696e6759202a2f200a *2c31313936202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520343420 *2a2f0a2c323134202f2a207769647468202a2f0a2c353232202f2a20686569676874202a2f0a2c *313730202f2a20686f726942656172696e6758202a2f0a2c323138202f2a20686f726942656172 *696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f6465203435202a2f0a2c353032202f2a207769647468202a2f0a2c313835202f2a20686569 *676874202a2f0a2c3835202f2a20686f726942656172696e6758202a2f0a2c363633202f2a2068 *6f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f6465203436202a2f0a2c323039202f2a207769647468202a2f0a2c323138 *202f2a20686569676874202a2f0a2c313735202f2a20686f726942656172696e6758202a2f0a2c *323138202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f6465203437202a2f0a2c363138202f2a207769647468 *202a2f0a2c31343639202f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e *6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c353639202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203438202a2f0a2c39383820 *2f2a207769647468202a2f0a2c31343731202f2a20686569676874202a2f0a2c3634202f2a2068 *6f726942656172696e6758202a2f0a2c31343332202f2a20686f726942656172696e6759202a2f *200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652034 *39202a2f0a2c353239202f2a207769647468202a2f0a2c31343236202f2a20686569676874202a *2f0a2c313936202f2a20686f726942656172696e6758202a2f0a2c31343236202f2a20686f7269 *42656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a *2043686172636f6465203530202a2f0a2c393930202f2a207769647468202a2f0a2c3134333720 *2f2a20686569676874202a2f0a2c3634202f2a20686f726942656172696e6758202a2f0a2c3134 *3337202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f6465203531202a2f0a2c31303031202f2a2077696474 *68202a2f0a2c31343733202f2a20686569676874202a2f0a2c3439202f2a20686f726942656172 *696e6758202a2f0a2c31343334202f2a20686f726942656172696e6759202a2f200a2c31313339 *202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203532202a2f0a2c31 *303139202f2a207769647468202a2f0a2c31343336202f2a20686569676874202a2f0a2c353220 *2f2a20686f726942656172696e6758202a2f0a2c31343336202f2a20686f726942656172696e67 *59202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *6465203533202a2f0a2c393836202f2a207769647468202a2f0a2c31343434202f2a2068656967 *6874202a2f0a2c3636202f2a20686f726942656172696e6758202a2f0a2c31343038202f2a2068 *6f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203534202a2f0a2c393832202f2a207769647468202a2f0a2c3134 *3735202f2a20686569676874202a2f0a2c3737202f2a20686f726942656172696e6758202a2f0a *2c31343338202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f6465203535202a2f0a2c393936202f2a207769 *647468202a2f0a2c31343038202f2a20686569676874202a2f0a2c3735202f2a20686f72694265 *6172696e6758202a2f0a2c31343038202f2a20686f726942656172696e6759202a2f200a2c3131 *3339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203536202a2f0a *2c393834202f2a207769647468202a2f0a2c31343737202f2a20686569676874202a2f0a2c3636 *202f2a20686f726942656172696e6758202a2f0a2c31343336202f2a20686f726942656172696e *6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f6465203537202a2f0a2c393638202f2a207769647468202a2f0a2c31343734202f2a20686569 *676874202a2f0a2c3733202f2a20686f726942656172696e6758202a2f0a2c31343334202f2a20 *686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f6465203538202a2f0a2c323039202f2a207769647468202a2f0a2c31 *303537202f2a20686569676874202a2f0a2c323237202f2a20686f726942656172696e6758202a *2f0a2c31303537202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f6465203539202a2f0a2c323133202f2a2077 *69647468202a2f0a2c31333631202f2a20686569676874202a2f0a2c323237202f2a20686f7269 *42656172696e6758202a2f0a2c31303537202f2a20686f726942656172696e6759202a2f200a2c *353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203630202a2f *0a2c31313639202f2a207769647468202a2f0a2c31303833202f2a20686569676874202a2f0a2c *3134202f2a20686f726942656172696e6758202a2f0a2c31303634202f2a20686f726942656172 *696e6759202a2f200a2c31313936202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f6465203631202a2f0a2c31303433202f2a207769647468202a2f0a2c363030202f2a2068 *6569676874202a2f0a2c3736202f2a20686f726942656172696e6758202a2f0a2c383232202f2a *20686f726942656172696e6759202a2f200a2c31313936202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f6465203632202a2f0a2c31313639202f2a207769647468202a2f0a *2c31303833202f2a20686569676874202a2f0a2c3134202f2a20686f726942656172696e675820 *2a2f0a2c31303634202f2a20686f726942656172696e6759202a2f200a2c31313936202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f6465203633202a2f0a2c383931202f2a *207769647468202a2f0a2c31343838202f2a20686569676874202a2f0a2c313536202f2a20686f *726942656172696e6758202a2f0a2c31343838202f2a20686f726942656172696e6759202a2f20 *0a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203634 *202a2f0a2c31363236202f2a207769647468202a2f0a2c31353532202f2a20686569676874202a *2f0a2c323235202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a20686f7269 *42656172696e6759202a2f200a2c32303739202f2a20686f7269416476616e6365202a2f0a2f2a *2043686172636f6465203635202a2f0a2c31333131202f2a207769647468202a2f0a2c31343639 *202f2a20686569676874202a2f0a2c3330202f2a20686f726942656172696e6758202a2f0a2c31 *343639202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f6465203636202a2f0a2c31313333202f2a20776964 *7468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313531202f2a20686f72694265 *6172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c3133 *3636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203637202a2f0a *2c31333033202f2a207769647468202a2f0a2c31353437202f2a20686569676874202a2f0a2c39 *30202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a20686f72694265617269 *6e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f6465203638202a2f0a2c31323134202f2a207769647468202a2f0a2c31343639202f2a2068 *6569676874202a2f0a2c313635202f2a20686f726942656172696e6758202a2f0a2c3134363920 *2f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f6465203639202a2f0a2c31303836202f2a207769647468202a *2f0a2c31343639202f2a20686569676874202a2f0a2c313735202f2a20686f726942656172696e *6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31333636202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203730202a2f0a2c313031 *39202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313735202f *2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759 *202a2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64 *65203731202a2f0a2c31333432202f2a207769647468202a2f0a2c31353438202f2a2068656967 *6874202a2f0a2c3939202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a2068 *6f726942656172696e6759202a2f200a2c31353933202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203732202a2f0a2c31313636202f2a207769647468202a2f0a2c31 *343639202f2a20686569676874202a2f0a2c313631202f2a20686f726942656172696e6758202a *2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f *7269416476616e6365202a2f0a2f2a2043686172636f6465203733202a2f0a2c323031202f2a20 *7769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c323031202f2a20686f72 *6942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a *2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203734202a *2f0a2c383432202f2a207769647468202a2f0a2c31353038202f2a20686569676874202a2f0a2c *3335202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172 *696e6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f6465203735202a2f0a2c31323032202f2a207769647468202a2f0a2c31343639202f2a20 *686569676874202a2f0a2c313536202f2a20686f726942656172696e6758202a2f0a2c31343639 *202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f7269416476616e *6365202a2f0a2f2a2043686172636f6465203736202a2f0a2c393433202f2a207769647468202a *2f0a2c31343639202f2a20686569676874202a2f0a2c313536202f2a20686f726942656172696e *6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31313339202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203737202a2f0a2c313430 *38202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313531202f *2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759 *202a2f200a2c31373036202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64 *65203738202a2f0a2c31313636202f2a207769647468202a2f0a2c31343639202f2a2068656967 *6874202a2f0a2c313536202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20 *686f726942656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f6465203739202a2f0a2c31343332202f2a207769647468202a2f0a2c *31353532202f2a20686569676874202a2f0a2c3830202f2a20686f726942656172696e6758202a *2f0a2c31353039202f2a20686f726942656172696e6759202a2f200a2c31353933202f2a20686f *7269416476616e6365202a2f0a2f2a2043686172636f6465203830202a2f0a2c31303937202f2a *207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313735202f2a20686f *726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f20 *0a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203831 *202a2f0a2c31343332202f2a207769647468202a2f0a2c31363236202f2a20686569676874202a *2f0a2c3830202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a20686f726942 *656172696e6759202a2f200a2c31353933202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f6465203832202a2f0a2c31323230202f2a207769647468202a2f0a2c3134363920 *2f2a20686569676874202a2f0a2c313830202f2a20686f726942656172696e6758202a2f0a2c31 *343639202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f6465203833202a2f0a2c31313734202f2a20776964 *7468202a2f0a2c31353532202f2a20686569676874202a2f0a2c3936202f2a20686f7269426561 *72696e6758202a2f0a2c31353039202f2a20686f726942656172696e6759202a2f200a2c313336 *36202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203834202a2f0a2c *31313932202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3333 *202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e *6759202a2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f6465203835202a2f0a2c31313537202f2a207769647468202a2f0a2c31353038202f2a206865 *69676874202a2f0a2c313730202f2a20686f726942656172696e6758202a2f0a2c31343639202f *2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f6465203836202a2f0a2c31323832202f2a207769647468202a2f *0a2c31343639202f2a20686569676874202a2f0a2c3532202f2a20686f726942656172696e6758 *202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f6465203837202a2f0a2c3138363820 *2f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3337202f2a2068 *6f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f *200a2c31393333202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652038 *38202a2f0a2c31323930202f2a207769647468202a2f0a2c31343639202f2a2068656967687420 *2a2f0a2c3432202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f7269 *42656172696e6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a *2043686172636f6465203839202a2f0a2c31333039202f2a207769647468202a2f0a2c31343639 *202f2a20686569676874202a2f0a2c3432202f2a20686f726942656172696e6758202a2f0a2c31 *343639202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f6465203930202a2f0a2c31313537202f2a20776964 *7468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3437202f2a20686f7269426561 *72696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c313235 *31202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203931202a2f0a2c *333834202f2a207769647468202a2f0a2c31383832202f2a20686569676874202a2f0a2c313238 *202f2a20686f726942656172696e6758202a2f0a2c31343739202f2a20686f726942656172696e *6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *6465203932202a2f0a2c373237202f2a207769647468202a2f0a2c31343639202f2a2068656967 *6874202a2f0a2c2d3639202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20 *686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203933202a2f0a2c333834202f2a207769647468202a2f0a2c3138 *3832202f2a20686569676874202a2f0a2c3437202f2a20686f726942656172696e6758202a2f0a *2c31343739202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f6465203934202a2f0a2c383538202f2a20776964 *7468202a2f0a2c383633202f2a20686569676874202a2f0a2c3531202f2a20686f726942656172 *696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c39363120 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203935202a2f0a2c3131 *3339202f2a207769647468202a2f0a2c313031202f2a20686569676874202a2f0a2c30202f2a20 *686f726942656172696e6758202a2f0a2c2d313535202f2a20686f726942656172696e6759202a *2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *3936202a2f0a2c343035202f2a207769647468202a2f0a2c343035202f2a20686569676874202a *2f0a2c3538202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f726942 *656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043 *686172636f6465203937202a2f0a2c31303133202f2a207769647468202a2f0a2c31313333202f *2a20686569676874202a2f0a2c3832202f2a20686f726942656172696e6758202a2f0a2c313039 *37202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f6465203938202a2f0a2c393433202f2a20776964746820 *2a2f0a2c31353038202f2a20686569676874202a2f0a2c313138202f2a20686f72694265617269 *6e6758202a2f0a2c31343734202f2a20686f726942656172696e6759202a2f200a2c3131333920 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203939202a2f0a2c3931 *37202f2a207769647468202a2f0a2c31313333202f2a20686569676874202a2f0a2c3539202f2a *20686f726942656172696e6758202a2f0a2c31313032202f2a20686f726942656172696e675920 *2a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *20313030202a2f0a2c393439202f2a207769647468202a2f0a2c31353132202f2a206865696768 *74202a2f0a2c3536202f2a20686f726942656172696e6758202a2f0a2c31343734202f2a20686f *726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520313031202a2f0a2c393738202f2a207769647468202a2f0a2c3131 *3335202f2a20686569676874202a2f0a2c3732202f2a20686f726942656172696e6758202a2f0a *2c31303937202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520313032202a2f0a2c353037202f2a2077 *69647468202a2f0a2c31343930202f2a20686569676874202a2f0a2c3238202f2a20686f726942 *656172696e6758202a2f0a2c31343930202f2a20686f726942656172696e6759202a2f200a2c35 *3639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313033202a2f *0a2c393339202f2a207769647468202a2f0a2c31353530202f2a20686569676874202a2f0a2c36 *31202f2a20686f726942656172696e6758202a2f0a2c31303937202f2a20686f72694265617269 *6e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520313034202a2f0a2c383733202f2a207769647468202a2f0a2c31343734202f2a2068 *6569676874202a2f0a2c313332202f2a20686f726942656172696e6758202a2f0a2c3134373420 *2f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f646520313035202a2f0a2c313833202f2a207769647468202a *2f0a2c31343639202f2a20686569676874202a2f0a2c313332202f2a20686f726942656172696e *6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c343535202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313036202a2f0a2c333530 *202f2a207769647468202a2f0a2c31393031202f2a20686569676874202a2f0a2c2d3338202f2a *20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e675920 *2a2f200a2c343535202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *313037202a2f0a2c383838202f2a207769647468202a2f0a2c31343639202f2a20686569676874 *202a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f *726942656172696e6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520313038202a2f0a2c313830202f2a207769647468202a2f0a2c3134 *3639202f2a20686569676874202a2f0a2c313337202f2a20686f726942656172696e6758202a2f *0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c343535202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520313039202a2f0a2c31343431202f2a20 *7769647468202a2f0a2c31303935202f2a20686569676874202a2f0a2c313332202f2a20686f72 *6942656172696e6758202a2f0a2c31303935202f2a20686f726942656172696e6759202a2f200a *2c31373036202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313130 *202a2f0a2c383733202f2a207769647468202a2f0a2c31303937202f2a20686569676874202a2f *0a2c313332202f2a20686f726942656172696e6758202a2f0a2c31303937202f2a20686f726942 *656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f646520313131202a2f0a2c393938202f2a207769647468202a2f0a2c3131343120 *2f2a20686569676874202a2f0a2c3539202f2a20686f726942656172696e6758202a2f0a2c3131 *3032202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f646520313132202a2f0a2c393433202f2a2077696474 *68202a2f0a2c31353234202f2a20686569676874202a2f0a2c313138202f2a20686f7269426561 *72696e6758202a2f0a2c31303937202f2a20686f726942656172696e6759202a2f200a2c313133 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313133202a2f0a *2c393435202f2a207769647468202a2f0a2c31353232202f2a20686569676874202a2f0a2c3630 *202f2a20686f726942656172696e6758202a2f0a2c31303935202f2a20686f726942656172696e *6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520313134202a2f0a2c353231202f2a207769647468202a2f0a2c31303935202f2a206865 *69676874202a2f0a2c313337202f2a20686f726942656172696e6758202a2f0a2c31303935202f *2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f646520313135202a2f0a2c383834202f2a207769647468202a2f0a *2c31313430202f2a20686569676874202a2f0a2c3636202f2a20686f726942656172696e675820 *2a2f0a2c31303939202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520313136202a2f0a2c343938202f *2a207769647468202a2f0a2c31333837202f2a20686569676874202a2f0a2c3233202f2a20686f *726942656172696e6758202a2f0a2c31333730202f2a20686f726942656172696e6759202a2f20 *0a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313137 *202a2f0a2c383632202f2a207769647468202a2f0a2c31313236202f2a20686569676874202a2f *0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31303937202f2a20686f726942 *656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f646520313138202a2f0a2c393931202f2a207769647468202a2f0a2c3130373120 *2f2a20686569676874202a2f0a2c3131202f2a20686f726942656172696e6758202a2f0a2c3130 *3731202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f646520313139202a2f0a2c31343233202f2a20776964 *7468202a2f0a2c31303731202f2a20686569676874202a2f0a2c3138202f2a20686f7269426561 *72696e6758202a2f0a2c31303731202f2a20686f726942656172696e6759202a2f200a2c313437 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313230202a2f0a *2c393832202f2a207769647468202a2f0a2c31303731202f2a20686569676874202a2f0a2c3131 *202f2a20686f726942656172696e6758202a2f0a2c31303731202f2a20686f726942656172696e *6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520313231202a2f0a2c393739202f2a207769647468202a2f0a2c31353336202f2a206865 *69676874202a2f0a2c3231202f2a20686f726942656172696e6758202a2f0a2c31303937202f2a *20686f726942656172696e6759202a2f200a2c31303234202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f646520313232202a2f0a2c383936202f2a207769647468202a2f0a *2c31303937202f2a20686569676874202a2f0a2c3532202f2a20686f726942656172696e675820 *2a2f0a2c31303937202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520313233202a2f0a2c363833202f *2a207769647468202a2f0a2c31393133202f2a20686569676874202a2f0a2c2d3433202f2a2068 *6f726942656172696e6758202a2f0a2c31343935202f2a20686f726942656172696e6759202a2f *200a2c363834202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203132 *34202a2f0a2c313731202f2a207769647468202a2f0a2c31343930202f2a20686569676874202a *2f0a2c313832202f2a20686f726942656172696e6758202a2f0a2c31343930202f2a20686f7269 *42656172696e6759202a2f200a2c353332202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f646520313235202a2f0a2c363833202f2a207769647468202a2f0a2c3139313320 *2f2a20686569676874202a2f0a2c3432202f2a20686f726942656172696e6758202a2f0a2c3134 *3935202f2a20686f726942656172696e6759202a2f200a2c363834202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520313236202a2f0a2c31313930202f2a2077696474 *68202a2f0a2c343035202f2a20686569676874202a2f0a2c32202f2a20686f726942656172696e *6758202a2f0a2c373235202f2a20686f726942656172696e6759202a2f200a2c31313936202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313237202a2f0a2c300a2c *300a2c300a2c300a2c300a2f2a2043686172636f646520313238202a2f0a2c300a2c300a2c300a *2c300a2c300a2f2a2043686172636f646520313239202a2f0a2c300a2c300a2c300a2c300a2c30 *0a2f2a2043686172636f646520313330202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043 *686172636f646520313331202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f *646520313332202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203133 *33202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313334202a2f0a *2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313335202a2f0a2c300a2c30 *0a2c300a2c300a2c300a2f2a2043686172636f646520313336202a2f0a2c300a2c300a2c300a2c *300a2c300a2f2a2043686172636f646520313337202a2f0a2c300a2c300a2c300a2c300a2c300a *2f2a2043686172636f646520313338202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a204368 *6172636f646520313339202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f64 *6520313430202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313431 *202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313432202a2f0a2c *300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313433202a2f0a2c300a2c300a *2c300a2c300a2c300a2f2a2043686172636f646520313434202a2f0a2c300a2c300a2c300a2c30 *0a2c300a2f2a2043686172636f646520313435202a2f0a2c300a2c300a2c300a2c300a2c300a2f *2a2043686172636f646520313436202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a20436861 *72636f646520313437202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465 *20313438202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f64652031343920 *2a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313530202a2f0a2c30 *0a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313531202a2f0a2c300a2c300a2c *300a2c300a2c300a2f2a2043686172636f646520313532202a2f0a2c300a2c300a2c300a2c300a *2c300a2f2a2043686172636f646520313533202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a *2043686172636f646520313534202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172 *636f646520313535202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520 *313536202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313537202a *2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313538202a2f0a2c300a *2c300a2c300a2c300a2c300a2f2a2043686172636f646520313539202a2f0a2c300a2c300a2c30 *0a2c300a2c300a2f2a2043686172636f646520313630202a2f0a2c30202f2a207769647468202a *2f0a2c30202f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f *0a2c30202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f646520313631202a2f0a2c323034202f2a2077696474 *68202a2f0a2c31343730202f2a20686569676874202a2f0a2c323332202f2a20686f7269426561 *72696e6758202a2f0a2c31303731202f2a20686f726942656172696e6759202a2f200a2c363832 *202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313632202a2f0a2c *393436202f2a207769647468202a2f0a2c31353132202f2a20686569676874202a2f0a2c313034 *202f2a20686f726942656172696e6758202a2f0a2c31323735202f2a20686f726942656172696e *6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520313633202a2f0a2c31303336202f2a207769647468202a2f0a2c31353033202f2a2068 *6569676874202a2f0a2c3536202f2a20686f726942656172696e6758202a2f0a2c31343637202f *2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520313634202a2f0a2c393730202f2a207769647468202a2f *0a2c393731202f2a20686569676874202a2f0a2c3735202f2a20686f726942656172696e675820 *2a2f0a2c31313839202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520313635202a2f0a2c3131373820 *2f2a207769647468202a2f0a2c31343035202f2a20686569676874202a2f0a2c2d3331202f2a20 *686f726942656172696e6758202a2f0a2c31343035202f2a20686f726942656172696e6759202a *2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *313636202a2f0a2c313731202f2a207769647468202a2f0a2c31343930202f2a20686569676874 *202a2f0a2c313832202f2a20686f726942656172696e6758202a2f0a2c31343930202f2a20686f *726942656172696e6759202a2f200a2c353332202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520313637202a2f0a2c393730202f2a207769647468202a2f0a2c313930 *32202f2a20686569676874202a2f0a2c3735202f2a20686f726942656172696e6758202a2f0a2c *31343730202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520313638202a2f0a2c353137202f2a207769 *647468202a2f0a2c333438202f2a20686569676874202a2f0a2c3732202f2a20686f7269426561 *72696e6758202a2f0a2c31343435202f2a20686f726942656172696e6759202a2f200a2c363832 *202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313639202a2f0a2c *31343730202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3139 *202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e *6759202a2f200a2c31353039202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520313730202a2f0a2c363539202f2a207769647468202a2f0a2c363832202f2a20686569 *676874202a2f0a2c3539202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a20 *686f726942656172696e6759202a2f200a2c373538202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f646520313731202a2f0a2c373432202f2a207769647468202a2f0a2c36 *3932202f2a20686569676874202a2f0a2c313934202f2a20686f726942656172696e6758202a2f *0a2c393035202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520313732202a2f0a2c31303433202f2a20 *7769647468202a2f0a2c363030202f2a20686569676874202a2f0a2c3736202f2a20686f726942 *656172696e6758202a2f0a2c383232202f2a20686f726942656172696e6759202a2f200a2c3131 *3936202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313733202a2f *0a2c353032202f2a207769647468202a2f0a2c313835202f2a20686569676874202a2f0a2c3835 *202f2a20686f726942656172696e6758202a2f0a2c363633202f2a20686f726942656172696e67 *59202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64 *6520313734202a2f0a2c31343637202f2a207769647468202a2f0a2c31343639202f2a20686569 *676874202a2f0a2c3231202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20 *686f726942656172696e6759202a2f200a2c31353039202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f646520313735202a2f0a2c363430202f2a207769647468202a2f0a2c *313138202f2a20686569676874202a2f0a2c38202f2a20686f726942656172696e6758202a2f0a *2c31343030202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520313736202a2f0a2c363034202f2a207769 *647468202a2f0a2c363034202f2a20686569676874202a2f0a2c313131202f2a20686f72694265 *6172696e6758202a2f0a2c31343331202f2a20686f726942656172696e6759202a2f200a2c3831 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313737202a2f0a *2c31303433202f2a207769647468202a2f0a2c31303435202f2a20686569676874202a2f0a2c34 *30202f2a20686f726942656172696e6758202a2f0a2c31303435202f2a20686f72694265617269 *6e6759202a2f200a2c31313234202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520313738202a2f0a2c363430202f2a207769647468202a2f0a2c383631202f2a206865 *69676874202a2f0a2c3131202f2a20686f726942656172696e6758202a2f0a2c31343332202f2a *20686f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f646520313739202a2f0a2c363437202f2a207769647468202a2f0a2c *383839202f2a20686569676874202a2f0a2c37202f2a20686f726942656172696e6758202a2f0a *2c31343331202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520313830202a2f0a2c343035202f2a207769 *647468202a2f0a2c343035202f2a20686569676874202a2f0a2c313933202f2a20686f72694265 *6172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c3638 *32202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313831202a2f0a *2c31313738202f2a207769647468202a2f0a2c31343931202f2a20686569676874202a2f0a2c2d *3535202f2a20686f726942656172696e6758202a2f0a2c31303639202f2a20686f726942656172 *696e6759202a2f200a2c31313830202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f646520313832202a2f0a2c31303736202f2a207769647468202a2f0a2c31383332202f2a *20686569676874202a2f0a2c2d3131202f2a20686f726942656172696e6758202a2f0a2c313436 *39202f2a20686f726942656172696e6759202a2f200a2c31313030202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520313833202a2f0a2c323536202f2a207769647468 *202a2f0a2c323536202f2a20686569676874202a2f0a2c313531202f2a20686f72694265617269 *6e6758202a2f0a2c383239202f2a20686f726942656172696e6759202a2f200a2c353639202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313834202a2f0a2c343430 *202f2a207769647468202a2f0a2c343631202f2a20686569676874202a2f0a2c313031202f2a20 *686f726942656172696e6758202a2f0a2c30202f2a20686f726942656172696e6759202a2f200a *2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031383520 *2a2f0a2c333832202f2a207769647468202a2f0a2c383535202f2a20686569676874202a2f0a2c *3837202f2a20686f726942656172696e6758202a2f0a2c31343236202f2a20686f726942656172 *696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520313836202a2f0a2c363532202f2a207769647468202a2f0a2c363832202f2a206865 *69676874202a2f0a2c3439202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a *20686f726942656172696e6759202a2f200a2c373438202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f646520313837202a2f0a2c373432202f2a207769647468202a2f0a2c *363932202f2a20686569676874202a2f0a2c313934202f2a20686f726942656172696e6758202a *2f0a2c393035202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f646520313838202a2f0a2c31343633202f2a *207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313633202f2a20686f *726942656172696e6758202a2f0a2c31343331202f2a20686f726942656172696e6759202a2f20 *0a2c31373038202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203138 *39202a2f0a2c31353030202f2a207769647468202a2f0a2c31343639202f2a2068656967687420 *2a2f0a2c3930202f2a20686f726942656172696e6758202a2f0a2c31343331202f2a20686f7269 *42656172696e6759202a2f200a2c31373038202f2a20686f7269416476616e6365202a2f0a2f2a *2043686172636f646520313930202a2f0a2c31353730202f2a207769647468202a2f0a2c313436 *39202f2a20686569676874202a2f0a2c3735202f2a20686f726942656172696e6758202a2f0a2c *31343331202f2a20686f726942656172696e6759202a2f200a2c31373038202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520313931202a2f0a2c383934202f2a207769 *647468202a2f0a2c31343839202f2a20686569676874202a2f0a2c313836202f2a20686f726942 *656172696e6758202a2f0a2c31303736202f2a20686f726942656172696e6759202a2f200a2c31 *323531202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313932202a *2f0a2c31333131202f2a207769647468202a2f0a2c31383734202f2a20686569676874202a2f0a *2c3330202f2a20686f726942656172696e6758202a2f0a2c31383734202f2a20686f7269426561 *72696e6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a204368 *6172636f646520313933202a2f0a2c31333131202f2a207769647468202a2f0a2c31383734202f *2a20686569676874202a2f0a2c3330202f2a20686f726942656172696e6758202a2f0a2c313837 *34202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520313934202a2f0a2c31333131202f2a2077696474 *68202a2f0a2c31383734202f2a20686569676874202a2f0a2c3330202f2a20686f726942656172 *696e6758202a2f0a2c31383734202f2a20686f726942656172696e6759202a2f200a2c31333636 *202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313935202a2f0a2c *31333131202f2a207769647468202a2f0a2c31383431202f2a20686569676874202a2f0a2c3330 *202f2a20686f726942656172696e6758202a2f0a2c31383431202f2a20686f726942656172696e *6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520313936202a2f0a2c31333131202f2a207769647468202a2f0a2c31383137202f2a2068 *6569676874202a2f0a2c3330202f2a20686f726942656172696e6758202a2f0a2c31383137202f *2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520313937202a2f0a2c31333131202f2a207769647468202a *2f0a2c31393436202f2a20686569676874202a2f0a2c3330202f2a20686f726942656172696e67 *58202a2f0a2c31393436202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313938202a2f0a2c313933 *32202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3136202f2a *20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e675920 *2a2f200a2c32303438202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *20313939202a2f0a2c31333033202f2a207769647468202a2f0a2c31393730202f2a2068656967 *6874202a2f0a2c3930202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a2068 *6f726942656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f646520323030202a2f0a2c31303836202f2a207769647468202a2f0a2c *31383734202f2a20686569676874202a2f0a2c313735202f2a20686f726942656172696e675820 *2a2f0a2c31383734202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520323031202a2f0a2c3130383620 *2f2a207769647468202a2f0a2c31383734202f2a20686569676874202a2f0a2c313735202f2a20 *686f726942656172696e6758202a2f0a2c31383734202f2a20686f726942656172696e6759202a *2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *323032202a2f0a2c31303836202f2a207769647468202a2f0a2c31383734202f2a206865696768 *74202a2f0a2c313735202f2a20686f726942656172696e6758202a2f0a2c31383734202f2a2068 *6f726942656172696e6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f646520323033202a2f0a2c31303836202f2a207769647468202a2f0a2c *31383137202f2a20686569676874202a2f0a2c313735202f2a20686f726942656172696e675820 *2a2f0a2c31383137202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520323034202a2f0a2c343035202f *2a207769647468202a2f0a2c31383733202f2a20686569676874202a2f0a2c32202f2a20686f72 *6942656172696e6758202a2f0a2c31383733202f2a20686f726942656172696e6759202a2f200a *2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032303520 *2a2f0a2c343035202f2a207769647468202a2f0a2c31383730202f2a20686569676874202a2f0a *2c313337202f2a20686f726942656172696e6758202a2f0a2c31383730202f2a20686f72694265 *6172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a204368 *6172636f646520323036202a2f0a2c353937202f2a207769647468202a2f0a2c31383738202f2a *20686569676874202a2f0a2c2d3236202f2a20686f726942656172696e6758202a2f0a2c313837 *38202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e *6365202a2f0a2f2a2043686172636f646520323037202a2f0a2c353137202f2a20776964746820 *2a2f0a2c31383133202f2a20686569676874202a2f0a2c3136202f2a20686f726942656172696e *6758202a2f0a2c31383133202f2a20686f726942656172696e6759202a2f200a2c353639202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323038202a2f0a2c313334 *36202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3333202f2a *20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e675920 *2a2f200a2c31343739202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *20323039202a2f0a2c31313636202f2a207769647468202a2f0a2c31383431202f2a2068656967 *6874202a2f0a2c313536202f2a20686f726942656172696e6758202a2f0a2c31383431202f2a20 *686f726942656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f646520323130202a2f0a2c31343332202f2a207769647468202a2f0a *2c31393537202f2a20686569676874202a2f0a2c3830202f2a20686f726942656172696e675820 *2a2f0a2c31393134202f2a20686f726942656172696e6759202a2f200a2c31353933202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520323131202a2f0a2c3134333220 *2f2a207769647468202a2f0a2c31393537202f2a20686569676874202a2f0a2c3830202f2a2068 *6f726942656172696e6758202a2f0a2c31393134202f2a20686f726942656172696e6759202a2f *200a2c31353933202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032 *3132202a2f0a2c31343332202f2a207769647468202a2f0a2c31393537202f2a20686569676874 *202a2f0a2c3830202f2a20686f726942656172696e6758202a2f0a2c31393134202f2a20686f72 *6942656172696e6759202a2f200a2c31353933202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520323133202a2f0a2c31343332202f2a207769647468202a2f0a2c3139 *3234202f2a20686569676874202a2f0a2c3830202f2a20686f726942656172696e6758202a2f0a *2c31383831202f2a20686f726942656172696e6759202a2f200a2c31353933202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520323134202a2f0a2c31343332202f2a20 *7769647468202a2f0a2c31393030202f2a20686569676874202a2f0a2c3830202f2a20686f7269 *42656172696e6758202a2f0a2c31383537202f2a20686f726942656172696e6759202a2f200a2c *31353933202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032313520 *2a2f0a2c393938202f2a207769647468202a2f0a2c393938202f2a20686569676874202a2f0a2c *313030202f2a20686f726942656172696e6758202a2f0a2c31303231202f2a20686f7269426561 *72696e6759202a2f200a2c31313936202f2a20686f7269416476616e6365202a2f0a2f2a204368 *6172636f646520323136202a2f0a2c31343436202f2a207769647468202a2f0a2c31353533202f *2a20686569676874202a2f0a2c3636202f2a20686f726942656172696e6758202a2f0a2c313531 *30202f2a20686f726942656172696e6759202a2f200a2c31353933202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520323137202a2f0a2c31313537202f2a2077696474 *68202a2f0a2c31393133202f2a20686569676874202a2f0a2c313730202f2a20686f7269426561 *72696e6758202a2f0a2c31383734202f2a20686f726942656172696e6759202a2f200a2c313437 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323138202a2f0a *2c31313537202f2a207769647468202a2f0a2c31393133202f2a20686569676874202a2f0a2c31 *3730202f2a20686f726942656172696e6758202a2f0a2c31383734202f2a20686f726942656172 *696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f646520323139202a2f0a2c31313537202f2a207769647468202a2f0a2c31393133202f2a *20686569676874202a2f0a2c313730202f2a20686f726942656172696e6758202a2f0a2c313837 *34202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520323230202a2f0a2c31313537202f2a2077696474 *68202a2f0a2c31383536202f2a20686569676874202a2f0a2c313730202f2a20686f7269426561 *72696e6758202a2f0a2c31383137202f2a20686f726942656172696e6759202a2f200a2c313437 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323231202a2f0a *2c31333039202f2a207769647468202a2f0a2c31383734202f2a20686569676874202a2f0a2c34 *32202f2a20686f726942656172696e6758202a2f0a2c31383734202f2a20686f72694265617269 *6e6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520323232202a2f0a2c31303938202f2a207769647468202a2f0a2c31343637202f2a20 *686569676874202a2f0a2c313734202f2a20686f726942656172696e6758202a2f0a2c31343637 *202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f7269416476616e *6365202a2f0a2f2a2043686172636f646520323233202a2f0a2c393037202f2a20776964746820 *2a2f0a2c31353230202f2a20686569676874202a2f0a2c313939202f2a20686f72694265617269 *6e6758202a2f0a2c31343931202f2a20686f726942656172696e6759202a2f200a2c3132353120 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323234202a2f0a2c31 *303133202f2a207769647468202a2f0a2c31353338202f2a20686569676874202a2f0a2c383220 *2f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e67 *59202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *646520323235202a2f0a2c31303133202f2a207769647468202a2f0a2c31353338202f2a206865 *69676874202a2f0a2c3832202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a *20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f646520323236202a2f0a2c31303133202f2a207769647468202a2f *0a2c31353338202f2a20686569676874202a2f0a2c3832202f2a20686f726942656172696e6758 *202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f646520323237202a2f0a2c31303133 *202f2a207769647468202a2f0a2c31353035202f2a20686569676874202a2f0a2c3832202f2a20 *686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a *2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *323238202a2f0a2c31303133202f2a207769647468202a2f0a2c31343831202f2a206865696768 *74202a2f0a2c3832202f2a20686f726942656172696e6758202a2f0a2c31343435202f2a20686f *726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520323239202a2f0a2c31303133202f2a207769647468202a2f0a2c31 *363632202f2a20686569676874202a2f0a2c3832202f2a20686f726942656172696e6758202a2f *0a2c31363236202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f646520323330202a2f0a2c31363632202f2a *207769647468202a2f0a2c31313333202f2a20686569676874202a2f0a2c3733202f2a20686f72 *6942656172696e6758202a2f0a2c31303937202f2a20686f726942656172696e6759202a2f200a *2c31383231202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323331 *202a2f0a2c393137202f2a207769647468202a2f0a2c31353633202f2a20686569676874202a2f *0a2c3539202f2a20686f726942656172696e6758202a2f0a2c31313032202f2a20686f72694265 *6172696e6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a2f2a2043 *686172636f646520323332202a2f0a2c393738202f2a207769647468202a2f0a2c31353430202f *2a20686569676874202a2f0a2c3732202f2a20686f726942656172696e6758202a2f0a2c313530 *32202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520323333202a2f0a2c393738202f2a207769647468 *202a2f0a2c31353430202f2a20686569676874202a2f0a2c3732202f2a20686f72694265617269 *6e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c3131333920 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323334202a2f0a2c39 *3738202f2a207769647468202a2f0a2c31353430202f2a20686569676874202a2f0a2c3732202f *2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759 *202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64 *6520323335202a2f0a2c393738202f2a207769647468202a2f0a2c31343833202f2a2068656967 *6874202a2f0a2c3732202f2a20686f726942656172696e6758202a2f0a2c31343435202f2a2068 *6f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f646520323336202a2f0a2c343035202f2a207769647468202a2f0a2c31 *353032202f2a20686569676874202a2f0a2c3133202f2a20686f726942656172696e6758202a2f *0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520323337202a2f0a2c343035202f2a2077 *69647468202a2f0a2c31353032202f2a20686569676874202a2f0a2c313433202f2a20686f7269 *42656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c *353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323338202a *2f0a2c353937202f2a207769647468202a2f0a2c31353032202f2a20686569676874202a2f0a2c *2d3137202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f7269426561 *72696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f646520323339202a2f0a2c353137202f2a207769647468202a2f0a2c31343435202f2a20 *686569676874202a2f0a2c3232202f2a20686f726942656172696e6758202a2f0a2c3134343520 *2f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520323430202a2f0a2c31303030202f2a207769647468202a *2f0a2c31363630202f2a20686569676874202a2f0a2c3631202f2a20686f726942656172696e67 *58202a2f0a2c31363233202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323431202a2f0a2c383733 *202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313332202f2a *20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e675920 *2a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *20323432202a2f0a2c393938202f2a207769647468202a2f0a2c31353431202f2a206865696768 *74202a2f0a2c3539202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f *726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520323433202a2f0a2c393938202f2a207769647468202a2f0a2c3135 *3431202f2a20686569676874202a2f0a2c3539202f2a20686f726942656172696e6758202a2f0a *2c31353032202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520323434202a2f0a2c393938202f2a2077 *69647468202a2f0a2c31353431202f2a20686569676874202a2f0a2c3539202f2a20686f726942 *656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c31 *313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323435202a *2f0a2c393938202f2a207769647468202a2f0a2c31353038202f2a20686569676874202a2f0a2c *3539202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172 *696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f646520323436202a2f0a2c393938202f2a207769647468202a2f0a2c31343834202f2a20 *686569676874202a2f0a2c3539202f2a20686f726942656172696e6758202a2f0a2c3134343520 *2f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f646520323437202a2f0a2c31303433202f2a20776964746820 *2a2f0a2c31303033202f2a20686569676874202a2f0a2c3430202f2a20686f726942656172696e *6758202a2f0a2c31303234202f2a20686f726942656172696e6759202a2f200a2c31313234202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323438202a2f0a2c3130 *3435202f2a207769647468202a2f0a2c31313539202f2a20686569676874202a2f0a2c3932202f *2a20686f726942656172696e6758202a2f0a2c31313131202f2a20686f726942656172696e6759 *202a2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64 *6520323439202a2f0a2c383632202f2a207769647468202a2f0a2c31353331202f2a2068656967 *6874202a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20 *686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f646520323530202a2f0a2c383632202f2a207769647468202a2f0a2c *31353331202f2a20686569676874202a2f0a2c313238202f2a20686f726942656172696e675820 *2a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520323531202a2f0a2c383632202f *2a207769647468202a2f0a2c31353331202f2a20686569676874202a2f0a2c313238202f2a2068 *6f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f *200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032 *3532202a2f0a2c383632202f2a207769647468202a2f0a2c31343734202f2a2068656967687420 *2a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31343435202f2a20686f72 *6942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520323533202a2f0a2c393739202f2a207769647468202a2f0a2c313934 *31202f2a20686569676874202a2f0a2c3231202f2a20686f726942656172696e6758202a2f0a2c *31353032202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520323534202a2f0a2c393337202f2a207769 *647468202a2f0a2c31383932202f2a20686569676874202a2f0a2c313238202f2a20686f726942 *656172696e6758202a2f0a2c31343535202f2a20686f726942656172696e6759202a2f200a2c31 *313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323535202a *2f0a2c393739202f2a207769647468202a2f0a2c31383834202f2a20686569676874202a2f0a2c *3231202f2a20686f726942656172696e6758202a2f0a2c31343435202f2a20686f726942656172 *696e6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a7d3b0a737461 *74696320636f6e737420756e7369676e6564206c6f6e6720666d65747269635b5d3d7b0a313933 *32202f2a206d61785f7769647468202a2f0a2c31393730202f2a206d61785f686569676874202a *2f0a2c323337202f2a206d61785f686f726942656172696e6758202a2f0a2c31393436202f2a20 *6d61785f686f726942656172696e6759202a2f0a2c32303739202f2a206d61785f686f72694164 *76616e6365202a2f0a7d3b0a23656e6469660a hunk ./Test/AFMParser.hs 7 +import System.Environment hunk ./Test/AFMParser.hs 30 +getName :: String -> Parser String +getName s = do + string s + spaces + c <- alphaNum >> many (alphaNum <|> oneOf " -+") + line + return c + hunk ./Test/AFMParser.hs 42 +getFloat :: String -> Parser Double +getFloat s = do string s + spaces + c <- many1 (alphaNum <|> oneOf ".-+") + line + return $ read c + hunk ./Test/AFMParser.hs 54 + | Special hunk ./Test/AFMParser.hs 58 + | Bold + | Roman hunk ./Test/AFMParser.hs 90 + | FontSpecific hunk ./Test/AFMParser.hs 143 -afm = do { string "StartFontMetrics" ; toEndOfLine +afm = do { comment "StartFontMetrics" hunk ./Test/AFMParser.hs 146 - ; fullName <- getString "FullName" + ; fullName <- getName "FullName" hunk ./Test/AFMParser.hs 149 - ; italicAngle <- getInt "ItalicAngle" + ; italicAngle <- getFloat "ItalicAngle" hunk ./Test/AFMParser.hs 158 - ; capHeight <- getInt "CapHeight" - ; xHeight <- getInt "XHeight" - ; ascender <- getInt "Ascender" - ; descender <- getInt "Descender" + ; capHeight <- option 0 $ getInt "CapHeight" + ; xHeight <- option 0 $ getInt "XHeight" + ; ascender <- option 0 $ getInt "Ascender" + ; descender <- option 0 $ getInt "Descender" hunk ./Test/AFMParser.hs 172 - l <- parseFromFile afm "../Core14_AFMs/Helvetica.afm" + r <- getArgs + l <- parseFromFile afm $ "../Core14_AFMs/" ++ head r hunk ./Test/Makefile 13 + +metrics: + @./afm Courier-Bold.afm + @./afm Courier.afm + @./afm Helvetica-Oblique.afm + @./afm Symbol.afm + @./afm Times-Italic.afm + @./afm Courier-BoldOblique.afm + @./afm Helvetica-Bold.afm + @./afm Helvetica.afm + @./afm Times-Bold.afm + @./afm Times-Roman.afm + @./afm Courier-Oblique.afm + @./afm Helvetica-BoldOblique.afm + @./afm Times-BoldItalic.afm + @./afm ZapfDingbats.afm hunk ./Graphics/PDF/Resources.hs 49 - deriving(Eq,Ord) + deriving(Eq,Ord,Enum) hunk ./Graphics/PDF/Text.hs 38 - , getLeading hunk ./Graphics/PDF/Text.hs 52 -foreign import ccall "ctext.h c_getLeading" getLeading :: Int -foreign import ccall "ctext.h c_getAdvance" getAdvance :: Word8 -> Int -foreign import ccall "ctext.h c_getDescent" cgetDescent :: Int +foreign import ccall "ctext.h c_getLeading" cgetLeading :: Int -> Int +foreign import ccall "ctext.h c_getAdvance" cgetAdvance :: Int -> Word8 -> Int +foreign import ccall "ctext.h c_getDescent" cgetDescent :: Int -> Int hunk ./Graphics/PDF/Text.hs 60 -trueSize fontSize textSize = (fromIntegral (textSize*fontSize)) / 2048.0 +trueSize fontSize textSize = (fromIntegral (textSize*fontSize)) / 1000.0 hunk ./Graphics/PDF/Text.hs 63 -getDescent (PDFFont _ s) = trueSize s cgetDescent +getDescent (PDFFont n s) = trueSize s (cgetDescent (fromEnum n)) hunk ./Graphics/PDF/Text.hs 66 -getHeight (PDFFont _ s) = trueSize s getLeading +getHeight (PDFFont n s) = trueSize s (cgetLeading (fromEnum n)) hunk ./Graphics/PDF/Text.hs 69 -textWidth (PDFFont _ s) (PDFString t) = trueSize s (sum . map getAdvance . B.unpack $ t) +textWidth (PDFFont n s) (PDFString t) = trueSize s (sum . map (cgetAdvance (fromEnum n)) . B.unpack $ t) hunk ./Test/AFMParser.hs 8 +import Data.Maybe(isJust,fromJust) +import qualified Data.IntMap as IM +import Data.List(intersperse) hunk ./Test/AFMParser.hs 107 - | B [Int] + | B [Double] hunk ./Test/AFMParser.hs 138 + +data Metric = Metric { charCode :: Int + , width :: Int + , name :: String + , bounds :: [Double] + } + deriving(Eq,Show) + +data Font = Font { metrics :: [Metric] + , underlinePosition :: Int + , underlineThickness :: Int + , ascent :: Int + , descent :: Int + } + deriving(Eq,Show) + +isEncoded :: Metric -> Bool +isEncoded (Metric c _ _ _) = c /= (-1) + +mkMetric :: [Elem] -> Metric +mkMetric l = foldr addElem (Metric (-1) 0 "" []) l + where + addElem (C c) m = m {charCode=c} + addElem (WX c) m = m {width=c} + addElem (N s) m = m {name=s} + addElem (B l) m = m {bounds=l} + addElem _ m = m hunk ./Test/AFMParser.hs 166 -charMetric :: Parser () +charMetric :: Parser Metric hunk ./Test/AFMParser.hs 168 - sepEndBy metricElem (many1 (oneOf "; ")) + l <- sepEndBy metricElem (many1 (oneOf "; ")) hunk ./Test/AFMParser.hs 170 - return () + return . mkMetric $ l hunk ./Test/AFMParser.hs 172 -afm :: Parser [Double] +afm :: Parser Font hunk ./Test/AFMParser.hs 197 - ; return bbox + ; return $ Font (filter isEncoded charMetrics) underlinePosition underlineThickness ascender descender hunk ./Test/AFMParser.hs 199 + +allFonts :: [String] +allFonts = [ "Helvetica.afm" + , "Helvetica-Bold.afm" + , "Helvetica-Oblique.afm" + , "Helvetica-BoldOblique.afm" + , "Times-Roman.afm" + , "Times-Bold.afm" + , "Times-Italic.afm" + , "Times-BoldItalic.afm" + , "Courier.afm" + , "Courier-Bold.afm" + , "Courier-Oblique.afm" + , "Courier-BoldOblique.afm" + , "Symbol.afm" + , "ZapfDingbats.afm" + ] + +createFontList :: Font -> [(Int,Int)] +createFontList (Font m up ut asc desc) = zip codes (map getWidth [32..255]) + where + codes = [32..255] + getWidth c = IM.findWithDefault spaceWidth c chars + spaceWidth = IM.findWithDefault 0 32 chars + chars = IM.fromList . map zipMetric $ m + zipMetric m@(Metric c w _ _) = (c,w) + +parseFont :: String -> IO (Maybe Font) +parseFont s = do + r <- parseFromFile afm $ "../Core14_AFMs/" ++ s + case r of + Left _ -> return $ Nothing + Right r -> return $ Just r + +fontData :: Font -> [String] +fontData (Font _ up ut asc desc) = [show up,show ut,show asc,show desc] hunk ./Test/AFMParser.hs 238 - r <- getArgs - l <- parseFromFile afm $ "../Core14_AFMs/" ++ head r - print l + maybeFonts <- mapM parseFont allFonts + let fonts = map fromJust . filter isJust $ maybeFonts + let carray = map createFontList fonts + putStrLn "#ifndef _METRICS_H_" + putStrLn "#define _METRICS_H_" + putStrLn "static const unsigned long gmetric[]={" + mapM_ putStr . intersperse "\n," . map (\(c,w) -> show w) . concat $ carray + putStrLn "};" + putStrLn "static const long fmetric[]={" + mapM_ putStr . intersperse "\n," . concatMap fontData $ fonts + putStrLn "};" + putStrLn "#endif" + + hunk ./Test/test.hs 104 + +fontDebug :: PDFFont -> String -> PDF () +fontDebug f t' = do + let t = toPDFString t' + page <- addPage Nothing + newSibling t Nothing Nothing + drawWithPage page $ do + fillColor $ Rgb 0 0 0 + drawText $ do + setFont f + textStart 10 400.0 + leading $ getHeight f + renderMode FillText + displayText t + startNewLine + displayText $ toPDFString "Another little test" + strokeColor $ Rgb 1 0 0 + stroke $ Line 10 400 612 400 + fill $ Circle 10 400 10 + stroke $ Rectangle 10 (400.0 - (getDescent f)) (10.0 + textWidth f t) (400.0 - getDescent f + getHeight f) hunk ./Test/test.hs 131 - page <- addPage Nothing - newSibling (toPDFString "Page Main") Nothing Nothing - drawWithPage page $ do - let f = PDFFont Times_Roman 48 - t = toPDFString "AAAAAAAAA¡" - fillColor $ Rgb 0 0 0 - drawText $ do - setFont f - textStart 10 (400.0 - (getDescent f)) - leading $ getHeight f - renderMode FillText - displayText t - startNewLine - displayText $ toPDFString "Another little test" - strokeColor $ Rgb 1 0 0 - stroke $ Line 10 400 612 400 - fill $ Circle 10 400 10 - stroke $ Rectangle 10 (400.0 - (getDescent f)) (10.0 + textWidth f t) (400.0 - getDescent f + getHeight f) - + fontDebug (PDFFont Times_Roman 48) ("AbAVAVcéèHjpA¡ Test!") + fontDebug (PDFFont Helvetica 48) ( "AbAVAVcéèHjpA¡ Test!") + fontDebug (PDFFont Times_BoldItalic 48) ( "AbAVAVcéèHjpA¡ Test!") + hunk ./c/ctext.h 3 -extern unsigned short c_getAdvance(unsigned char c); -extern unsigned short c_getLeading(void); -extern unsigned short c_getDescent(void); +extern short c_getAdvance(unsigned short,unsigned char); +extern short c_getLeading(unsigned short); +extern short c_getDescent(unsigned short); hunk ./c/metrics.c 3 +#include hunk ./c/metrics.c 5 -unsigned short c_getAdvance(unsigned char c) +#define GFONTSIZE (255-32+1) +#define FFONTSIZE (4) + +short c_getAdvance(unsigned short font,unsigned char c) hunk ./c/metrics.c 10 - return(gmetric[c*5+4]); + if (c<32) + return(0); + return(gmetric[font*GFONTSIZE+c-32]); hunk ./c/metrics.c 15 -unsigned short c_getLeading(void) +short c_getLeading(unsigned short font) hunk ./c/metrics.c 17 - return(fmetric[1]); + return(fmetric[font*FFONTSIZE+2]-fmetric[font*FFONTSIZE+3]); hunk ./c/metrics.c 20 -unsigned short c_getDescent(void) +short c_getDescent(unsigned short font) hunk ./c/metrics.c 22 - return(fmetric[1] - fmetric[3]); + return(-fmetric[font*FFONTSIZE+3]); binary ./c/metrics.h oldhex *2369666e646566205f4d4554524943535f485f0a23646566696e65205f4d4554524943535f485f *0a2f2a4e6220666163657320320a48656c76657469636120526567756c6172202a2f0a2f2a2063 *6861726d6170203a20756e6963202a2f0a2f2a20636861726d6170203a2061726d6e202a2f0a2f *2a20636861726d6170203a2061726d6e202a2f0a2f2a20636861726d6170203a2061726d6e202a *2f0a2f2a20636861726d6170203a2061726d6e202a2f0a2f2a20636861726d6170203a2061726d *6e202a2f0a2f2a20636861726d6170203a2061726d6e202a2f0a2f2a20636861726d6170203a20 *61726d6e202a2f0a2f2a20636861726d6170203a2000000000202a2f0a2f2a20636861726d6170 *203a2000000000202a2f0a73746174696320636f6e737420756e7369676e6564206c6f6e672067 *6d65747269635b5d3d7b0a2f2a2043686172636f64652030202a2f0a30202f2a20776964746820 *2a2f0a2c30202f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a *2f0a2c30202f2a20686f726942656172696e6759202a2f200a2c30202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f64652031202a2f0a2c300a2c300a2c300a2c300a2c300a *2f2a2043686172636f64652032202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172 *636f64652033202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203420 *2a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f64652035202a2f0a2c300a2c *300a2c300a2c300a2c300a2f2a2043686172636f64652036202a2f0a2c300a2c300a2c300a2c30 *0a2c300a2f2a2043686172636f64652037202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a20 *43686172636f64652038202a2f0a2c30202f2a207769647468202a2f0a2c30202f2a2068656967 *6874202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f2a20686f726942 *656172696e6759202a2f200a2c30202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f64652039202a2f0a2c30202f2a207769647468202a2f0a2c30202f2a2068656967687420 *2a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f2a20686f726942656172 *696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f6465203130202a2f0a2c30202f2a207769647468202a2f0a2c30202f2a2068656967687420 *2a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f2a20686f726942656172 *696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f6465203131202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f64652031 *32202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203133202a2f0a2c *30202f2a207769647468202a2f0a2c30202f2a20686569676874202a2f0a2c30202f2a20686f72 *6942656172696e6758202a2f0a2c30202f2a20686f726942656172696e6759202a2f200a2c3536 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203134202a2f0a2c *300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203135202a2f0a2c300a2c300a2c *300a2c300a2c300a2f2a2043686172636f6465203136202a2f0a2c300a2c300a2c300a2c300a2c *300a2f2a2043686172636f6465203137202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043 *686172636f6465203138202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f64 *65203139202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203230202a *2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203231202a2f0a2c300a2c *300a2c300a2c300a2c300a2f2a2043686172636f6465203232202a2f0a2c300a2c300a2c300a2c *300a2c300a2f2a2043686172636f6465203233202a2f0a2c300a2c300a2c300a2c300a2c300a2f *2a2043686172636f6465203234202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172 *636f6465203235202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f64652032 *36202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203237202a2f0a2c *300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203238202a2f0a2c300a2c300a2c *300a2c300a2c300a2f2a2043686172636f6465203239202a2f0a2c30202f2a207769647468202a *2f0a2c30202f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f *0a2c30202f2a20686f726942656172696e6759202a2f200a2c30202f2a20686f7269416476616e *6365202a2f0a2f2a2043686172636f6465203330202a2f0a2c300a2c300a2c300a2c300a2c300a *2f2a2043686172636f6465203331202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a20436861 *72636f6465203332202a2f0a2c30202f2a207769647468202a2f0a2c30202f2a20686569676874 *202a2f0a2c30202f2a20686f726942656172696e6758202a2f0a2c30202f2a20686f7269426561 *72696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f6465203333202a2f0a2c323033202f2a207769647468202a2f0a2c31343639202f2a2068 *6569676874202a2f0a2c323337202f2a20686f726942656172696e6758202a2f0a2c3134363920 *2f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f6465203334202a2f0a2c353234202f2a207769647468202a2f0a *2c353838202f2a20686569676874202a2f0a2c313034202f2a20686f726942656172696e675820 *2a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c373237202f2a20686f *7269416476616e6365202a2f0a2f2a2043686172636f6465203335202a2f0a2c31313337202f2a *207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c30202f2a20686f7269 *42656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c *31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203336202a *2f0a2c393937202f2a207769647468202a2f0a2c31383235202f2a20686569676874202a2f0a2c *3634202f2a20686f726942656172696e6758202a2f0a2c31353838202f2a20686f726942656172 *696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f6465203337202a2f0a2c31363738202f2a207769647468202a2f0a2c31343634202f2a20 *686569676874202a2f0a2c3636202f2a20686f726942656172696e6758202a2f0a2c3134323620 *2f2a20686f726942656172696e6759202a2f200a2c31383231202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f6465203338202a2f0a2c31323331202f2a207769647468202a *2f0a2c31353031202f2a20686569676874202a2f0a2c3839202f2a20686f726942656172696e67 *58202a2f0a2c31343637202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203339202a2f0a2c31383220 *2f2a207769647468202a2f0a2c353838202f2a20686569676874202a2f0a2c313031202f2a2068 *6f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f *200a2c333931202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203430 *202a2f0a2c343637202f2a207769647468202a2f0a2c31393131202f2a20686569676874202a2f *0a2c313432202f2a20686f726942656172696e6758202a2f0a2c31343933202f2a20686f726942 *656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043 *686172636f6465203431202a2f0a2c343637202f2a207769647468202a2f0a2c31393131202f2a *20686569676874202a2f0a2c3638202f2a20686f726942656172696e6758202a2f0a2c31343933 *202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f6465203432202a2f0a2c363330202f2a207769647468202a2f *0a2c353838202f2a20686569676874202a2f0a2c3738202f2a20686f726942656172696e675820 *2a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c373937202f2a20686f *7269416476616e6365202a2f0a2f2a2043686172636f6465203433202a2f0a2c31303433202f2a *207769647468202a2f0a2c31303435202f2a20686569676874202a2f0a2c3736202f2a20686f72 *6942656172696e6758202a2f0a2c31303435202f2a20686f726942656172696e6759202a2f200a *2c31313936202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520343420 *2a2f0a2c323134202f2a207769647468202a2f0a2c353232202f2a20686569676874202a2f0a2c *313730202f2a20686f726942656172696e6758202a2f0a2c323138202f2a20686f726942656172 *696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f6465203435202a2f0a2c353032202f2a207769647468202a2f0a2c313835202f2a20686569 *676874202a2f0a2c3835202f2a20686f726942656172696e6758202a2f0a2c363633202f2a2068 *6f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f6465203436202a2f0a2c323039202f2a207769647468202a2f0a2c323138 *202f2a20686569676874202a2f0a2c313735202f2a20686f726942656172696e6758202a2f0a2c *323138202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f6465203437202a2f0a2c363138202f2a207769647468 *202a2f0a2c31343639202f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e *6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c353639202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203438202a2f0a2c39383820 *2f2a207769647468202a2f0a2c31343731202f2a20686569676874202a2f0a2c3634202f2a2068 *6f726942656172696e6758202a2f0a2c31343332202f2a20686f726942656172696e6759202a2f *200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652034 *39202a2f0a2c353239202f2a207769647468202a2f0a2c31343236202f2a20686569676874202a *2f0a2c313936202f2a20686f726942656172696e6758202a2f0a2c31343236202f2a20686f7269 *42656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a *2043686172636f6465203530202a2f0a2c393930202f2a207769647468202a2f0a2c3134333720 *2f2a20686569676874202a2f0a2c3634202f2a20686f726942656172696e6758202a2f0a2c3134 *3337202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f6465203531202a2f0a2c31303031202f2a2077696474 *68202a2f0a2c31343733202f2a20686569676874202a2f0a2c3439202f2a20686f726942656172 *696e6758202a2f0a2c31343334202f2a20686f726942656172696e6759202a2f200a2c31313339 *202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203532202a2f0a2c31 *303139202f2a207769647468202a2f0a2c31343336202f2a20686569676874202a2f0a2c353220 *2f2a20686f726942656172696e6758202a2f0a2c31343336202f2a20686f726942656172696e67 *59202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *6465203533202a2f0a2c393836202f2a207769647468202a2f0a2c31343434202f2a2068656967 *6874202a2f0a2c3636202f2a20686f726942656172696e6758202a2f0a2c31343038202f2a2068 *6f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203534202a2f0a2c393832202f2a207769647468202a2f0a2c3134 *3735202f2a20686569676874202a2f0a2c3737202f2a20686f726942656172696e6758202a2f0a *2c31343338202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f6465203535202a2f0a2c393936202f2a207769 *647468202a2f0a2c31343038202f2a20686569676874202a2f0a2c3735202f2a20686f72694265 *6172696e6758202a2f0a2c31343038202f2a20686f726942656172696e6759202a2f200a2c3131 *3339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203536202a2f0a *2c393834202f2a207769647468202a2f0a2c31343737202f2a20686569676874202a2f0a2c3636 *202f2a20686f726942656172696e6758202a2f0a2c31343336202f2a20686f726942656172696e *6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f6465203537202a2f0a2c393638202f2a207769647468202a2f0a2c31343734202f2a20686569 *676874202a2f0a2c3733202f2a20686f726942656172696e6758202a2f0a2c31343334202f2a20 *686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f6465203538202a2f0a2c323039202f2a207769647468202a2f0a2c31 *303537202f2a20686569676874202a2f0a2c323237202f2a20686f726942656172696e6758202a *2f0a2c31303537202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f6465203539202a2f0a2c323133202f2a2077 *69647468202a2f0a2c31333631202f2a20686569676874202a2f0a2c323237202f2a20686f7269 *42656172696e6758202a2f0a2c31303537202f2a20686f726942656172696e6759202a2f200a2c *353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203630202a2f *0a2c31313639202f2a207769647468202a2f0a2c31303833202f2a20686569676874202a2f0a2c *3134202f2a20686f726942656172696e6758202a2f0a2c31303634202f2a20686f726942656172 *696e6759202a2f200a2c31313936202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f6465203631202a2f0a2c31303433202f2a207769647468202a2f0a2c363030202f2a2068 *6569676874202a2f0a2c3736202f2a20686f726942656172696e6758202a2f0a2c383232202f2a *20686f726942656172696e6759202a2f200a2c31313936202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f6465203632202a2f0a2c31313639202f2a207769647468202a2f0a *2c31303833202f2a20686569676874202a2f0a2c3134202f2a20686f726942656172696e675820 *2a2f0a2c31303634202f2a20686f726942656172696e6759202a2f200a2c31313936202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f6465203633202a2f0a2c383931202f2a *207769647468202a2f0a2c31343838202f2a20686569676874202a2f0a2c313536202f2a20686f *726942656172696e6758202a2f0a2c31343838202f2a20686f726942656172696e6759202a2f20 *0a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203634 *202a2f0a2c31363236202f2a207769647468202a2f0a2c31353532202f2a20686569676874202a *2f0a2c323235202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a20686f7269 *42656172696e6759202a2f200a2c32303739202f2a20686f7269416476616e6365202a2f0a2f2a *2043686172636f6465203635202a2f0a2c31333131202f2a207769647468202a2f0a2c31343639 *202f2a20686569676874202a2f0a2c3330202f2a20686f726942656172696e6758202a2f0a2c31 *343639202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f6465203636202a2f0a2c31313333202f2a20776964 *7468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313531202f2a20686f72694265 *6172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c3133 *3636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203637202a2f0a *2c31333033202f2a207769647468202a2f0a2c31353437202f2a20686569676874202a2f0a2c39 *30202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a20686f72694265617269 *6e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f6465203638202a2f0a2c31323134202f2a207769647468202a2f0a2c31343639202f2a2068 *6569676874202a2f0a2c313635202f2a20686f726942656172696e6758202a2f0a2c3134363920 *2f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f6465203639202a2f0a2c31303836202f2a207769647468202a *2f0a2c31343639202f2a20686569676874202a2f0a2c313735202f2a20686f726942656172696e *6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31333636202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203730202a2f0a2c313031 *39202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313735202f *2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759 *202a2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64 *65203731202a2f0a2c31333432202f2a207769647468202a2f0a2c31353438202f2a2068656967 *6874202a2f0a2c3939202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a2068 *6f726942656172696e6759202a2f200a2c31353933202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203732202a2f0a2c31313636202f2a207769647468202a2f0a2c31 *343639202f2a20686569676874202a2f0a2c313631202f2a20686f726942656172696e6758202a *2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f *7269416476616e6365202a2f0a2f2a2043686172636f6465203733202a2f0a2c323031202f2a20 *7769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c323031202f2a20686f72 *6942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a *2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203734202a *2f0a2c383432202f2a207769647468202a2f0a2c31353038202f2a20686569676874202a2f0a2c *3335202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172 *696e6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f6465203735202a2f0a2c31323032202f2a207769647468202a2f0a2c31343639202f2a20 *686569676874202a2f0a2c313536202f2a20686f726942656172696e6758202a2f0a2c31343639 *202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f7269416476616e *6365202a2f0a2f2a2043686172636f6465203736202a2f0a2c393433202f2a207769647468202a *2f0a2c31343639202f2a20686569676874202a2f0a2c313536202f2a20686f726942656172696e *6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31313339202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203737202a2f0a2c313430 *38202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313531202f *2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759 *202a2f200a2c31373036202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64 *65203738202a2f0a2c31313636202f2a207769647468202a2f0a2c31343639202f2a2068656967 *6874202a2f0a2c313536202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20 *686f726942656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f6465203739202a2f0a2c31343332202f2a207769647468202a2f0a2c *31353532202f2a20686569676874202a2f0a2c3830202f2a20686f726942656172696e6758202a *2f0a2c31353039202f2a20686f726942656172696e6759202a2f200a2c31353933202f2a20686f *7269416476616e6365202a2f0a2f2a2043686172636f6465203830202a2f0a2c31303937202f2a *207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313735202f2a20686f *726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f20 *0a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203831 *202a2f0a2c31343332202f2a207769647468202a2f0a2c31363236202f2a20686569676874202a *2f0a2c3830202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a20686f726942 *656172696e6759202a2f200a2c31353933202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f6465203832202a2f0a2c31323230202f2a207769647468202a2f0a2c3134363920 *2f2a20686569676874202a2f0a2c313830202f2a20686f726942656172696e6758202a2f0a2c31 *343639202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f6465203833202a2f0a2c31313734202f2a20776964 *7468202a2f0a2c31353532202f2a20686569676874202a2f0a2c3936202f2a20686f7269426561 *72696e6758202a2f0a2c31353039202f2a20686f726942656172696e6759202a2f200a2c313336 *36202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203834202a2f0a2c *31313932202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3333 *202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e *6759202a2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f6465203835202a2f0a2c31313537202f2a207769647468202a2f0a2c31353038202f2a206865 *69676874202a2f0a2c313730202f2a20686f726942656172696e6758202a2f0a2c31343639202f *2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f6465203836202a2f0a2c31323832202f2a207769647468202a2f *0a2c31343639202f2a20686569676874202a2f0a2c3532202f2a20686f726942656172696e6758 *202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f6465203837202a2f0a2c3138363820 *2f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3337202f2a2068 *6f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f *200a2c31393333202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652038 *38202a2f0a2c31323930202f2a207769647468202a2f0a2c31343639202f2a2068656967687420 *2a2f0a2c3432202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f7269 *42656172696e6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a *2043686172636f6465203839202a2f0a2c31333039202f2a207769647468202a2f0a2c31343639 *202f2a20686569676874202a2f0a2c3432202f2a20686f726942656172696e6758202a2f0a2c31 *343639202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f72694164 *76616e6365202a2f0a2f2a2043686172636f6465203930202a2f0a2c31313537202f2a20776964 *7468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3437202f2a20686f7269426561 *72696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c313235 *31202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203931202a2f0a2c *333834202f2a207769647468202a2f0a2c31383832202f2a20686569676874202a2f0a2c313238 *202f2a20686f726942656172696e6758202a2f0a2c31343739202f2a20686f726942656172696e *6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *6465203932202a2f0a2c373237202f2a207769647468202a2f0a2c31343639202f2a2068656967 *6874202a2f0a2c2d3639202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20 *686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f6465203933202a2f0a2c333834202f2a207769647468202a2f0a2c3138 *3832202f2a20686569676874202a2f0a2c3437202f2a20686f726942656172696e6758202a2f0a *2c31343739202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f6465203934202a2f0a2c383538202f2a20776964 *7468202a2f0a2c383633202f2a20686569676874202a2f0a2c3531202f2a20686f726942656172 *696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c39363120 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203935202a2f0a2c3131 *3339202f2a207769647468202a2f0a2c313031202f2a20686569676874202a2f0a2c30202f2a20 *686f726942656172696e6758202a2f0a2c2d313535202f2a20686f726942656172696e6759202a *2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *3936202a2f0a2c343035202f2a207769647468202a2f0a2c343035202f2a20686569676874202a *2f0a2c3538202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f726942 *656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043 *686172636f6465203937202a2f0a2c31303133202f2a207769647468202a2f0a2c31313333202f *2a20686569676874202a2f0a2c3832202f2a20686f726942656172696e6758202a2f0a2c313039 *37202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f6465203938202a2f0a2c393433202f2a20776964746820 *2a2f0a2c31353038202f2a20686569676874202a2f0a2c313138202f2a20686f72694265617269 *6e6758202a2f0a2c31343734202f2a20686f726942656172696e6759202a2f200a2c3131333920 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203939202a2f0a2c3931 *37202f2a207769647468202a2f0a2c31313333202f2a20686569676874202a2f0a2c3539202f2a *20686f726942656172696e6758202a2f0a2c31313032202f2a20686f726942656172696e675920 *2a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *20313030202a2f0a2c393439202f2a207769647468202a2f0a2c31353132202f2a206865696768 *74202a2f0a2c3536202f2a20686f726942656172696e6758202a2f0a2c31343734202f2a20686f *726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520313031202a2f0a2c393738202f2a207769647468202a2f0a2c3131 *3335202f2a20686569676874202a2f0a2c3732202f2a20686f726942656172696e6758202a2f0a *2c31303937202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520313032202a2f0a2c353037202f2a2077 *69647468202a2f0a2c31343930202f2a20686569676874202a2f0a2c3238202f2a20686f726942 *656172696e6758202a2f0a2c31343930202f2a20686f726942656172696e6759202a2f200a2c35 *3639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313033202a2f *0a2c393339202f2a207769647468202a2f0a2c31353530202f2a20686569676874202a2f0a2c36 *31202f2a20686f726942656172696e6758202a2f0a2c31303937202f2a20686f72694265617269 *6e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520313034202a2f0a2c383733202f2a207769647468202a2f0a2c31343734202f2a2068 *6569676874202a2f0a2c313332202f2a20686f726942656172696e6758202a2f0a2c3134373420 *2f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f646520313035202a2f0a2c313833202f2a207769647468202a *2f0a2c31343639202f2a20686569676874202a2f0a2c313332202f2a20686f726942656172696e *6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c343535202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313036202a2f0a2c333530 *202f2a207769647468202a2f0a2c31393031202f2a20686569676874202a2f0a2c2d3338202f2a *20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e675920 *2a2f200a2c343535202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *313037202a2f0a2c383838202f2a207769647468202a2f0a2c31343639202f2a20686569676874 *202a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f *726942656172696e6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520313038202a2f0a2c313830202f2a207769647468202a2f0a2c3134 *3639202f2a20686569676874202a2f0a2c313337202f2a20686f726942656172696e6758202a2f *0a2c31343639202f2a20686f726942656172696e6759202a2f200a2c343535202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520313039202a2f0a2c31343431202f2a20 *7769647468202a2f0a2c31303935202f2a20686569676874202a2f0a2c313332202f2a20686f72 *6942656172696e6758202a2f0a2c31303935202f2a20686f726942656172696e6759202a2f200a *2c31373036202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313130 *202a2f0a2c383733202f2a207769647468202a2f0a2c31303937202f2a20686569676874202a2f *0a2c313332202f2a20686f726942656172696e6758202a2f0a2c31303937202f2a20686f726942 *656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f646520313131202a2f0a2c393938202f2a207769647468202a2f0a2c3131343120 *2f2a20686569676874202a2f0a2c3539202f2a20686f726942656172696e6758202a2f0a2c3131 *3032202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f646520313132202a2f0a2c393433202f2a2077696474 *68202a2f0a2c31353234202f2a20686569676874202a2f0a2c313138202f2a20686f7269426561 *72696e6758202a2f0a2c31303937202f2a20686f726942656172696e6759202a2f200a2c313133 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313133202a2f0a *2c393435202f2a207769647468202a2f0a2c31353232202f2a20686569676874202a2f0a2c3630 *202f2a20686f726942656172696e6758202a2f0a2c31303935202f2a20686f726942656172696e *6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520313134202a2f0a2c353231202f2a207769647468202a2f0a2c31303935202f2a206865 *69676874202a2f0a2c313337202f2a20686f726942656172696e6758202a2f0a2c31303935202f *2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f646520313135202a2f0a2c383834202f2a207769647468202a2f0a *2c31313430202f2a20686569676874202a2f0a2c3636202f2a20686f726942656172696e675820 *2a2f0a2c31303939202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520313136202a2f0a2c343938202f *2a207769647468202a2f0a2c31333837202f2a20686569676874202a2f0a2c3233202f2a20686f *726942656172696e6758202a2f0a2c31333730202f2a20686f726942656172696e6759202a2f20 *0a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313137 *202a2f0a2c383632202f2a207769647468202a2f0a2c31313236202f2a20686569676874202a2f *0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31303937202f2a20686f726942 *656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f646520313138202a2f0a2c393931202f2a207769647468202a2f0a2c3130373120 *2f2a20686569676874202a2f0a2c3131202f2a20686f726942656172696e6758202a2f0a2c3130 *3731202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f646520313139202a2f0a2c31343233202f2a20776964 *7468202a2f0a2c31303731202f2a20686569676874202a2f0a2c3138202f2a20686f7269426561 *72696e6758202a2f0a2c31303731202f2a20686f726942656172696e6759202a2f200a2c313437 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313230202a2f0a *2c393832202f2a207769647468202a2f0a2c31303731202f2a20686569676874202a2f0a2c3131 *202f2a20686f726942656172696e6758202a2f0a2c31303731202f2a20686f726942656172696e *6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520313231202a2f0a2c393739202f2a207769647468202a2f0a2c31353336202f2a206865 *69676874202a2f0a2c3231202f2a20686f726942656172696e6758202a2f0a2c31303937202f2a *20686f726942656172696e6759202a2f200a2c31303234202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f646520313232202a2f0a2c383936202f2a207769647468202a2f0a *2c31303937202f2a20686569676874202a2f0a2c3532202f2a20686f726942656172696e675820 *2a2f0a2c31303937202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520313233202a2f0a2c363833202f *2a207769647468202a2f0a2c31393133202f2a20686569676874202a2f0a2c2d3433202f2a2068 *6f726942656172696e6758202a2f0a2c31343935202f2a20686f726942656172696e6759202a2f *200a2c363834202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203132 *34202a2f0a2c313731202f2a207769647468202a2f0a2c31343930202f2a20686569676874202a *2f0a2c313832202f2a20686f726942656172696e6758202a2f0a2c31343930202f2a20686f7269 *42656172696e6759202a2f200a2c353332202f2a20686f7269416476616e6365202a2f0a2f2a20 *43686172636f646520313235202a2f0a2c363833202f2a207769647468202a2f0a2c3139313320 *2f2a20686569676874202a2f0a2c3432202f2a20686f726942656172696e6758202a2f0a2c3134 *3935202f2a20686f726942656172696e6759202a2f200a2c363834202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520313236202a2f0a2c31313930202f2a2077696474 *68202a2f0a2c343035202f2a20686569676874202a2f0a2c32202f2a20686f726942656172696e *6758202a2f0a2c373235202f2a20686f726942656172696e6759202a2f200a2c31313936202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313237202a2f0a2c300a2c *300a2c300a2c300a2c300a2f2a2043686172636f646520313238202a2f0a2c300a2c300a2c300a *2c300a2c300a2f2a2043686172636f646520313239202a2f0a2c300a2c300a2c300a2c300a2c30 *0a2f2a2043686172636f646520313330202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043 *686172636f646520313331202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f *646520313332202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465203133 *33202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313334202a2f0a *2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313335202a2f0a2c300a2c30 *0a2c300a2c300a2c300a2f2a2043686172636f646520313336202a2f0a2c300a2c300a2c300a2c *300a2c300a2f2a2043686172636f646520313337202a2f0a2c300a2c300a2c300a2c300a2c300a *2f2a2043686172636f646520313338202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a204368 *6172636f646520313339202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f64 *6520313430202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313431 *202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313432202a2f0a2c *300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313433202a2f0a2c300a2c300a *2c300a2c300a2c300a2f2a2043686172636f646520313434202a2f0a2c300a2c300a2c300a2c30 *0a2c300a2f2a2043686172636f646520313435202a2f0a2c300a2c300a2c300a2c300a2c300a2f *2a2043686172636f646520313436202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a20436861 *72636f646520313437202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f6465 *20313438202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f64652031343920 *2a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313530202a2f0a2c30 *0a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313531202a2f0a2c300a2c300a2c *300a2c300a2c300a2f2a2043686172636f646520313532202a2f0a2c300a2c300a2c300a2c300a *2c300a2f2a2043686172636f646520313533202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a *2043686172636f646520313534202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172 *636f646520313535202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520 *313536202a2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313537202a *2f0a2c300a2c300a2c300a2c300a2c300a2f2a2043686172636f646520313538202a2f0a2c300a *2c300a2c300a2c300a2c300a2f2a2043686172636f646520313539202a2f0a2c300a2c300a2c30 *0a2c300a2c300a2f2a2043686172636f646520313630202a2f0a2c30202f2a207769647468202a *2f0a2c30202f2a20686569676874202a2f0a2c30202f2a20686f726942656172696e6758202a2f *0a2c30202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476 *616e6365202a2f0a2f2a2043686172636f646520313631202a2f0a2c323034202f2a2077696474 *68202a2f0a2c31343730202f2a20686569676874202a2f0a2c323332202f2a20686f7269426561 *72696e6758202a2f0a2c31303731202f2a20686f726942656172696e6759202a2f200a2c363832 *202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313632202a2f0a2c *393436202f2a207769647468202a2f0a2c31353132202f2a20686569676874202a2f0a2c313034 *202f2a20686f726942656172696e6758202a2f0a2c31323735202f2a20686f726942656172696e *6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520313633202a2f0a2c31303336202f2a207769647468202a2f0a2c31353033202f2a2068 *6569676874202a2f0a2c3536202f2a20686f726942656172696e6758202a2f0a2c31343637202f *2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520313634202a2f0a2c393730202f2a207769647468202a2f *0a2c393731202f2a20686569676874202a2f0a2c3735202f2a20686f726942656172696e675820 *2a2f0a2c31313839202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520313635202a2f0a2c3131373820 *2f2a207769647468202a2f0a2c31343035202f2a20686569676874202a2f0a2c2d3331202f2a20 *686f726942656172696e6758202a2f0a2c31343035202f2a20686f726942656172696e6759202a *2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *313636202a2f0a2c313731202f2a207769647468202a2f0a2c31343930202f2a20686569676874 *202a2f0a2c313832202f2a20686f726942656172696e6758202a2f0a2c31343930202f2a20686f *726942656172696e6759202a2f200a2c353332202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520313637202a2f0a2c393730202f2a207769647468202a2f0a2c313930 *32202f2a20686569676874202a2f0a2c3735202f2a20686f726942656172696e6758202a2f0a2c *31343730202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520313638202a2f0a2c353137202f2a207769 *647468202a2f0a2c333438202f2a20686569676874202a2f0a2c3732202f2a20686f7269426561 *72696e6758202a2f0a2c31343435202f2a20686f726942656172696e6759202a2f200a2c363832 *202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313639202a2f0a2c *31343730202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3139 *202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e *6759202a2f200a2c31353039202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520313730202a2f0a2c363539202f2a207769647468202a2f0a2c363832202f2a20686569 *676874202a2f0a2c3539202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a20 *686f726942656172696e6759202a2f200a2c373538202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f646520313731202a2f0a2c373432202f2a207769647468202a2f0a2c36 *3932202f2a20686569676874202a2f0a2c313934202f2a20686f726942656172696e6758202a2f *0a2c393035202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520313732202a2f0a2c31303433202f2a20 *7769647468202a2f0a2c363030202f2a20686569676874202a2f0a2c3736202f2a20686f726942 *656172696e6758202a2f0a2c383232202f2a20686f726942656172696e6759202a2f200a2c3131 *3936202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313733202a2f *0a2c353032202f2a207769647468202a2f0a2c313835202f2a20686569676874202a2f0a2c3835 *202f2a20686f726942656172696e6758202a2f0a2c363633202f2a20686f726942656172696e67 *59202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64 *6520313734202a2f0a2c31343637202f2a207769647468202a2f0a2c31343639202f2a20686569 *676874202a2f0a2c3231202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20 *686f726942656172696e6759202a2f200a2c31353039202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f646520313735202a2f0a2c363430202f2a207769647468202a2f0a2c *313138202f2a20686569676874202a2f0a2c38202f2a20686f726942656172696e6758202a2f0a *2c31343030202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520313736202a2f0a2c363034202f2a207769 *647468202a2f0a2c363034202f2a20686569676874202a2f0a2c313131202f2a20686f72694265 *6172696e6758202a2f0a2c31343331202f2a20686f726942656172696e6759202a2f200a2c3831 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313737202a2f0a *2c31303433202f2a207769647468202a2f0a2c31303435202f2a20686569676874202a2f0a2c34 *30202f2a20686f726942656172696e6758202a2f0a2c31303435202f2a20686f72694265617269 *6e6759202a2f200a2c31313234202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520313738202a2f0a2c363430202f2a207769647468202a2f0a2c383631202f2a206865 *69676874202a2f0a2c3131202f2a20686f726942656172696e6758202a2f0a2c31343332202f2a *20686f726942656172696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f646520313739202a2f0a2c363437202f2a207769647468202a2f0a2c *383839202f2a20686569676874202a2f0a2c37202f2a20686f726942656172696e6758202a2f0a *2c31343331202f2a20686f726942656172696e6759202a2f200a2c363832202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520313830202a2f0a2c343035202f2a207769 *647468202a2f0a2c343035202f2a20686569676874202a2f0a2c313933202f2a20686f72694265 *6172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c3638 *32202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313831202a2f0a *2c31313738202f2a207769647468202a2f0a2c31343931202f2a20686569676874202a2f0a2c2d *3535202f2a20686f726942656172696e6758202a2f0a2c31303639202f2a20686f726942656172 *696e6759202a2f200a2c31313830202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f646520313832202a2f0a2c31303736202f2a207769647468202a2f0a2c31383332202f2a *20686569676874202a2f0a2c2d3131202f2a20686f726942656172696e6758202a2f0a2c313436 *39202f2a20686f726942656172696e6759202a2f200a2c31313030202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520313833202a2f0a2c323536202f2a207769647468 *202a2f0a2c323536202f2a20686569676874202a2f0a2c313531202f2a20686f72694265617269 *6e6758202a2f0a2c383239202f2a20686f726942656172696e6759202a2f200a2c353639202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313834202a2f0a2c343430 *202f2a207769647468202a2f0a2c343631202f2a20686569676874202a2f0a2c313031202f2a20 *686f726942656172696e6758202a2f0a2c30202f2a20686f726942656172696e6759202a2f200a *2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652031383520 *2a2f0a2c333832202f2a207769647468202a2f0a2c383535202f2a20686569676874202a2f0a2c *3837202f2a20686f726942656172696e6758202a2f0a2c31343236202f2a20686f726942656172 *696e6759202a2f200a2c363832202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520313836202a2f0a2c363532202f2a207769647468202a2f0a2c363832202f2a206865 *69676874202a2f0a2c3439202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a *20686f726942656172696e6759202a2f200a2c373438202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f646520313837202a2f0a2c373432202f2a207769647468202a2f0a2c *363932202f2a20686569676874202a2f0a2c313934202f2a20686f726942656172696e6758202a *2f0a2c393035202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f646520313838202a2f0a2c31343633202f2a *207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313633202f2a20686f *726942656172696e6758202a2f0a2c31343331202f2a20686f726942656172696e6759202a2f20 *0a2c31373038202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465203138 *39202a2f0a2c31353030202f2a207769647468202a2f0a2c31343639202f2a2068656967687420 *2a2f0a2c3930202f2a20686f726942656172696e6758202a2f0a2c31343331202f2a20686f7269 *42656172696e6759202a2f200a2c31373038202f2a20686f7269416476616e6365202a2f0a2f2a *2043686172636f646520313930202a2f0a2c31353730202f2a207769647468202a2f0a2c313436 *39202f2a20686569676874202a2f0a2c3735202f2a20686f726942656172696e6758202a2f0a2c *31343331202f2a20686f726942656172696e6759202a2f200a2c31373038202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520313931202a2f0a2c383934202f2a207769 *647468202a2f0a2c31343839202f2a20686569676874202a2f0a2c313836202f2a20686f726942 *656172696e6758202a2f0a2c31303736202f2a20686f726942656172696e6759202a2f200a2c31 *323531202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313932202a *2f0a2c31333131202f2a207769647468202a2f0a2c31383734202f2a20686569676874202a2f0a *2c3330202f2a20686f726942656172696e6758202a2f0a2c31383734202f2a20686f7269426561 *72696e6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a204368 *6172636f646520313933202a2f0a2c31333131202f2a207769647468202a2f0a2c31383734202f *2a20686569676874202a2f0a2c3330202f2a20686f726942656172696e6758202a2f0a2c313837 *34202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520313934202a2f0a2c31333131202f2a2077696474 *68202a2f0a2c31383734202f2a20686569676874202a2f0a2c3330202f2a20686f726942656172 *696e6758202a2f0a2c31383734202f2a20686f726942656172696e6759202a2f200a2c31333636 *202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313935202a2f0a2c *31333131202f2a207769647468202a2f0a2c31383431202f2a20686569676874202a2f0a2c3330 *202f2a20686f726942656172696e6758202a2f0a2c31383431202f2a20686f726942656172696e *6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a204368617263 *6f646520313936202a2f0a2c31333131202f2a207769647468202a2f0a2c31383137202f2a2068 *6569676874202a2f0a2c3330202f2a20686f726942656172696e6758202a2f0a2c31383137202f *2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520313937202a2f0a2c31333131202f2a207769647468202a *2f0a2c31393436202f2a20686569676874202a2f0a2c3330202f2a20686f726942656172696e67 *58202a2f0a2c31393436202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520313938202a2f0a2c313933 *32202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3136202f2a *20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e675920 *2a2f200a2c32303438202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *20313939202a2f0a2c31333033202f2a207769647468202a2f0a2c31393730202f2a2068656967 *6874202a2f0a2c3930202f2a20686f726942656172696e6758202a2f0a2c31353039202f2a2068 *6f726942656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f646520323030202a2f0a2c31303836202f2a207769647468202a2f0a2c *31383734202f2a20686569676874202a2f0a2c313735202f2a20686f726942656172696e675820 *2a2f0a2c31383734202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520323031202a2f0a2c3130383620 *2f2a207769647468202a2f0a2c31383734202f2a20686569676874202a2f0a2c313735202f2a20 *686f726942656172696e6758202a2f0a2c31383734202f2a20686f726942656172696e6759202a *2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *323032202a2f0a2c31303836202f2a207769647468202a2f0a2c31383734202f2a206865696768 *74202a2f0a2c313735202f2a20686f726942656172696e6758202a2f0a2c31383734202f2a2068 *6f726942656172696e6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f646520323033202a2f0a2c31303836202f2a207769647468202a2f0a2c *31383137202f2a20686569676874202a2f0a2c313735202f2a20686f726942656172696e675820 *2a2f0a2c31383137202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520323034202a2f0a2c343035202f *2a207769647468202a2f0a2c31383733202f2a20686569676874202a2f0a2c32202f2a20686f72 *6942656172696e6758202a2f0a2c31383733202f2a20686f726942656172696e6759202a2f200a *2c353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032303520 *2a2f0a2c343035202f2a207769647468202a2f0a2c31383730202f2a20686569676874202a2f0a *2c313337202f2a20686f726942656172696e6758202a2f0a2c31383730202f2a20686f72694265 *6172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a204368 *6172636f646520323036202a2f0a2c353937202f2a207769647468202a2f0a2c31383738202f2a *20686569676874202a2f0a2c2d3236202f2a20686f726942656172696e6758202a2f0a2c313837 *38202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e *6365202a2f0a2f2a2043686172636f646520323037202a2f0a2c353137202f2a20776964746820 *2a2f0a2c31383133202f2a20686569676874202a2f0a2c3136202f2a20686f726942656172696e *6758202a2f0a2c31383133202f2a20686f726942656172696e6759202a2f200a2c353639202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323038202a2f0a2c313334 *36202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c3333202f2a *20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e675920 *2a2f200a2c31343739202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *20323039202a2f0a2c31313636202f2a207769647468202a2f0a2c31383431202f2a2068656967 *6874202a2f0a2c313536202f2a20686f726942656172696e6758202a2f0a2c31383431202f2a20 *686f726942656172696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f646520323130202a2f0a2c31343332202f2a207769647468202a2f0a *2c31393537202f2a20686569676874202a2f0a2c3830202f2a20686f726942656172696e675820 *2a2f0a2c31393134202f2a20686f726942656172696e6759202a2f200a2c31353933202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520323131202a2f0a2c3134333220 *2f2a207769647468202a2f0a2c31393537202f2a20686569676874202a2f0a2c3830202f2a2068 *6f726942656172696e6758202a2f0a2c31393134202f2a20686f726942656172696e6759202a2f *200a2c31353933202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032 *3132202a2f0a2c31343332202f2a207769647468202a2f0a2c31393537202f2a20686569676874 *202a2f0a2c3830202f2a20686f726942656172696e6758202a2f0a2c31393134202f2a20686f72 *6942656172696e6759202a2f200a2c31353933202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520323133202a2f0a2c31343332202f2a207769647468202a2f0a2c3139 *3234202f2a20686569676874202a2f0a2c3830202f2a20686f726942656172696e6758202a2f0a *2c31383831202f2a20686f726942656172696e6759202a2f200a2c31353933202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520323134202a2f0a2c31343332202f2a20 *7769647468202a2f0a2c31393030202f2a20686569676874202a2f0a2c3830202f2a20686f7269 *42656172696e6758202a2f0a2c31383537202f2a20686f726942656172696e6759202a2f200a2c *31353933202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032313520 *2a2f0a2c393938202f2a207769647468202a2f0a2c393938202f2a20686569676874202a2f0a2c *313030202f2a20686f726942656172696e6758202a2f0a2c31303231202f2a20686f7269426561 *72696e6759202a2f200a2c31313936202f2a20686f7269416476616e6365202a2f0a2f2a204368 *6172636f646520323136202a2f0a2c31343436202f2a207769647468202a2f0a2c31353533202f *2a20686569676874202a2f0a2c3636202f2a20686f726942656172696e6758202a2f0a2c313531 *30202f2a20686f726942656172696e6759202a2f200a2c31353933202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520323137202a2f0a2c31313537202f2a2077696474 *68202a2f0a2c31393133202f2a20686569676874202a2f0a2c313730202f2a20686f7269426561 *72696e6758202a2f0a2c31383734202f2a20686f726942656172696e6759202a2f200a2c313437 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323138202a2f0a *2c31313537202f2a207769647468202a2f0a2c31393133202f2a20686569676874202a2f0a2c31 *3730202f2a20686f726942656172696e6758202a2f0a2c31383734202f2a20686f726942656172 *696e6759202a2f200a2c31343739202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f646520323139202a2f0a2c31313537202f2a207769647468202a2f0a2c31393133202f2a *20686569676874202a2f0a2c313730202f2a20686f726942656172696e6758202a2f0a2c313837 *34202f2a20686f726942656172696e6759202a2f200a2c31343739202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520323230202a2f0a2c31313537202f2a2077696474 *68202a2f0a2c31383536202f2a20686569676874202a2f0a2c313730202f2a20686f7269426561 *72696e6758202a2f0a2c31383137202f2a20686f726942656172696e6759202a2f200a2c313437 *39202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323231202a2f0a *2c31333039202f2a207769647468202a2f0a2c31383734202f2a20686569676874202a2f0a2c34 *32202f2a20686f726942656172696e6758202a2f0a2c31383734202f2a20686f72694265617269 *6e6759202a2f200a2c31333636202f2a20686f7269416476616e6365202a2f0a2f2a2043686172 *636f646520323232202a2f0a2c31303938202f2a207769647468202a2f0a2c31343637202f2a20 *686569676874202a2f0a2c313734202f2a20686f726942656172696e6758202a2f0a2c31343637 *202f2a20686f726942656172696e6759202a2f200a2c31333636202f2a20686f7269416476616e *6365202a2f0a2f2a2043686172636f646520323233202a2f0a2c393037202f2a20776964746820 *2a2f0a2c31353230202f2a20686569676874202a2f0a2c313939202f2a20686f72694265617269 *6e6758202a2f0a2c31343931202f2a20686f726942656172696e6759202a2f200a2c3132353120 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323234202a2f0a2c31 *303133202f2a207769647468202a2f0a2c31353338202f2a20686569676874202a2f0a2c383220 *2f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e67 *59202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f *646520323235202a2f0a2c31303133202f2a207769647468202a2f0a2c31353338202f2a206865 *69676874202a2f0a2c3832202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a *20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e636520 *2a2f0a2f2a2043686172636f646520323236202a2f0a2c31303133202f2a207769647468202a2f *0a2c31353338202f2a20686569676874202a2f0a2c3832202f2a20686f726942656172696e6758 *202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20 *686f7269416476616e6365202a2f0a2f2a2043686172636f646520323237202a2f0a2c31303133 *202f2a207769647468202a2f0a2c31353035202f2a20686569676874202a2f0a2c3832202f2a20 *686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e6759202a *2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520 *323238202a2f0a2c31303133202f2a207769647468202a2f0a2c31343831202f2a206865696768 *74202a2f0a2c3832202f2a20686f726942656172696e6758202a2f0a2c31343435202f2a20686f *726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520323239202a2f0a2c31303133202f2a207769647468202a2f0a2c31 *363632202f2a20686569676874202a2f0a2c3832202f2a20686f726942656172696e6758202a2f *0a2c31363236202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f72 *69416476616e6365202a2f0a2f2a2043686172636f646520323330202a2f0a2c31363632202f2a *207769647468202a2f0a2c31313333202f2a20686569676874202a2f0a2c3733202f2a20686f72 *6942656172696e6758202a2f0a2c31303937202f2a20686f726942656172696e6759202a2f200a *2c31383231202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323331 *202a2f0a2c393137202f2a207769647468202a2f0a2c31353633202f2a20686569676874202a2f *0a2c3539202f2a20686f726942656172696e6758202a2f0a2c31313032202f2a20686f72694265 *6172696e6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a2f2a2043 *686172636f646520323332202a2f0a2c393738202f2a207769647468202a2f0a2c31353430202f *2a20686569676874202a2f0a2c3732202f2a20686f726942656172696e6758202a2f0a2c313530 *32202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f726941647661 *6e6365202a2f0a2f2a2043686172636f646520323333202a2f0a2c393738202f2a207769647468 *202a2f0a2c31353430202f2a20686569676874202a2f0a2c3732202f2a20686f72694265617269 *6e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c3131333920 *2f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323334202a2f0a2c39 *3738202f2a207769647468202a2f0a2c31353430202f2a20686569676874202a2f0a2c3732202f *2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759 *202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64 *6520323335202a2f0a2c393738202f2a207769647468202a2f0a2c31343833202f2a2068656967 *6874202a2f0a2c3732202f2a20686f726942656172696e6758202a2f0a2c31343435202f2a2068 *6f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f *0a2f2a2043686172636f646520323336202a2f0a2c343035202f2a207769647468202a2f0a2c31 *353032202f2a20686569676874202a2f0a2c3133202f2a20686f726942656172696e6758202a2f *0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520323337202a2f0a2c343035202f2a2077 *69647468202a2f0a2c31353032202f2a20686569676874202a2f0a2c313433202f2a20686f7269 *42656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c *353639202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323338202a *2f0a2c353937202f2a207769647468202a2f0a2c31353032202f2a20686569676874202a2f0a2c *2d3137202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f7269426561 *72696e6759202a2f200a2c353639202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f646520323339202a2f0a2c353137202f2a207769647468202a2f0a2c31343435202f2a20 *686569676874202a2f0a2c3232202f2a20686f726942656172696e6758202a2f0a2c3134343520 *2f2a20686f726942656172696e6759202a2f200a2c353639202f2a20686f7269416476616e6365 *202a2f0a2f2a2043686172636f646520323430202a2f0a2c31303030202f2a207769647468202a *2f0a2c31363630202f2a20686569676874202a2f0a2c3631202f2a20686f726942656172696e67 *58202a2f0a2c31363233202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a *20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323431202a2f0a2c383733 *202f2a207769647468202a2f0a2c31343639202f2a20686569676874202a2f0a2c313332202f2a *20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172696e675920 *2a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f6465 *20323432202a2f0a2c393938202f2a207769647468202a2f0a2c31353431202f2a206865696768 *74202a2f0a2c3539202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20686f *726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a *2f2a2043686172636f646520323433202a2f0a2c393938202f2a207769647468202a2f0a2c3135 *3431202f2a20686569676874202a2f0a2c3539202f2a20686f726942656172696e6758202a2f0a *2c31353032202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269 *416476616e6365202a2f0a2f2a2043686172636f646520323434202a2f0a2c393938202f2a2077 *69647468202a2f0a2c31353431202f2a20686569676874202a2f0a2c3539202f2a20686f726942 *656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c31 *313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323435202a *2f0a2c393938202f2a207769647468202a2f0a2c31353038202f2a20686569676874202a2f0a2c *3539202f2a20686f726942656172696e6758202a2f0a2c31343639202f2a20686f726942656172 *696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a20436861 *72636f646520323436202a2f0a2c393938202f2a207769647468202a2f0a2c31343834202f2a20 *686569676874202a2f0a2c3539202f2a20686f726942656172696e6758202a2f0a2c3134343520 *2f2a20686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e63 *65202a2f0a2f2a2043686172636f646520323437202a2f0a2c31303433202f2a20776964746820 *2a2f0a2c31303033202f2a20686569676874202a2f0a2c3430202f2a20686f726942656172696e *6758202a2f0a2c31303234202f2a20686f726942656172696e6759202a2f200a2c31313234202f *2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323438202a2f0a2c3130 *3435202f2a207769647468202a2f0a2c31313539202f2a20686569676874202a2f0a2c3932202f *2a20686f726942656172696e6758202a2f0a2c31313131202f2a20686f726942656172696e6759 *202a2f200a2c31323531202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64 *6520323439202a2f0a2c383632202f2a207769647468202a2f0a2c31353331202f2a2068656967 *6874202a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31353032202f2a20 *686f726942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a *2f0a2f2a2043686172636f646520323530202a2f0a2c383632202f2a207769647468202a2f0a2c *31353331202f2a20686569676874202a2f0a2c313238202f2a20686f726942656172696e675820 *2a2f0a2c31353032202f2a20686f726942656172696e6759202a2f200a2c31313339202f2a2068 *6f7269416476616e6365202a2f0a2f2a2043686172636f646520323531202a2f0a2c383632202f *2a207769647468202a2f0a2c31353331202f2a20686569676874202a2f0a2c313238202f2a2068 *6f726942656172696e6758202a2f0a2c31353032202f2a20686f726942656172696e6759202a2f *200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f64652032 *3532202a2f0a2c383632202f2a207769647468202a2f0a2c31343734202f2a2068656967687420 *2a2f0a2c313238202f2a20686f726942656172696e6758202a2f0a2c31343435202f2a20686f72 *6942656172696e6759202a2f200a2c31313339202f2a20686f7269416476616e6365202a2f0a2f *2a2043686172636f646520323533202a2f0a2c393739202f2a207769647468202a2f0a2c313934 *31202f2a20686569676874202a2f0a2c3231202f2a20686f726942656172696e6758202a2f0a2c *31353032202f2a20686f726942656172696e6759202a2f200a2c31303234202f2a20686f726941 *6476616e6365202a2f0a2f2a2043686172636f646520323534202a2f0a2c393337202f2a207769 *647468202a2f0a2c31383932202f2a20686569676874202a2f0a2c313238202f2a20686f726942 *656172696e6758202a2f0a2c31343535202f2a20686f726942656172696e6759202a2f200a2c31 *313339202f2a20686f7269416476616e6365202a2f0a2f2a2043686172636f646520323535202a *2f0a2c393739202f2a207769647468202a2f0a2c31383834202f2a20686569676874202a2f0a2c *3231202f2a20686f726942656172696e6758202a2f0a2c31343435202f2a20686f726942656172 *696e6759202a2f200a2c31303234202f2a20686f7269416476616e6365202a2f0a7d3b0a737461 *74696320636f6e737420756e7369676e6564206c6f6e6720666d65747269635b5d3d7b0a313933 *32202f2a206d61785f7769647468202a2f0a2c31393730202f2a206d61785f686569676874202a *2f0a2c323337202f2a206d61785f686f726942656172696e6758202a2f0a2c31393436202f2a20 *6d61785f686f726942656172696e6759202a2f0a2c32303739202f2a206d61785f686f72694164 *76616e6365202a2f0a7d3b0a23656e6469660a newhex *2369666e646566205f4d4554524943535f485f0a23646566696e65205f4d4554524943535f485f *0a73746174696320636f6e737420756e7369676e6564206c6f6e6720676d65747269635b5d3d7b *0a3237380a2c3237380a2c3335350a2c3535360a2c3535360a2c3838390a2c3636370a2c323232 *0a2c3333330a2c3333330a2c3338390a2c3538340a2c3237380a2c3333330a2c3237380a2c3237 *380a2c3535360a2c3535360a2c3535360a2c3535360a2c3535360a2c3535360a2c3535360a2c35 *35360a2c3535360a2c3535360a2c3237380a2c3237380a2c3538340a2c3538340a2c3538340a2c *3535360a2c313031350a2c3636370a2c3636370a2c3732320a2c3732320a2c3636370a2c363131 *0a2c3737380a2c3732320a2c3237380a2c3530300a2c3636370a2c3535360a2c3833330a2c3732 *320a2c3737380a2c3636370a2c3737380a2c3732320a2c3636370a2c3631310a2c3732320a2c36 *36370a2c3934340a2c3636370a2c3636370a2c3631310a2c3237380a2c3237380a2c3237380a2c *3436390a2c3535360a2c3232320a2c3535360a2c3535360a2c3530300a2c3535360a2c3535360a *2c3237380a2c3535360a2c3535360a2c3232320a2c3232320a2c3530300a2c3232320a2c383333 *0a2c3535360a2c3535360a2c3535360a2c3535360a2c3333330a2c3530300a2c3237380a2c3535 *360a2c3530300a2c3732320a2c3530300a2c3530300a2c3530300a2c3333340a2c3236300a2c33 *33340a2c3538340a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c *3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a *2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c323738 *0a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237 *380a2c3237380a2c3237380a2c3237380a2c3237380a2c3333330a2c3535360a2c3535360a2c31 *36370a2c3535360a2c3535360a2c3535360a2c3535360a2c3139310a2c3333330a2c3535360a2c *3333330a2c3333330a2c3530300a2c3530300a2c3237380a2c3535360a2c3535360a2c3535360a *2c3237380a2c3237380a2c3533370a2c3335300a2c3232320a2c3333330a2c3333330a2c353536 *0a2c313030300a2c313030300a2c3237380a2c3631310a2c3237380a2c3333330a2c3333330a2c *3333330a2c3333330a2c3333330a2c3333330a2c3333330a2c3333330a2c3237380a2c3333330a *2c3333330a2c3237380a2c3333330a2c3333330a2c3333330a2c313030300a2c3237380a2c3237 *380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c32 *37380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c313030300a *2c3237380a2c3337300a2c3237380a2c3237380a2c3237380a2c3237380a2c3535360a2c373738 *0a2c313030300a2c3336350a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c38 *38390a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3232320a2c *3631310a2c3934340a2c3631310a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a *2c3333330a2c3437340a2c3535360a2c3535360a2c3838390a2c3732320a2c3237380a2c333333 *0a2c3333330a2c3338390a2c3538340a2c3237380a2c3333330a2c3237380a2c3237380a2c3535 *360a2c3535360a2c3535360a2c3535360a2c3535360a2c3535360a2c3535360a2c3535360a2c35 *35360a2c3535360a2c3333330a2c3333330a2c3538340a2c3538340a2c3538340a2c3631310a2c *3937350a2c3732320a2c3732320a2c3732320a2c3732320a2c3636370a2c3631310a2c3737380a *2c3732320a2c3237380a2c3535360a2c3732320a2c3631310a2c3833330a2c3732320a2c373738 *0a2c3636370a2c3737380a2c3732320a2c3636370a2c3631310a2c3732320a2c3636370a2c3934 *340a2c3636370a2c3636370a2c3631310a2c3333330a2c3237380a2c3333330a2c3538340a2c35 *35360a2c3237380a2c3535360a2c3631310a2c3535360a2c3631310a2c3535360a2c3333330a2c *3631310a2c3631310a2c3237380a2c3237380a2c3535360a2c3237380a2c3838390a2c3631310a *2c3631310a2c3631310a2c3631310a2c3338390a2c3535360a2c3333330a2c3631310a2c353536 *0a2c3737380a2c3535360a2c3535360a2c3530300a2c3338390a2c3238300a2c3338390a2c3538 *340a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c32 *37380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c *3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a *2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c323738 *0a2c3237380a2c3237380a2c3237380a2c3333330a2c3535360a2c3535360a2c3136370a2c3535 *360a2c3535360a2c3535360a2c3535360a2c3233380a2c3530300a2c3535360a2c3333330a2c33 *33330a2c3631310a2c3631310a2c3237380a2c3535360a2c3535360a2c3535360a2c3237380a2c *3237380a2c3535360a2c3335300a2c3237380a2c3530300a2c3530300a2c3535360a2c31303030 *0a2c313030300a2c3237380a2c3631310a2c3237380a2c3333330a2c3333330a2c3333330a2c33 *33330a2c3333330a2c3333330a2c3333330a2c3333330a2c3237380a2c3333330a2c3333330a2c *3237380a2c3333330a2c3333330a2c3333330a2c313030300a2c3237380a2c3237380a2c323738 *0a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237 *380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c313030300a2c3237380a2c *3337300a2c3237380a2c3237380a2c3237380a2c3237380a2c3631310a2c3737380a2c31303030 *0a2c3336350a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3838390a2c3237 *380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3631310a2c39 *34340a2c3631310a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c *3335350a2c3535360a2c3535360a2c3838390a2c3636370a2c3232320a2c3333330a2c3333330a *2c3338390a2c3538340a2c3237380a2c3333330a2c3237380a2c3237380a2c3535360a2c353536 *0a2c3535360a2c3535360a2c3535360a2c3535360a2c3535360a2c3535360a2c3535360a2c3535 *360a2c3237380a2c3237380a2c3538340a2c3538340a2c3538340a2c3535360a2c313031350a2c *3636370a2c3636370a2c3732320a2c3732320a2c3636370a2c3631310a2c3737380a2c3732320a *2c3237380a2c3530300a2c3636370a2c3535360a2c3833330a2c3732320a2c3737380a2c363637 *0a2c3737380a2c3732320a2c3636370a2c3631310a2c3732320a2c3636370a2c3934340a2c3636 *370a2c3636370a2c3631310a2c3237380a2c3237380a2c3237380a2c3436390a2c3535360a2c32 *32320a2c3535360a2c3535360a2c3530300a2c3535360a2c3535360a2c3237380a2c3535360a2c *3535360a2c3232320a2c3232320a2c3530300a2c3232320a2c3833330a2c3535360a2c3535360a *2c3535360a2c3535360a2c3333330a2c3530300a2c3237380a2c3535360a2c3530300a2c373232 *0a2c3530300a2c3530300a2c3530300a2c3333340a2c3236300a2c3333340a2c3538340a2c3237 *380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c32 *37380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c *3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a *2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c323738 *0a2c3237380a2c3237380a2c3333330a2c3535360a2c3535360a2c3136370a2c3535360a2c3535 *360a2c3535360a2c3535360a2c3139310a2c3333330a2c3535360a2c3333330a2c3333330a2c35 *30300a2c3530300a2c3237380a2c3535360a2c3535360a2c3535360a2c3237380a2c3237380a2c *3533370a2c3335300a2c3232320a2c3333330a2c3333330a2c3535360a2c313030300a2c313030 *300a2c3237380a2c3631310a2c3237380a2c3333330a2c3333330a2c3333330a2c3333330a2c33 *33330a2c3333330a2c3333330a2c3333330a2c3237380a2c3333330a2c3333330a2c3237380a2c *3333330a2c3333330a2c3333330a2c313030300a2c3237380a2c3237380a2c3237380a2c323738 *0a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237 *380a2c3237380a2c3237380a2c3237380a2c3237380a2c313030300a2c3237380a2c3337300a2c *3237380a2c3237380a2c3237380a2c3237380a2c3535360a2c3737380a2c313030300a2c333635 *0a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3838390a2c3237380a2c3237 *380a2c3237380a2c3237380a2c3237380a2c3237380a2c3232320a2c3631310a2c3934340a2c36 *31310a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3333330a2c3437340a2c *3535360a2c3535360a2c3838390a2c3732320a2c3237380a2c3333330a2c3333330a2c3338390a *2c3538340a2c3237380a2c3333330a2c3237380a2c3237380a2c3535360a2c3535360a2c353536 *0a2c3535360a2c3535360a2c3535360a2c3535360a2c3535360a2c3535360a2c3535360a2c3333 *330a2c3333330a2c3538340a2c3538340a2c3538340a2c3631310a2c3937350a2c3732320a2c37 *32320a2c3732320a2c3732320a2c3636370a2c3631310a2c3737380a2c3732320a2c3237380a2c *3535360a2c3732320a2c3631310a2c3833330a2c3732320a2c3737380a2c3636370a2c3737380a *2c3732320a2c3636370a2c3631310a2c3732320a2c3636370a2c3934340a2c3636370a2c363637 *0a2c3631310a2c3333330a2c3237380a2c3333330a2c3538340a2c3535360a2c3237380a2c3535 *360a2c3631310a2c3535360a2c3631310a2c3535360a2c3333330a2c3631310a2c3631310a2c32 *37380a2c3237380a2c3535360a2c3237380a2c3838390a2c3631310a2c3631310a2c3631310a2c *3631310a2c3338390a2c3535360a2c3333330a2c3631310a2c3535360a2c3737380a2c3535360a *2c3535360a2c3530300a2c3338390a2c3238300a2c3338390a2c3538340a2c3237380a2c323738 *0a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237 *380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c32 *37380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c *3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a *2c3237380a2c3333330a2c3535360a2c3535360a2c3136370a2c3535360a2c3535360a2c353536 *0a2c3535360a2c3233380a2c3530300a2c3535360a2c3333330a2c3333330a2c3631310a2c3631 *310a2c3237380a2c3535360a2c3535360a2c3535360a2c3237380a2c3237380a2c3535360a2c33 *35300a2c3237380a2c3530300a2c3530300a2c3535360a2c313030300a2c313030300a2c323738 *0a2c3631310a2c3237380a2c3333330a2c3333330a2c3333330a2c3333330a2c3333330a2c3333 *330a2c3333330a2c3333330a2c3237380a2c3333330a2c3333330a2c3237380a2c3333330a2c33 *33330a2c3333330a2c313030300a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a *2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c323738 *0a2c3237380a2c3237380a2c3237380a2c313030300a2c3237380a2c3337300a2c3237380a2c32 *37380a2c3237380a2c3237380a2c3631310a2c3737380a2c313030300a2c3336350a2c3237380a *2c3237380a2c3237380a2c3237380a2c3237380a2c3838390a2c3237380a2c3237380a2c323738 *0a2c3237380a2c3237380a2c3237380a2c3237380a2c3631310a2c3934340a2c3631310a2c3237 *380a2c3237380a2c3237380a2c3237380a2c3235300a2c3333330a2c3430380a2c3530300a2c35 *30300a2c3833330a2c3737380a2c3333330a2c3333330a2c3333330a2c3530300a2c3536340a2c *3235300a2c3333330a2c3235300a2c3237380a2c3530300a2c3530300a2c3530300a2c3530300a *2c3530300a2c3530300a2c3530300a2c3530300a2c3530300a2c3530300a2c3237380a2c323738 *0a2c3536340a2c3536340a2c3536340a2c3434340a2c3932310a2c3732320a2c3636370a2c3636 *370a2c3732320a2c3631310a2c3535360a2c3732320a2c3732320a2c3333330a2c3338390a2c37 *32320a2c3631310a2c3838390a2c3732320a2c3732320a2c3535360a2c3732320a2c3636370a2c *3535360a2c3631310a2c3732320a2c3732320a2c3934340a2c3732320a2c3732320a2c3631310a *2c3333330a2c3237380a2c3333330a2c3436390a2c3530300a2c3333330a2c3434340a2c353030 *0a2c3434340a2c3530300a2c3434340a2c3333330a2c3530300a2c3530300a2c3237380a2c3237 *380a2c3530300a2c3237380a2c3737380a2c3530300a2c3530300a2c3530300a2c3530300a2c33 *33330a2c3338390a2c3237380a2c3530300a2c3530300a2c3732320a2c3530300a2c3530300a2c *3434340a2c3438300a2c3230300a2c3438300a2c3534310a2c3235300a2c3235300a2c3235300a *2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c323530 *0a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235 *300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c32 *35300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c *3333330a2c3530300a2c3530300a2c3136370a2c3530300a2c3530300a2c3530300a2c3530300a *2c3138300a2c3434340a2c3530300a2c3333330a2c3333330a2c3535360a2c3535360a2c323530 *0a2c3530300a2c3530300a2c3530300a2c3235300a2c3235300a2c3435330a2c3335300a2c3333 *330a2c3434340a2c3434340a2c3530300a2c313030300a2c313030300a2c3235300a2c3434340a *2c3235300a2c3333330a2c3333330a2c3333330a2c3333330a2c3333330a2c3333330a2c333333 *0a2c3333330a2c3235300a2c3333330a2c3333330a2c3235300a2c3333330a2c3333330a2c3333 *330a2c313030300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c *3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a *2c3235300a2c3235300a2c3838390a2c3235300a2c3237360a2c3235300a2c3235300a2c323530 *0a2c3235300a2c3631310a2c3732320a2c3838390a2c3331300a2c3235300a2c3235300a2c3235 *300a2c3235300a2c3235300a2c3636370a2c3235300a2c3235300a2c3235300a2c3237380a2c32 *35300a2c3235300a2c3237380a2c3530300a2c3732320a2c3530300a2c3235300a2c3235300a2c *3235300a2c3235300a2c3235300a2c3333330a2c3535350a2c3530300a2c3530300a2c31303030 *0a2c3833330a2c3333330a2c3333330a2c3333330a2c3530300a2c3537300a2c3235300a2c3333 *330a2c3235300a2c3237380a2c3530300a2c3530300a2c3530300a2c3530300a2c3530300a2c35 *30300a2c3530300a2c3530300a2c3530300a2c3530300a2c3333330a2c3333330a2c3537300a2c *3537300a2c3537300a2c3530300a2c3933300a2c3732320a2c3636370a2c3732320a2c3732320a *2c3636370a2c3631310a2c3737380a2c3737380a2c3338390a2c3530300a2c3737380a2c363637 *0a2c3934340a2c3732320a2c3737380a2c3631310a2c3737380a2c3732320a2c3535360a2c3636 *370a2c3732320a2c3732320a2c313030300a2c3732320a2c3732320a2c3636370a2c3333330a2c *3237380a2c3333330a2c3538310a2c3530300a2c3333330a2c3530300a2c3535360a2c3434340a *2c3535360a2c3434340a2c3333330a2c3530300a2c3535360a2c3237380a2c3333330a2c353536 *0a2c3237380a2c3833330a2c3535360a2c3530300a2c3535360a2c3535360a2c3434340a2c3338 *390a2c3333330a2c3535360a2c3530300a2c3732320a2c3530300a2c3530300a2c3434340a2c33 *39340a2c3232300a2c3339340a2c3532300a2c3235300a2c3235300a2c3235300a2c3235300a2c *3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a *2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c323530 *0a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235 *300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3333330a2c35 *30300a2c3530300a2c3136370a2c3530300a2c3530300a2c3530300a2c3530300a2c3237380a2c *3530300a2c3530300a2c3333330a2c3333330a2c3535360a2c3535360a2c3235300a2c3530300a *2c3530300a2c3530300a2c3235300a2c3235300a2c3534300a2c3335300a2c3333330a2c353030 *0a2c3530300a2c3530300a2c313030300a2c313030300a2c3235300a2c3530300a2c3235300a2c *3333330a2c3333330a2c3333330a2c3333330a2c3333330a2c3333330a2c3333330a2c3333330a *2c3235300a2c3333330a2c3333330a2c3235300a2c3333330a2c3333330a2c3333330a2c313030 *300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c32 *35300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c *3235300a2c313030300a2c3235300a2c3330300a2c3235300a2c3235300a2c3235300a2c323530 *0a2c3636370a2c3737380a2c313030300a2c3333300a2c3235300a2c3235300a2c3235300a2c32 *35300a2c3235300a2c3732320a2c3235300a2c3235300a2c3235300a2c3237380a2c3235300a2c *3235300a2c3237380a2c3530300a2c3732320a2c3535360a2c3235300a2c3235300a2c3235300a *2c3235300a2c3235300a2c3333330a2c3432300a2c3530300a2c3530300a2c3833330a2c373738 *0a2c3333330a2c3333330a2c3333330a2c3530300a2c3637350a2c3235300a2c3333330a2c3235 *300a2c3237380a2c3530300a2c3530300a2c3530300a2c3530300a2c3530300a2c3530300a2c35 *30300a2c3530300a2c3530300a2c3530300a2c3333330a2c3333330a2c3637350a2c3637350a2c *3637350a2c3530300a2c3932300a2c3631310a2c3631310a2c3636370a2c3732320a2c3631310a *2c3631310a2c3732320a2c3732320a2c3333330a2c3434340a2c3636370a2c3535360a2c383333 *0a2c3636370a2c3732320a2c3631310a2c3732320a2c3631310a2c3530300a2c3535360a2c3732 *320a2c3631310a2c3833330a2c3631310a2c3535360a2c3535360a2c3338390a2c3237380a2c33 *38390a2c3432320a2c3530300a2c3333330a2c3530300a2c3530300a2c3434340a2c3530300a2c *3434340a2c3237380a2c3530300a2c3530300a2c3237380a2c3237380a2c3434340a2c3237380a *2c3732320a2c3530300a2c3530300a2c3530300a2c3530300a2c3338390a2c3338390a2c323738 *0a2c3530300a2c3434340a2c3636370a2c3434340a2c3434340a2c3338390a2c3430300a2c3237 *350a2c3430300a2c3534310a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c32 *35300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c *3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a *2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c323530 *0a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3338390a2c3530300a2c3530 *300a2c3136370a2c3530300a2c3530300a2c3530300a2c3530300a2c3231340a2c3535360a2c35 *30300a2c3333330a2c3333330a2c3530300a2c3530300a2c3235300a2c3530300a2c3530300a2c *3530300a2c3235300a2c3235300a2c3532330a2c3335300a2c3333330a2c3535360a2c3535360a *2c3530300a2c3838390a2c313030300a2c3235300a2c3530300a2c3235300a2c3333330a2c3333 *330a2c3333330a2c3333330a2c3333330a2c3333330a2c3333330a2c3333330a2c3235300a2c33 *33330a2c3333330a2c3235300a2c3333330a2c3333330a2c3333330a2c3838390a2c3235300a2c *3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a *2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c383839 *0a2c3235300a2c3237360a2c3235300a2c3235300a2c3235300a2c3235300a2c3535360a2c3732 *320a2c3934340a2c3331300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c36 *36370a2c3235300a2c3235300a2c3235300a2c3237380a2c3235300a2c3235300a2c3237380a2c *3530300a2c3636370a2c3530300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a *2c3338390a2c3535350a2c3530300a2c3530300a2c3833330a2c3737380a2c3333330a2c333333 *0a2c3333330a2c3530300a2c3537300a2c3235300a2c3333330a2c3235300a2c3237380a2c3530 *300a2c3530300a2c3530300a2c3530300a2c3530300a2c3530300a2c3530300a2c3530300a2c35 *30300a2c3530300a2c3333330a2c3333330a2c3537300a2c3537300a2c3537300a2c3530300a2c *3833320a2c3636370a2c3636370a2c3636370a2c3732320a2c3636370a2c3636370a2c3732320a *2c3737380a2c3338390a2c3530300a2c3636370a2c3631310a2c3838390a2c3732320a2c373232 *0a2c3631310a2c3732320a2c3636370a2c3535360a2c3631310a2c3732320a2c3636370a2c3838 *390a2c3636370a2c3631310a2c3631310a2c3333330a2c3237380a2c3333330a2c3537300a2c35 *30300a2c3333330a2c3530300a2c3530300a2c3434340a2c3530300a2c3434340a2c3333330a2c *3530300a2c3535360a2c3237380a2c3237380a2c3530300a2c3237380a2c3737380a2c3535360a *2c3530300a2c3530300a2c3530300a2c3338390a2c3338390a2c3237380a2c3535360a2c343434 *0a2c3636370a2c3530300a2c3434340a2c3338390a2c3334380a2c3232300a2c3334380a2c3537 *300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c32 *35300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c *3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a *2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c323530 *0a2c3235300a2c3235300a2c3235300a2c3338390a2c3530300a2c3530300a2c3136370a2c3530 *300a2c3530300a2c3530300a2c3530300a2c3237380a2c3530300a2c3530300a2c3333330a2c33 *33330a2c3535360a2c3535360a2c3235300a2c3530300a2c3530300a2c3530300a2c3235300a2c *3235300a2c3530300a2c3335300a2c3333330a2c3530300a2c3530300a2c3530300a2c31303030 *0a2c313030300a2c3235300a2c3530300a2c3235300a2c3333330a2c3333330a2c3333330a2c33 *33330a2c3333330a2c3333330a2c3333330a2c3333330a2c3235300a2c3333330a2c3333330a2c *3235300a2c3333330a2c3333330a2c3333330a2c313030300a2c3235300a2c3235300a2c323530 *0a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235 *300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3934340a2c3235300a2c32 *36360a2c3235300a2c3235300a2c3235300a2c3235300a2c3631310a2c3732320a2c3934340a2c *3330300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3732320a2c3235300a *2c3235300a2c3235300a2c3237380a2c3235300a2c3235300a2c3237380a2c3530300a2c373232 *0a2c3530300a2c3235300a2c3235300a2c3235300a2c3235300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630 *300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c36 *30300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c *3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a *2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c3630300a2c363030 *0a2c3630300a2c3630300a2c3630300a2c3630300a2c3235300a2c3333330a2c3731330a2c3530 *300a2c3534390a2c3833330a2c3737380a2c3433390a2c3333330a2c3333330a2c3530300a2c35 *34390a2c3235300a2c3534390a2c3235300a2c3237380a2c3530300a2c3530300a2c3530300a2c *3530300a2c3530300a2c3530300a2c3530300a2c3530300a2c3530300a2c3530300a2c3237380a *2c3237380a2c3534390a2c3534390a2c3534390a2c3434340a2c3534390a2c3732320a2c363637 *0a2c3732320a2c3631320a2c3631310a2c3736330a2c3630330a2c3732320a2c3333330a2c3633 *310a2c3732320a2c3638360a2c3838390a2c3732320a2c3732320a2c3736380a2c3734310a2c35 *35360a2c3539320a2c3631310a2c3639300a2c3433390a2c3736380a2c3634350a2c3739350a2c *3631310a2c3333330a2c3836330a2c3333330a2c3635380a2c3530300a2c3530300a2c3633310a *2c3534390a2c3534390a2c3439340a2c3433390a2c3532310a2c3431310a2c3630330a2c333239 *0a2c3630330a2c3534390a2c3534390a2c3537360a2c3532310a2c3534390a2c3534390a2c3532 *310a2c3534390a2c3630330a2c3433390a2c3537360a2c3731330a2c3638360a2c3439330a2c36 *38360a2c3439340a2c3438300a2c3230300a2c3438300a2c3534390a2c3235300a2c3235300a2c *3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a *2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c323530 *0a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235 *300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c3235300a2c37 *35300a2c3632300a2c3234370a2c3534390a2c3136370a2c3731330a2c3530300a2c3735330a2c *3735330a2c3735330a2c3735330a2c313034320a2c3938370a2c3630330a2c3938370a2c363033 *0a2c3430300a2c3534390a2c3431310a2c3534390a2c3534390a2c3731330a2c3439340a2c3436 *300a2c3534390a2c3534390a2c3534390a2c3534390a2c313030300a2c3630330a2c313030300a *2c3635380a2c3832330a2c3638360a2c3739350a2c3938370a2c3736380a2c3736380a2c383233 *0a2c3736380a2c3736380a2c3731330a2c3731330a2c3731330a2c3731330a2c3731330a2c3731 *330a2c3731330a2c3736380a2c3731330a2c3739300a2c3739300a2c3839300a2c3832330a2c35 *34390a2c3235300a2c3731330a2c3630330a2c3630330a2c313034320a2c3938370a2c3630330a *2c3938370a2c3630330a2c3439340a2c3332390a2c3739300a2c3739300a2c3738360a2c373133 *0a2c3338340a2c3338340a2c3338340a2c3338340a2c3338340a2c3338340a2c3439340a2c3439 *340a2c3439340a2c3439340a2c3235300a2c3332390a2c3237340a2c3638360a2c3638360a2c36 *38360a2c3338340a2c3338340a2c3338340a2c3338340a2c3338340a2c3338340a2c3439340a2c *3439340a2c3439340a2c3235300a2c3237380a2c3937340a2c3936310a2c3937340a2c3938300a *2c3731390a2c3738390a2c3739300a2c3739310a2c3639300a2c3936300a2c3933390a2c353439 *0a2c3835350a2c3931310a2c3933330a2c3931310a2c3934350a2c3937340a2c3735350a2c3834 *360a2c3736320a2c3736310a2c3537310a2c3637370a2c3736330a2c3736300a2c3735390a2c37 *35340a2c3439340a2c3535320a2c3533370a2c3537370a2c3639320a2c3738360a2c3738380a2c *3738380a2c3739300a2c3739330a2c3739340a2c3831360a2c3832330a2c3738390a2c3834310a *2c3832330a2c3833330a2c3831360a2c3833310a2c3932330a2c3734340a2c3732330a2c373439 *0a2c3739300a2c3739320a2c3639350a2c3737360a2c3736380a2c3739320a2c3735390a2c3730 *370a2c3730380a2c3638320a2c3730310a2c3832360a2c3831350a2c3738390a2c3738390a2c37 *30370a2c3638370a2c3639360a2c3638390a2c3738360a2c3738370a2c3731330a2c3739310a2c *3738350a2c3739310a2c3837330a2c3736310a2c3736320a2c3736320a2c3735390a2c3735390a *2c3839320a2c3839320a2c3738380a2c3738340a2c3433380a2c3133380a2c3237370a2c343135 *0a2c3339320a2c3339320a2c3636380a2c3636380a2c3237380a2c3339300a2c3339300a2c3331 *370a2c3331370a2c3237360a2c3237360a2c3530390a2c3530390a2c3431300a2c3431300a2c32 *33340a2c3233340a2c3333340a2c3333340a2c3237380a2c3237380a2c3237380a2c3237380a2c *3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a *2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c3237380a2c373332 *0a2c3534340a2c3534340a2c3931300a2c3636370a2c3736300a2c3736300a2c3737360a2c3539 *350a2c3639340a2c3632360a2c3738380a2c3738380a2c3738380a2c3738380a2c3738380a2c37 *38380a2c3738380a2c3738380a2c3738380a2c3738380a2c3738380a2c3738380a2c3738380a2c *3738380a2c3738380a2c3738380a2c3738380a2c3738380a2c3738380a2c3738380a2c3738380a *2c3738380a2c3738380a2c3738380a2c3738380a2c3738380a2c3738380a2c3738380a2c373838 *0a2c3738380a2c3738380a2c3738380a2c3738380a2c3738380a2c3738380a2c3738380a2c3738 *380a2c3738380a2c3738380a2c3738380a2c3839340a2c3833380a2c313031360a2c3435380a2c *3734380a2c3932340a2c3734380a2c3931380a2c3932370a2c3932380a2c3932380a2c3833340a *2c3837330a2c3832380a2c3932340a2c3932340a2c3931370a2c3933300a2c3933310a2c343633 *0a2c3838330a2c3833360a2c3833360a2c3836370a2c3836370a2c3639360a2c3639360a2c3837 *340a2c3237380a2c3837340a2c3736300a2c3934360a2c3737310a2c3836350a2c3737310a2c38 *38380a2c3936370a2c3838380a2c3833310a2c3837330a2c3932370a2c3937300a2c3931380a2c *3237387d3b0a73746174696320636f6e7374206c6f6e6720666d65747269635b5d3d7b0a2d3130 *300a2c35300a2c3731380a2c2d3230370a2c2d3130300a2c35300a2c3731380a2c2d3230370a2c *2d3130300a2c35300a2c3731380a2c2d3230370a2c2d3130300a2c35300a2c3731380a2c2d3230 *370a2c2d3130300a2c35300a2c3638330a2c2d3231370a2c2d3130300a2c35300a2c3638330a2c *2d3231370a2c2d3130300a2c35300a2c3638330a2c2d3231370a2c2d3130300a2c35300a2c3638 *330a2c2d3231370a2c2d3130300a2c35300a2c3632390a2c2d3135370a2c2d3130300a2c35300a *2c3632390a2c2d3135370a2c2d3130300a2c35300a2c3632390a2c2d3135370a2c2d3130300a2c *35300a2c3632390a2c2d3135370a2c2d3130300a2c35300a2c300a2c300a2c2d3130300a2c3530 *0a2c300a2c307d3b0a23656e6469660a addfile ./Graphics/PDF/LowLevel/Kern.hs hunk ./Graphics/PDF/LowLevel/Kern.hs 1 +-- #hide +module Graphics.PDF.LowLevel.Kern(kerns) where + +import qualified Data.Map as M +import Data.Word +kerns :: M.Map (Int,Word8,Word8) Int +kerns = M.fromList [((0,32,84),-50),((0,32,86),-50),((0,32,87),-40),((0,32,89),-90),((0,32,96),-60),((0,32,170),-30),((0,39,32),-70),((0,39,39),-57),((0,39,100),-50),((0,39,114),-50),((0,39,115),-50),((0,44,39),-100),((0,44,186),-100),((0,46,32),-60),((0,46,39),-100),((0,46,186),-100),((0,58,32),-50),((0,59,32),-50),((0,65,67),-30),((0,65,71),-30),((0,65,79),-30),((0,65,81),-30),((0,65,84),-120),((0,65,85),-50),((0,65,86),-70),((0,65,87),-50),((0,65,89),-100),((0,65,117),-30),((0,65,118),-40),((0,65,119),-40),((0,65,121),-40),((0,65,233),-30),((0,66,44),-20),((0,66,46),-20),((0,66,85),-10),((0,67,44),-30),((0,67,46),-30),((0,68,44),-70),((0,68,46),-70),((0,68,65),-40),((0,68,86),-70),((0,68,87),-40),((0,68,89),-90),((0,70,44),-150),((0,70,46),-150),((0,70,65),-80),((0,70,97),-50),((0,70,101),-30),((0,70,111),-30),((0,70,114),-45),((0,70,249),-30),((0,74,44),-30),((0,74,46),-30),((0,74,65),-20),((0,74,97),-20),((0,74,117),-20),((0,75,79),-50),((0,75,101),-40),((0,75,111),-40),((0,75,117),-30),((0,75,121),-50),((0,75,233),-50),((0,75,249),-40),((0,76,39),-160),((0,76,84),-110),((0,76,86),-110),((0,76,87),-70),((0,76,89),-140),((0,76,121),-30),((0,76,186),-140),((0,79,44),-40),((0,79,46),-40),((0,79,65),-20),((0,79,84),-40),((0,79,86),-50),((0,79,87),-30),((0,79,88),-60),((0,79,89),-70),((0,80,44),-180),((0,80,46),-180),((0,80,65),-120),((0,80,97),-40),((0,80,101),-50),((0,80,111),-50),((0,80,249),-50),((0,81,85),-10),((0,82,79),-20),((0,82,84),-30),((0,82,85),-40),((0,82,86),-50),((0,82,87),-30),((0,82,89),-50),((0,82,233),-20),((0,83,44),-20),((0,83,46),-20),((0,84,44),-120),((0,84,45),-140),((0,84,46),-120),((0,84,58),-20),((0,84,59),-20),((0,84,65),-120),((0,84,79),-40),((0,84,97),-120),((0,84,101),-120),((0,84,111),-120),((0,84,114),-120),((0,84,117),-120),((0,84,119),-120),((0,84,121),-120),((0,84,233),-40),((0,84,249),-120),((0,85,44),-40),((0,85,46),-40),((0,85,65),-40),((0,86,44),-125),((0,86,45),-80),((0,86,46),-125),((0,86,58),-40),((0,86,59),-40),((0,86,65),-80),((0,86,71),-40),((0,86,79),-40),((0,86,97),-70),((0,86,101),-80),((0,86,111),-80),((0,86,117),-70),((0,86,233),-40),((0,86,249),-80),((0,87,44),-80),((0,87,45),-40),((0,87,46),-80),((0,87,65),-50),((0,87,79),-20),((0,87,97),-40),((0,87,101),-30),((0,87,111),-30),((0,87,117),-30),((0,87,121),-20),((0,87,233),-20),((0,87,249),-30),((0,89,44),-140),((0,89,45),-140),((0,89,46),-140),((0,89,58),-60),((0,89,59),-60),((0,89,65),-110),((0,89,79),-85),((0,89,97),-140),((0,89,101),-140),((0,89,105),-20),((0,89,111),-140),((0,89,117),-110),((0,89,233),-85),((0,89,249),-140),((0,96,96),-57),((0,97,118),-20),((0,97,119),-20),((0,97,121),-30),((0,98,44),-40),((0,98,46),-40),((0,98,98),-10),((0,98,108),-20),((0,98,117),-20),((0,98,118),-20),((0,98,121),-20),((0,98,248),-20),((0,99,44),-15),((0,99,107),-20),((0,101,44),-15),((0,101,46),-15),((0,101,118),-30),((0,101,119),-20),((0,101,120),-30),((0,101,121),-20),((0,102,39),50),((0,102,44),-30),((0,102,46),-30),((0,102,97),-30),((0,102,101),-30),((0,102,111),-30),((0,102,186),60),((0,102,245),-28),((0,102,249),-30),((0,103,114),-10),((0,104,121),-30),((0,107,101),-20),((0,107,111),-20),((0,107,249),-20),((0,109,117),-10),((0,109,121),-15),((0,110,117),-10),((0,110,118),-20),((0,110,121),-15),((0,111,44),-40),((0,111,46),-40),((0,111,118),-15),((0,111,119),-15),((0,111,120),-30),((0,111,121),-30),((0,112,44),-35),((0,112,46),-35),((0,112,121),-30),((0,114,44),-50),((0,114,46),-50),((0,114,58),30),((0,114,59),30),((0,114,97),-10),((0,114,105),15),((0,114,107),15),((0,114,108),15),((0,114,109),25),((0,114,110),25),((0,114,112),30),((0,114,116),40),((0,114,117),15),((0,114,118),30),((0,114,121),30),((0,114,248),15),((0,115,44),-15),((0,115,46),-15),((0,115,119),-30),((0,118,44),-80),((0,118,46),-80),((0,118,97),-25),((0,118,101),-25),((0,118,111),-25),((0,118,249),-25),((0,119,44),-60),((0,119,46),-60),((0,119,97),-15),((0,119,101),-10),((0,119,111),-10),((0,119,249),-10),((0,120,101),-30),((0,121,44),-100),((0,121,46),-100),((0,121,97),-20),((0,121,101),-20),((0,121,111),-20),((0,121,249),-20),((0,122,101),-15),((0,122,111),-15),((0,122,249),-15),((0,186,32),-40),((0,232,39),-160),((0,232,84),-110),((0,232,86),-110),((0,232,87),-70),((0,232,89),-140),((0,232,121),-30),((0,232,186),-140),((0,233,44),-40),((0,233,46),-40),((0,233,65),-20),((0,233,84),-40),((0,233,86),-50),((0,233,87),-30),((0,233,88),-60),((0,233,89),-70),((0,249,44),-95),((0,249,46),-95),((0,249,97),-55),((0,249,98),-55),((0,249,99),-55),((0,249,100),-55),((0,249,101),-55),((0,249,102),-55),((0,249,103),-55),((0,249,104),-55),((0,249,105),-55),((0,249,106),-55),((0,249,107),-55),((0,249,108),-55),((0,249,109),-55),((0,249,110),-55),((0,249,111),-55),((0,249,112),-55),((0,249,113),-55),((0,249,114),-55),((0,249,115),-55),((0,249,116),-55),((0,249,117),-55),((0,249,118),-70),((0,249,119),-70),((0,249,120),-85),((0,249,121),-70),((0,249,122),-55),((0,249,248),-55),((0,249,249),-55),((1,32,84),-100),((1,32,86),-80),((1,32,87),-80),((1,32,89),-120),((1,32,96),-60),((1,32,170),-80),((1,39,32),-80),((1,39,39),-46),((1,39,100),-80),((1,39,108),-20),((1,39,114),-40),((1,39,115),-60),((1,39,118),-20),((1,39,248),-20),((1,44,32),-40),((1,44,39),-120),((1,44,186),-120),((1,46,32),-40),((1,46,39),-120),((1,46,186),-120),((1,58,32),-40),((1,59,32),-40),((1,65,67),-40),((1,65,71),-50),((1,65,79),-40),((1,65,81),-40),((1,65,84),-90),((1,65,85),-50),((1,65,86),-80),((1,65,87),-60),((1,65,89),-110),((1,65,117),-30),((1,65,118),-40),((1,65,119),-30),((1,65,121),-30),((1,65,233),-40),((1,66,65),-30),((1,66,85),-10),((1,68,44),-30),((1,68,46),-30),((1,68,65),-40),((1,68,86),-40),((1,68,87),-40),((1,68,89),-70),((1,70,44),-100),((1,70,46),-100),((1,70,65),-80),((1,70,97),-20),((1,74,44),-20),((1,74,46),-20),((1,74,65),-20),((1,74,117),-20),((1,75,79),-30),((1,75,101),-15),((1,75,111),-35),((1,75,117),-30),((1,75,121),-40),((1,75,233),-30),((1,75,249),-35),((1,76,39),-140),((1,76,84),-90),((1,76,86),-110),((1,76,87),-80),((1,76,89),-120),((1,76,121),-30),((1,76,186),-140),((1,79,44),-40),((1,79,46),-40),((1,79,65),-50),((1,79,84),-40),((1,79,86),-50),((1,79,87),-50),((1,79,88),-50),((1,79,89),-70),((1,80,44),-120),((1,80,46),-120),((1,80,65),-100),((1,80,97),-30),((1,80,101),-30),((1,80,111),-40),((1,80,249),-40),((1,81,44),20),((1,81,46),20),((1,81,85),-10),((1,82,79),-20),((1,82,84),-20),((1,82,85),-20),((1,82,86),-50),((1,82,87),-40),((1,82,89),-50),((1,82,233),-20),((1,84,44),-80),((1,84,45),-120),((1,84,46),-80),((1,84,58),-40),((1,84,59),-40),((1,84,65),-90),((1,84,79),-40),((1,84,97),-80),((1,84,101),-60),((1,84,111),-80),((1,84,114),-80),((1,84,117),-90),((1,84,119),-60),((1,84,121),-60),((1,84,233),-40),((1,84,249),-80),((1,85,44),-30),((1,85,46),-30),((1,85,65),-50),((1,86,44),-120),((1,86,45),-80),((1,86,46),-120),((1,86,58),-40),((1,86,59),-40),((1,86,65),-80),((1,86,71),-50),((1,86,79),-50),((1,86,97),-60),((1,86,101),-50),((1,86,111),-90),((1,86,117),-60),((1,86,233),-50),((1,86,249),-90),((1,87,44),-80),((1,87,45),-40),((1,87,46),-80),((1,87,58),-10),((1,87,59),-10),((1,87,65),-60),((1,87,79),-20),((1,87,97),-40),((1,87,101),-35),((1,87,111),-60),((1,87,117),-45),((1,87,121),-20),((1,87,233),-20),((1,87,249),-60),((1,89,44),-100),((1,89,46),-100),((1,89,58),-50),((1,89,59),-50),((1,89,65),-110),((1,89,79),-70),((1,89,97),-90),((1,89,101),-80),((1,89,111),-100),((1,89,117),-100),((1,89,233),-70),((1,89,249),-100),((1,96,96),-46),((1,97,103),-10),((1,97,118),-15),((1,97,119),-15),((1,97,121),-20),((1,98,108),-10),((1,98,117),-20),((1,98,118),-20),((1,98,121),-20),((1,98,248),-10),((1,99,104),-10),((1,99,107),-20),((1,99,108),-20),((1,99,121),-10),((1,99,248),-20),((1,100,100),-10),((1,100,118),-15),((1,100,119),-15),((1,100,121),-15),((1,101,44),10),((1,101,46),20),((1,101,118),-15),((1,101,119),-15),((1,101,120),-15),((1,101,121),-15),((1,102,39),30),((1,102,44),-10),((1,102,46),-10),((1,102,101),-10),((1,102,111),-20),((1,102,186),30),((1,102,249),-20),((1,103,101),10),((1,103,103),-10),((1,104,121),-20),((1,107,111),-15),((1,107,249),-15),((1,108,119),-15),((1,108,121),-15),((1,109,117),-20),((1,109,121),-30),((1,110,117),-10),((1,110,118),-40),((1,110,121),-20),((1,111,118),-20),((1,111,119),-15),((1,111,120),-30),((1,111,121),-20),((1,112,121),-15),((1,114,44),-60),((1,114,45),-20),((1,114,46),-60),((1,114,99),-20),((1,114,100),-20),((1,114,103),-15),((1,114,111),-20),((1,114,113),-20),((1,114,115),-15),((1,114,116),20),((1,114,118),10),((1,114,121),10),((1,114,249),-20),((1,115,119),-15),((1,118,44),-80),((1,118,46),-80),((1,118,97),-20),((1,118,111),-30),((1,118,249),-30),((1,119,44),-40),((1,119,46),-40),((1,119,111),-20),((1,119,249),-20),((1,120,101),-10),((1,121,44),-80),((1,121,46),-80),((1,121,97),-30),((1,121,101),-10),((1,121,111),-25),((1,121,249),-25),((1,122,101),10),((1,186,32),-80),((1,232,39),-140),((1,232,84),-90),((1,232,86),-110),((1,232,87),-80),((1,232,89),-120),((1,232,121),-30),((1,232,186),-140),((1,233,44),-40),((1,233,46),-40),((1,233,65),-50),((1,233,84),-40),((1,233,86),-50),((1,233,87),-50),((1,233,88),-50),((1,233,89),-70),((1,248,119),-15),((1,248,121),-15),((1,249,118),-20),((1,249,119),-15),((1,249,120),-30),((1,249,121),-20),((2,32,84),-50),((2,32,86),-50),((2,32,87),-40),((2,32,89),-90),((2,32,96),-60),((2,32,170),-30),((2,39,32),-70),((2,39,39),-57),((2,39,100),-50),((2,39,114),-50),((2,39,115),-50),((2,44,39),-100),((2,44,186),-100),((2,46,32),-60),((2,46,39),-100),((2,46,186),-100),((2,58,32),-50),((2,59,32),-50),((2,65,67),-30),((2,65,71),-30),((2,65,79),-30),((2,65,81),-30),((2,65,84),-120),((2,65,85),-50),((2,65,86),-70),((2,65,87),-50),((2,65,89),-100),((2,65,117),-30),((2,65,118),-40),((2,65,119),-40),((2,65,121),-40),((2,65,233),-30),((2,66,44),-20),((2,66,46),-20),((2,66,85),-10),((2,67,44),-30),((2,67,46),-30),((2,68,44),-70),((2,68,46),-70),((2,68,65),-40),((2,68,86),-70),((2,68,87),-40),((2,68,89),-90),((2,70,44),-150),((2,70,46),-150),((2,70,65),-80),((2,70,97),-50),((2,70,101),-30),((2,70,111),-30),((2,70,114),-45),((2,70,249),-30),((2,74,44),-30),((2,74,46),-30),((2,74,65),-20),((2,74,97),-20),((2,74,117),-20),((2,75,79),-50),((2,75,101),-40),((2,75,111),-40),((2,75,117),-30),((2,75,121),-50),((2,75,233),-50),((2,75,249),-40),((2,76,39),-160),((2,76,84),-110),((2,76,86),-110),((2,76,87),-70),((2,76,89),-140),((2,76,121),-30),((2,76,186),-140),((2,79,44),-40),((2,79,46),-40),((2,79,65),-20),((2,79,84),-40),((2,79,86),-50),((2,79,87),-30),((2,79,88),-60),((2,79,89),-70),((2,80,44),-180),((2,80,46),-180),((2,80,65),-120),((2,80,97),-40),((2,80,101),-50),((2,80,111),-50),((2,80,249),-50),((2,81,85),-10),((2,82,79),-20),((2,82,84),-30),((2,82,85),-40),((2,82,86),-50),((2,82,87),-30),((2,82,89),-50),((2,82,233),-20),((2,83,44),-20),((2,83,46),-20),((2,84,44),-120),((2,84,45),-140),((2,84,46),-120),((2,84,58),-20),((2,84,59),-20),((2,84,65),-120),((2,84,79),-40),((2,84,97),-120),((2,84,101),-120),((2,84,111),-120),((2,84,114),-120),((2,84,117),-120),((2,84,119),-120),((2,84,121),-120),((2,84,233),-40),((2,84,249),-120),((2,85,44),-40),((2,85,46),-40),((2,85,65),-40),((2,86,44),-125),((2,86,45),-80),((2,86,46),-125),((2,86,58),-40),((2,86,59),-40),((2,86,65),-80),((2,86,71),-40),((2,86,79),-40),((2,86,97),-70),((2,86,101),-80),((2,86,111),-80),((2,86,117),-70),((2,86,233),-40),((2,86,249),-80),((2,87,44),-80),((2,87,45),-40),((2,87,46),-80),((2,87,65),-50),((2,87,79),-20),((2,87,97),-40),((2,87,101),-30),((2,87,111),-30),((2,87,117),-30),((2,87,121),-20),((2,87,233),-20),((2,87,249),-30),((2,89,44),-140),((2,89,45),-140),((2,89,46),-140),((2,89,58),-60),((2,89,59),-60),((2,89,65),-110),((2,89,79),-85),((2,89,97),-140),((2,89,101),-140),((2,89,105),-20),((2,89,111),-140),((2,89,117),-110),((2,89,233),-85),((2,89,249),-140),((2,96,96),-57),((2,97,118),-20),((2,97,119),-20),((2,97,121),-30),((2,98,44),-40),((2,98,46),-40),((2,98,98),-10),((2,98,108),-20),((2,98,117),-20),((2,98,118),-20),((2,98,121),-20),((2,98,248),-20),((2,99,44),-15),((2,99,107),-20),((2,101,44),-15),((2,101,46),-15),((2,101,118),-30),((2,101,119),-20),((2,101,120),-30),((2,101,121),-20),((2,102,39),50),((2,102,44),-30),((2,102,46),-30),((2,102,97),-30),((2,102,101),-30),((2,102,111),-30),((2,102,186),60),((2,102,245),-28),((2,102,249),-30),((2,103,114),-10),((2,104,121),-30),((2,107,101),-20),((2,107,111),-20),((2,107,249),-20),((2,109,117),-10),((2,109,121),-15),((2,110,117),-10),((2,110,118),-20),((2,110,121),-15),((2,111,44),-40),((2,111,46),-40),((2,111,118),-15),((2,111,119),-15),((2,111,120),-30),((2,111,121),-30),((2,112,44),-35),((2,112,46),-35),((2,112,121),-30),((2,114,44),-50),((2,114,46),-50),((2,114,58),30),((2,114,59),30),((2,114,97),-10),((2,114,105),15),((2,114,107),15),((2,114,108),15),((2,114,109),25),((2,114,110),25),((2,114,112),30),((2,114,116),40),((2,114,117),15),((2,114,118),30),((2,114,121),30),((2,114,248),15),((2,115,44),-15),((2,115,46),-15),((2,115,119),-30),((2,118,44),-80),((2,118,46),-80),((2,118,97),-25),((2,118,101),-25),((2,118,111),-25),((2,118,249),-25),((2,119,44),-60),((2,119,46),-60),((2,119,97),-15),((2,119,101),-10),((2,119,111),-10),((2,119,249),-10),((2,120,101),-30),((2,121,44),-100),((2,121,46),-100),((2,121,97),-20),((2,121,101),-20),((2,121,111),-20),((2,121,249),-20),((2,122,101),-15),((2,122,111),-15),((2,122,249),-15),((2,186,32),-40),((2,232,39),-160),((2,232,84),-110),((2,232,86),-110),((2,232,87),-70),((2,232,89),-140),((2,232,121),-30),((2,232,186),-140),((2,233,44),-40),((2,233,46),-40),((2,233,65),-20),((2,233,84),-40),((2,233,86),-50),((2,233,87),-30),((2,233,88),-60),((2,233,89),-70),((2,249,44),-95),((2,249,46),-95),((2,249,97),-55),((2,249,98),-55),((2,249,99),-55),((2,249,100),-55),((2,249,101),-55),((2,249,102),-55),((2,249,103),-55),((2,249,104),-55),((2,249,105),-55),((2,249,106),-55),((2,249,107),-55),((2,249,108),-55),((2,249,109),-55),((2,249,110),-55),((2,249,111),-55),((2,249,112),-55),((2,249,113),-55),((2,249,114),-55),((2,249,115),-55),((2,249,116),-55),((2,249,117),-55),((2,249,118),-70),((2,249,119),-70),((2,249,120),-85),((2,249,121),-70),((2,249,122),-55),((2,249,248),-55),((2,249,249),-55),((3,32,84),-100),((3,32,86),-80),((3,32,87),-80),((3,32,89),-120),((3,32,96),-60),((3,32,170),-80),((3,39,32),-80),((3,39,39),-46),((3,39,100),-80),((3,39,108),-20),((3,39,114),-40),((3,39,115),-60),((3,39,118),-20),((3,39,248),-20),((3,44,32),-40),((3,44,39),-120),((3,44,186),-120),((3,46,32),-40),((3,46,39),-120),((3,46,186),-120),((3,58,32),-40),((3,59,32),-40),((3,65,67),-40),((3,65,71),-50),((3,65,79),-40),((3,65,81),-40),((3,65,84),-90),((3,65,85),-50),((3,65,86),-80),((3,65,87),-60),((3,65,89),-110),((3,65,117),-30),((3,65,118),-40),((3,65,119),-30),((3,65,121),-30),((3,65,233),-40),((3,66,65),-30),((3,66,85),-10),((3,68,44),-30),((3,68,46),-30),((3,68,65),-40),((3,68,86),-40),((3,68,87),-40),((3,68,89),-70),((3,70,44),-100),((3,70,46),-100),((3,70,65),-80),((3,70,97),-20),((3,74,44),-20),((3,74,46),-20),((3,74,65),-20),((3,74,117),-20),((3,75,79),-30),((3,75,101),-15),((3,75,111),-35),((3,75,117),-30),((3,75,121),-40),((3,75,233),-30),((3,75,249),-35),((3,76,39),-140),((3,76,84),-90),((3,76,86),-110),((3,76,87),-80),((3,76,89),-120),((3,76,121),-30),((3,76,186),-140),((3,79,44),-40),((3,79,46),-40),((3,79,65),-50),((3,79,84),-40),((3,79,86),-50),((3,79,87),-50),((3,79,88),-50),((3,79,89),-70),((3,80,44),-120),((3,80,46),-120),((3,80,65),-100),((3,80,97),-30),((3,80,101),-30),((3,80,111),-40),((3,80,249),-40),((3,81,44),20),((3,81,46),20),((3,81,85),-10),((3,82,79),-20),((3,82,84),-20),((3,82,85),-20),((3,82,86),-50),((3,82,87),-40),((3,82,89),-50),((3,82,233),-20),((3,84,44),-80),((3,84,45),-120),((3,84,46),-80),((3,84,58),-40),((3,84,59),-40),((3,84,65),-90),((3,84,79),-40),((3,84,97),-80),((3,84,101),-60),((3,84,111),-80),((3,84,114),-80),((3,84,117),-90),((3,84,119),-60),((3,84,121),-60),((3,84,233),-40),((3,84,249),-80),((3,85,44),-30),((3,85,46),-30),((3,85,65),-50),((3,86,44),-120),((3,86,45),-80),((3,86,46),-120),((3,86,58),-40),((3,86,59),-40),((3,86,65),-80),((3,86,71),-50),((3,86,79),-50),((3,86,97),-60),((3,86,101),-50),((3,86,111),-90),((3,86,117),-60),((3,86,233),-50),((3,86,249),-90),((3,87,44),-80),((3,87,45),-40),((3,87,46),-80),((3,87,58),-10),((3,87,59),-10),((3,87,65),-60),((3,87,79),-20),((3,87,97),-40),((3,87,101),-35),((3,87,111),-60),((3,87,117),-45),((3,87,121),-20),((3,87,233),-20),((3,87,249),-60),((3,89,44),-100),((3,89,46),-100),((3,89,58),-50),((3,89,59),-50),((3,89,65),-110),((3,89,79),-70),((3,89,97),-90),((3,89,101),-80),((3,89,111),-100),((3,89,117),-100),((3,89,233),-70),((3,89,249),-100),((3,96,96),-46),((3,97,103),-10),((3,97,118),-15),((3,97,119),-15),((3,97,121),-20),((3,98,108),-10),((3,98,117),-20),((3,98,118),-20),((3,98,121),-20),((3,98,248),-10),((3,99,104),-10),((3,99,107),-20),((3,99,108),-20),((3,99,121),-10),((3,99,248),-20),((3,100,100),-10),((3,100,118),-15),((3,100,119),-15),((3,100,121),-15),((3,101,44),10),((3,101,46),20),((3,101,118),-15),((3,101,119),-15),((3,101,120),-15),((3,101,121),-15),((3,102,39),30),((3,102,44),-10),((3,102,46),-10),((3,102,101),-10),((3,102,111),-20),((3,102,186),30),((3,102,249),-20),((3,103,101),10),((3,103,103),-10),((3,104,121),-20),((3,107,111),-15),((3,107,249),-15),((3,108,119),-15),((3,108,121),-15),((3,109,117),-20),((3,109,121),-30),((3,110,117),-10),((3,110,118),-40),((3,110,121),-20),((3,111,118),-20),((3,111,119),-15),((3,111,120),-30),((3,111,121),-20),((3,112,121),-15),((3,114,44),-60),((3,114,45),-20),((3,114,46),-60),((3,114,99),-20),((3,114,100),-20),((3,114,103),-15),((3,114,111),-20),((3,114,113),-20),((3,114,115),-15),((3,114,116),20),((3,114,118),10),((3,114,121),10),((3,114,249),-20),((3,115,119),-15),((3,118,44),-80),((3,118,46),-80),((3,118,97),-20),((3,118,111),-30),((3,118,249),-30),((3,119,44),-40),((3,119,46),-40),((3,119,111),-20),((3,119,249),-20),((3,120,101),-10),((3,121,44),-80),((3,121,46),-80),((3,121,97),-30),((3,121,101),-10),((3,121,111),-25),((3,121,249),-25),((3,122,101),10),((3,186,32),-80),((3,232,39),-140),((3,232,84),-90),((3,232,86),-110),((3,232,87),-80),((3,232,89),-120),((3,232,121),-30),((3,232,186),-140),((3,233,44),-40),((3,233,46),-40),((3,233,65),-50),((3,233,84),-40),((3,233,86),-50),((3,233,87),-50),((3,233,88),-50),((3,233,89),-70),((3,248,119),-15),((3,248,121),-15),((3,249,118),-20),((3,249,119),-15),((3,249,120),-30),((3,249,121),-20),((4,32,65),-55),((4,32,84),-18),((4,32,86),-50),((4,32,87),-30),((4,32,89),-90),((4,39,32),-74),((4,39,39),-74),((4,39,100),-50),((4,39,108),-10),((4,39,114),-50),((4,39,115),-55),((4,39,116),-18),((4,39,118),-50),((4,39,248),-10),((4,44,39),-70),((4,44,186),-70),((4,46,39),-70),((4,46,186),-70),((4,65,39),-111),((4,65,67),-40),((4,65,71),-40),((4,65,79),-55),((4,65,81),-55),((4,65,84),-111),((4,65,85),-55),((4,65,86),-135),((4,65,87),-90),((4,65,89),-105),((4,65,118),-74),((4,65,119),-92),((4,65,121),-92),((4,65,233),-55),((4,66,65),-35),((4,66,85),-10),((4,68,65),-40),((4,68,86),-40),((4,68,87),-30),((4,68,89),-55),((4,70,44),-80),((4,70,46),-80),((4,70,65),-74),((4,70,97),-15),((4,70,111),-15),((4,70,249),-15),((4,74,65),-60),((4,75,79),-30),((4,75,101),-25),((4,75,111),-35),((4,75,117),-15),((4,75,121),-25),((4,75,233),-30),((4,75,249),-35),((4,76,39),-92),((4,76,84),-92),((4,76,86),-100),((4,76,87),-74),((4,76,89),-100),((4,76,121),-55),((4,78,65),-35),((4,79,65),-35),((4,79,84),-40),((4,79,86),-50),((4,79,87),-35),((4,79,88),-40),((4,79,89),-50),((4,80,44),-111),((4,80,46),-111),((4,80,65),-92),((4,80,97),-15),((4,81,85),-10),((4,82,79),-40),((4,82,84),-60),((4,82,85),-40),((4,82,86),-80),((4,82,87),-55),((4,82,89),-65),((4,82,233),-40),((4,84,44),-74),((4,84,45),-92),((4,84,46),-74),((4,84,58),-50),((4,84,59),-55),((4,84,65),-93),((4,84,79),-18),((4,84,97),-80),((4,84,101),-70),((4,84,105),-35),((4,84,111),-80),((4,84,114),-35),((4,84,117),-45),((4,84,119),-80),((4,84,121),-80),((4,84,233),-18),((4,84,249),-80),((4,85,65),-40),((4,86,44),-129),((4,86,45),-100),((4,86,46),-129),((4,86,58),-74),((4,86,59),-74),((4,86,65),-135),((4,86,71),-15),((4,86,79),-40),((4,86,97),-111),((4,86,101),-111),((4,86,105),-60),((4,86,111),-129),((4,86,117),-75),((4,86,233),-40),((4,86,249),-129),((4,87,44),-92),((4,87,45),-65),((4,87,46),-92),((4,87,58),-37),((4,87,59),-37),((4,87,65),-120),((4,87,79),-10),((4,87,97),-80),((4,87,101),-80),((4,87,105),-40),((4,87,111),-80),((4,87,117),-50),((4,87,121),-73),((4,87,233),-10),((4,87,249),-80),((4,89,44),-129),((4,89,45),-111),((4,89,46),-129),((4,89,58),-92),((4,89,59),-92),((4,89,65),-120),((4,89,79),-30),((4,89,97),-100),((4,89,101),-100),((4,89,105),-55),((4,89,111),-110),((4,89,117),-111),((4,89,233),-30),((4,89,249),-110),((4,96,65),-80),((4,96,96),-74),((4,97,118),-20),((4,97,119),-15),((4,98,46),-40),((4,98,117),-20),((4,98,118),-15),((4,99,121),-15),((4,101,103),-15),((4,101,118),-25),((4,101,119),-25),((4,101,120),-15),((4,101,121),-15),((4,102,39),55),((4,102,97),-10),((4,102,102),-25),((4,102,105),-20),((4,102,245),-50),((4,103,97),-5),((4,104,121),-5),((4,105,118),-25),((4,107,101),-10),((4,107,111),-10),((4,107,121),-15),((4,107,249),-10),((4,108,119),-10),((4,110,118),-40),((4,110,121),-15),((4,111,118),-15),((4,111,119),-25),((4,111,121),-10),((4,112,121),-10),((4,114,44),-40),((4,114,45),-20),((4,114,46),-55),((4,114,103),-18),((4,118,44),-65),((4,118,46),-65),((4,118,97),-25),((4,118,101),-15),((4,118,111),-20),((4,118,249),-20),((4,119,44),-65),((4,119,46),-65),((4,119,97),-10),((4,119,111),-10),((4,119,249),-10),((4,120,101),-15),((4,121,44),-65),((4,121,46),-65),((4,170,65),-80),((4,232,39),-92),((4,232,84),-92),((4,232,86),-100),((4,232,87),-74),((4,232,89),-100),((4,232,121),-55),((4,233,65),-35),((4,233,84),-40),((4,233,86),-50),((4,233,87),-35),((4,233,88),-40),((4,233,89),-50),((4,248,119),-10),((4,249,118),-15),((4,249,119),-25),((4,249,121),-10),((5,32,65),-55),((5,32,84),-30),((5,32,86),-45),((5,32,87),-30),((5,32,89),-55),((5,39,32),-74),((5,39,39),-63),((5,39,100),-20),((5,39,114),-20),((5,39,115),-37),((5,39,118),-20),((5,44,39),-55),((5,44,186),-45),((5,46,39),-55),((5,46,186),-55),((5,65,39),-74),((5,65,67),-55),((5,65,71),-55),((5,65,79),-45),((5,65,81),-45),((5,65,84),-95),((5,65,85),-50),((5,65,86),-145),((5,65,87),-130),((5,65,89),-100),((5,65,112),-25),((5,65,117),-50),((5,65,118),-100),((5,65,119),-90),((5,65,121),-74),((5,65,233),-45),((5,66,65),-30),((5,66,85),-10),((5,68,46),-20),((5,68,65),-35),((5,68,86),-40),((5,68,87),-40),((5,68,89),-40),((5,70,44),-92),((5,70,46),-110),((5,70,65),-90),((5,70,97),-25),((5,70,101),-25),((5,70,111),-25),((5,70,249),-25),((5,74,46),-20),((5,74,65),-30),((5,74,97),-15),((5,74,101),-15),((5,74,111),-15),((5,74,117),-15),((5,74,249),-15),((5,75,79),-30),((5,75,101),-25),((5,75,111),-25),((5,75,117),-15),((5,75,121),-45),((5,75,233),-30),((5,75,249),-25),((5,76,39),-110),((5,76,84),-92),((5,76,86),-92),((5,76,87),-92),((5,76,89),-92),((5,76,121),-55),((5,76,186),-20),((5,78,65),-20),((5,79,65),-40),((5,79,84),-40),((5,79,86),-50),((5,79,87),-50),((5,79,88),-40),((5,79,89),-50),((5,80,44),-92),((5,80,46),-110),((5,80,65),-74),((5,80,97),-10),((5,80,101),-20),((5,80,111),-20),((5,80,249),-20),((5,81,46),-20),((5,81,85),-10),((5,82,79),-30),((5,82,84),-40),((5,82,85),-30),((5,82,86),-55),((5,82,87),-35),((5,82,89),-35),((5,82,233),-30),((5,84,44),-74),((5,84,45),-92),((5,84,46),-90),((5,84,58),-74),((5,84,59),-74),((5,84,65),-90),((5,84,79),-18),((5,84,97),-92),((5,84,101),-92),((5,84,105),-18),((5,84,111),-92),((5,84,114),-74),((5,84,117),-92),((5,84,119),-74),((5,84,121),-34),((5,84,233),-18),((5,84,249),-92),((5,85,44),-50),((5,85,46),-50),((5,85,65),-60),((5,86,44),-129),((5,86,45),-74),((5,86,46),-145),((5,86,58),-92),((5,86,59),-92),((5,86,65),-135),((5,86,71),-30),((5,86,79),-45),((5,86,97),-92),((5,86,101),-100),((5,86,105),-37),((5,86,111),-100),((5,86,117),-92),((5,86,233),-45),((5,86,249),-100),((5,87,44),-92),((5,87,45),-37),((5,87,46),-92),((5,87,58),-55),((5,87,59),-55),((5,87,65),-120),((5,87,79),-10),((5,87,97),-65),((5,87,101),-65),((5,87,105),-18),((5,87,111),-75),((5,87,117),-50),((5,87,121),-60),((5,87,233),-10),((5,87,249),-75),((5,89,44),-92),((5,89,45),-92),((5,89,46),-92),((5,89,58),-92),((5,89,59),-92),((5,89,65),-110),((5,89,79),-35),((5,89,97),-85),((5,89,101),-111),((5,89,105),-37),((5,89,111),-111),((5,89,117),-92),((5,89,233),-35),((5,89,249),-111),((5,96,65),-10),((5,96,96),-63),((5,97,118),-25),((5,98,46),-40),((5,98,98),-10),((5,98,117),-20),((5,98,118),-15),((5,100,119),-15),((5,101,118),-15),((5,102,39),55),((5,102,44),-15),((5,102,46),-15),((5,102,105),-25),((5,102,111),-25),((5,102,186),50),((5,102,245),-35),((5,102,249),-25),((5,103,46),-15),((5,104,121),-15),((5,105,118),-10),((5,107,101),-10),((5,107,111),-15),((5,107,121),-15),((5,107,249),-15),((5,110,118),-40),((5,111,118),-10),((5,111,119),-10),((5,114,44),-92),((5,114,45),-37),((5,114,46),-100),((5,114,99),-18),((5,114,101),-18),((5,114,103),-10),((5,114,110),-15),((5,114,111),-18),((5,114,112),-10),((5,114,113),-18),((5,114,118),-10),((5,114,249),-18),((5,118,44),-55),((5,118,46),-70),((5,118,97),-10),((5,118,101),-10),((5,118,111),-10),((5,118,249),-10),((5,119,44),-55),((5,119,46),-70),((5,119,111),-10),((5,119,249),-10),((5,121,44),-55),((5,121,46),-70),((5,121,101),-10),((5,121,111),-25),((5,121,249),-25),((5,170,65),-10),((5,232,39),-110),((5,232,84),-92),((5,232,86),-92),((5,232,87),-92),((5,232,89),-92),((5,232,121),-55),((5,232,186),-20),((5,233,65),-40),((5,233,84),-40),((5,233,86),-50),((5,233,87),-50),((5,233,88),-40),((5,233,89),-50),((5,249,118),-10),((5,249,119),-10),((6,32,65),-18),((6,32,84),-18),((6,32,86),-35),((6,32,87),-40),((6,32,89),-75),((6,39,32),-111),((6,39,39),-111),((6,39,100),-25),((6,39,114),-25),((6,39,115),-40),((6,39,116),-30),((6,39,118),-10),((6,44,39),-140),((6,44,186),-140),((6,46,39),-140),((6,46,186),-140),((6,65,39),-37),((6,65,67),-30),((6,65,71),-35),((6,65,79),-40),((6,65,81),-40),((6,65,84),-37),((6,65,85),-50),((6,65,86),-105),((6,65,87),-95),((6,65,89),-55),((6,65,117),-20),((6,65,118),-55),((6,65,119),-55),((6,65,121),-55),((6,65,233),-40),((6,66,65),-25),((6,66,85),-10),((6,68,65),-35),((6,68,86),-40),((6,68,87),-40),((6,68,89),-40),((6,70,44),-135),((6,70,46),-135),((6,70,65),-115),((6,70,97),-75),((6,70,101),-75),((6,70,105),-45),((6,70,111),-105),((6,70,114),-55),((6,70,249),-105),((6,74,44),-25),((6,74,46),-25),((6,74,65),-40),((6,74,97),-35),((6,74,101),-25),((6,74,111),-25),((6,74,117),-35),((6,74,249),-25),((6,75,79),-50),((6,75,101),-35),((6,75,111),-40),((6,75,117),-40),((6,75,121),-40),((6,75,233),-50),((6,75,249),-40),((6,76,39),-37),((6,76,84),-20),((6,76,86),-55),((6,76,87),-55),((6,76,89),-20),((6,76,121),-30),((6,78,65),-27),((6,79,65),-55),((6,79,84),-40),((6,79,86),-50),((6,79,87),-50),((6,79,88),-40),((6,79,89),-50),((6,80,44),-135),((6,80,46),-135),((6,80,65),-90),((6,80,97),-80),((6,80,101),-80),((6,80,111),-80),((6,80,249),-80),((6,81,85),-10),((6,82,79),-40),((6,82,85),-40),((6,82,86),-18),((6,82,87),-18),((6,82,89),-18),((6,82,233),-40),((6,84,44),-74),((6,84,45),-74),((6,84,46),-74),((6,84,58),-55),((6,84,59),-65),((6,84,65),-50),((6,84,79),-18),((6,84,97),-92),((6,84,101),-92),((6,84,105),-55),((6,84,111),-92),((6,84,114),-55),((6,84,117),-55),((6,84,119),-74),((6,84,121),-74),((6,84,233),-18),((6,84,249),-92),((6,85,44),-25),((6,85,46),-25),((6,85,65),-40),((6,86,44),-129),((6,86,45),-55),((6,86,46),-129),((6,86,58),-65),((6,86,59),-74),((6,86,65),-60),((6,86,79),-30),((6,86,97),-111),((6,86,101),-111),((6,86,105),-74),((6,86,111),-111),((6,86,117),-74),((6,86,233),-30),((6,86,249),-111),((6,87,44),-92),((6,87,45),-37),((6,87,46),-92),((6,87,58),-65),((6,87,59),-65),((6,87,65),-60),((6,87,79),-25),((6,87,97),-92),((6,87,101),-92),((6,87,105),-55),((6,87,111),-92),((6,87,117),-55),((6,87,121),-70),((6,87,233),-25),((6,87,249),-92),((6,89,44),-92),((6,89,45),-74),((6,89,46),-92),((6,89,58),-65),((6,89,59),-65),((6,89,65),-50),((6,89,79),-15),((6,89,97),-92),((6,89,101),-92),((6,89,105),-74),((6,89,111),-92),((6,89,117),-92),((6,89,233),-15),((6,89,249),-92),((6,96,96),-111),((6,97,103),-10),((6,98,46),-40),((6,98,117),-20),((6,99,104),-15),((6,99,107),-20),((6,101,44),-10),((6,101,46),-15),((6,101,103),-40),((6,101,118),-15),((6,101,119),-15),((6,101,120),-20),((6,101,121),-30),((6,102,39),92),((6,102,44),-10),((6,102,46),-15),((6,102,102),-18),((6,102,105),-20),((6,102,245),-60),((6,103,44),-10),((6,103,46),-15),((6,103,101),-10),((6,103,103),-10),((6,107,101),-10),((6,107,111),-10),((6,107,121),-10),((6,107,249),-10),((6,110,118),-40),((6,111,103),-10),((6,111,118),-10),((6,114,44),-111),((6,114,45),-20),((6,114,46),-111),((6,114,97),-15),((6,114,99),-37),((6,114,100),-37),((6,114,101),-37),((6,114,103),-37),((6,114,111),-45),((6,114,113),-37),((6,114,115),-10),((6,114,249),-45),((6,118,44),-74),((6,118,46),-74),((6,119,44),-74),((6,119,46),-74),((6,121,44),-55),((6,121,46),-55),((6,232,39),-37),((6,232,84),-20),((6,232,86),-55),((6,232,87),-55),((6,232,89),-20),((6,232,121),-30),((6,233,65),-55),((6,233,84),-40),((6,233,86),-50),((6,233,87),-50),((6,233,88),-40),((6,233,89),-50),((6,249,103),-10),((6,249,118),-10),((7,32,65),-37),((7,32,86),-70),((7,32,87),-70),((7,32,89),-70),((7,39,32),-74),((7,39,39),-74),((7,39,100),-15),((7,39,114),-15),((7,39,115),-74),((7,39,116),-37),((7,39,118),-15),((7,44,39),-95),((7,44,186),-95),((7,46,39),-95),((7,46,186),-95),((7,65,39),-74),((7,65,67),-65),((7,65,71),-60),((7,65,79),-50),((7,65,81),-55),((7,65,84),-55),((7,65,85),-50),((7,65,86),-95),((7,65,87),-100),((7,65,89),-70),((7,65,117),-30),((7,65,118),-74),((7,65,119),-74),((7,65,121),-74),((7,65,233),-50),((7,66,65),-25),((7,66,85),-10),((7,68,65),-25),((7,68,86),-50),((7,68,87),-40),((7,68,89),-50),((7,70,44),-129),((7,70,46),-129),((7,70,65),-100),((7,70,97),-95),((7,70,101),-100),((7,70,105),-40),((7,70,111),-70),((7,70,114),-50),((7,70,249),-70),((7,74,44),-10),((7,74,46),-10),((7,74,65),-25),((7,74,97),-40),((7,74,101),-40),((7,74,111),-40),((7,74,117),-40),((7,74,249),-40),((7,75,79),-30),((7,75,101),-25),((7,75,111),-25),((7,75,117),-20),((7,75,121),-20),((7,75,233),-30),((7,75,249),-25),((7,76,39),-55),((7,76,84),-18),((7,76,86),-37),((7,76,87),-37),((7,76,89),-37),((7,76,121),-37),((7,78,65),-30),((7,79,65),-40),((7,79,84),-40),((7,79,86),-50),((7,79,87),-50),((7,79,88),-40),((7,79,89),-50),((7,80,44),-129),((7,80,46),-129),((7,80,65),-85),((7,80,97),-40),((7,80,101),-50),((7,80,111),-55),((7,80,249),-55),((7,81,85),-10),((7,82,79),-40),((7,82,84),-30),((7,82,85),-40),((7,82,86),-18),((7,82,87),-18),((7,82,89),-18),((7,82,233),-40),((7,84,44),-92),((7,84,45),-92),((7,84,46),-92),((7,84,58),-74),((7,84,59),-74),((7,84,65),-55),((7,84,79),-18),((7,84,97),-92),((7,84,101),-92),((7,84,105),-37),((7,84,111),-95),((7,84,114),-37),((7,84,117),-37),((7,84,119),-37),((7,84,121),-37),((7,84,233),-18),((7,84,249),-95),((7,85,65),-45),((7,86,44),-129),((7,86,45),-70),((7,86,46),-129),((7,86,58),-74),((7,86,59),-74),((7,86,65),-85),((7,86,71),-10),((7,86,79),-30),((7,86,97),-111),((7,86,101),-111),((7,86,105),-55),((7,86,111),-111),((7,86,117),-55),((7,86,233),-30),((7,86,249),-111),((7,87,44),-74),((7,87,45),-50),((7,87,46),-74),((7,87,58),-55),((7,87,59),-55),((7,87,65),-74),((7,87,79),-15),((7,87,97),-85),((7,87,101),-90),((7,87,105),-37),((7,87,111),-80),((7,87,117),-55),((7,87,121),-55),((7,87,233),-15),((7,87,249),-80),((7,89,44),-92),((7,89,45),-92),((7,89,46),-74),((7,89,58),-92),((7,89,59),-92),((7,89,65),-74),((7,89,79),-25),((7,89,97),-92),((7,89,101),-111),((7,89,105),-55),((7,89,111),-111),((7,89,117),-92),((7,89,233),-25),((7,89,249),-111),((7,96,96),-74),((7,98,46),-40),((7,98,98),-10),((7,98,117),-20),((7,99,104),-10),((7,99,107),-10),((7,101,98),-10),((7,102,39),55),((7,102,44),-10),((7,102,46),-10),((7,102,101),-10),((7,102,102),-18),((7,102,111),-10),((7,102,245),-30),((7,102,249),-10),((7,107,101),-30),((7,107,111),-10),((7,107,249),-10),((7,110,118),-40),((7,111,118),-15),((7,111,119),-25),((7,111,120),-10),((7,111,121),-10),((7,114,44),-65),((7,114,46),-65),((7,118,44),-37),((7,118,46),-37),((7,118,101),-15),((7,118,111),-15),((7,118,249),-15),((7,119,44),-37),((7,119,46),-37),((7,119,97),-10),((7,119,101),-10),((7,119,111),-15),((7,119,249),-15),((7,120,101),-10),((7,121,44),-37),((7,121,46),-37),((7,232,39),-55),((7,232,84),-18),((7,232,86),-37),((7,232,87),-37),((7,232,89),-37),((7,232,121),-37),((7,233,65),-40),((7,233,84),-40),((7,233,86),-50),((7,233,87),-50),((7,233,88),-40),((7,233,89),-50),((7,249,118),-15),((7,249,119),-25),((7,249,120),-10),((7,249,121),-10)] hunk ./Graphics/PDF/Text.hs 51 +import Graphics.PDF.LowLevel.Kern(kerns) +import qualified Data.Map as M(findWithDefault) hunk ./Graphics/PDF/Text.hs 57 +foreign import ccall "ctext.h c_hasKern" hasKern :: Int -> Bool hunk ./Graphics/PDF/Text.hs 71 +-- | Get the kern value for a given font and pair of charcode +getKern :: (Int,Word8,Word8) -> Int +getKern k = M.findWithDefault 0 k kerns + hunk ./Graphics/PDF/Text.hs 76 -textWidth (PDFFont n s) (PDFString t) = trueSize s (sum . map (cgetAdvance (fromEnum n)) . B.unpack $ t) +textWidth (PDFFont n s) (PDFString t) = let w = sum . map (cgetAdvance (fromEnum n)) . B.unpack $ t in + if hasKern (fromEnum n) + then + trueSize s (w + (sum . map getKern $ [(fromEnum n,ca,cb) | (ca,cb) <- B.zip t (B.tail t)])) + else + trueSize s w hunk ./HPDF.cabal 37 + Graphics.PDF.LowLevel.Kern hunk ./Test/AFMParser.hs 8 -import Data.Maybe(isJust,fromJust) +import Data.Maybe(isJust,fromJust,mapMaybe) hunk ./Test/AFMParser.hs 11 +import qualified Data.Map as M hunk ./Test/AFMParser.hs 22 -toEndOfLine = do many1 (noneOf "\r\n") +toEndOfLine = do many (noneOf "\r\n") hunk ./Test/AFMParser.hs 152 + , kernData :: Maybe [KX] hunk ./Test/AFMParser.hs 173 - + +data KX = KX String String Int + deriving(Eq,Ord,Show) + +kernPair :: Parser KX +kernPair = do string "KPX" + spaces + namea <- many1 letter + spaces + nameb <- many1 letter + spaces + nb <- many1 (oneOf "-+0123456789") + line + return $ KX namea nameb (read nb) + +getKernData :: Parser (Maybe [KX]) +getKernData = do + { comment "StartKernData" + ; nbKerns <- getInt "StartKernPairs" + ; k <- many1 kernPair + ; comment "EndKernPairs" + ; comment "EndKernData" + ; return $ Just k + } + hunk ./Test/AFMParser.hs 222 - ; getString "EndCharMetrics" - ; return $ Font (filter isEncoded charMetrics) underlinePosition underlineThickness ascender descender + ; comment "EndCharMetrics" + ; kerns <- option Nothing getKernData + ; comment "EndFontMetrics" + ; return $ Font (filter isEncoded charMetrics) underlinePosition underlineThickness ascender descender kerns hunk ./Test/AFMParser.hs 246 -createFontList (Font m up ut asc desc) = zip codes (map getWidth [32..255]) +createFontList (Font m up ut asc desc k) = zip codes (map getWidth [32..255]) hunk ./Test/AFMParser.hs 258 - Left _ -> return $ Nothing + Left e -> error (show e) hunk ./Test/AFMParser.hs 262 -fontData (Font _ up ut asc desc) = [show up,show ut,show asc,show desc] +fontData (Font _ up ut asc desc k) = [show up,show ut,show asc,show desc,maybe "0" (const "1") k] + +kernForFont :: (Int,Font) -> M.Map (Int,Int,Int) Int +kernForFont (i,(Font m _ _ _ _ Nothing)) = M.empty +kernForFont (i,(Font m _ _ _ _ (Just k))) = do + let names = M.fromList . map (\x -> (name x, charCode x)) $ m + k' = mapMaybe kernToList k + kernToList (KX na nb v) = + let ca = M.lookup na names + cb = M.lookup nb names in + case (ca,cb) of + (Just a,Just b) -> Just $ ((i,a,b),v) + (_,_) -> Nothing + M.fromList k' + + + +createKern :: [Font] -> IO () +createKern f = do + let allmaps = map kernForFont $ (zip [0..] f) + endkern = M.fromList $ [((i,j,0),0) | i <- [0..13],j <- [32..255]] + result = M.unions $ allmaps + putStrLn $ "-- #hide" + putStrLn $ "module Graphics.PDF.LowLevel.Kern(kerns) where" + putStrLn "" + putStrLn $ "import qualified Data.Map as M" + putStrLn $ "import Data.Word" + putStrLn $ "kerns :: M.Map (Int,Word8,Word8) Int" + putStrLn $ "kerns = M." ++ (show result) hunk ./Test/AFMParser.hs 294 + r <- getArgs hunk ./Test/AFMParser.hs 297 - let carray = map createFontList fonts - putStrLn "#ifndef _METRICS_H_" - putStrLn "#define _METRICS_H_" - putStrLn "static const unsigned long gmetric[]={" - mapM_ putStr . intersperse "\n," . map (\(c,w) -> show w) . concat $ carray - putStrLn "};" - putStrLn "static const long fmetric[]={" - mapM_ putStr . intersperse "\n," . concatMap fontData $ fonts - putStrLn "};" - putStrLn "#endif" + if null r + then do + let carray = map createFontList fonts + putStrLn "#ifndef _METRICS_H_" + putStrLn "#define _METRICS_H_" + putStrLn "static const unsigned long gmetric[]={" + mapM_ putStr . intersperse "\n," . map (\(c,w) -> show w) . concat $ carray + putStrLn "};" + putStrLn "static const long fmetric[]={" + mapM_ putStr . intersperse "\n," . concatMap fontData $ fonts + putStrLn "};" + putStrLn "#endif" + else do + createKern fonts hunk ./Test/Makefile 16 - @./afm Courier.afm - @./afm Helvetica-Oblique.afm - @./afm Symbol.afm - @./afm Times-Italic.afm - @./afm Courier-BoldOblique.afm - @./afm Helvetica-Bold.afm - @./afm Helvetica.afm - @./afm Times-Bold.afm - @./afm Times-Roman.afm - @./afm Courier-Oblique.afm - @./afm Helvetica-BoldOblique.afm - @./afm Times-BoldItalic.afm - @./afm ZapfDingbats.afm hunk ./Test/test.hs 101 - -f = PDFFont Times_Roman 48 -t = toPDFString "This is a test éèçàù" - + hunk ./Test/test.hs 129 - fontDebug (PDFFont Helvetica 48) ( "AbAVAVcéèHjpA¡ Test!") + fontDebug (PDFFont Helvetica 48) ( "AAAVAA") hunk ./Test/test.hs 131 + fontDebug (PDFFont Courier 48) ( "AbAVAVcéèHjpA¡ Test!") hunk ./c/ctext.h 6 +extern int c_hasKern(unsigned short); hunk ./c/metrics.c 6 -#define FFONTSIZE (4) +#define FFONTSIZE (5) hunk ./c/metrics.c 24 + +int c_hasKern(unsigned short font) +{ + return(fmetric[font*FFONTSIZE+4]); +} hunk ./c/metrics.h 3145 +,1 hunk ./c/metrics.h 3150 +,1 hunk ./c/metrics.h 3155 +,1 hunk ./c/metrics.h 3160 +,1 hunk ./c/metrics.h 3165 +,1 hunk ./c/metrics.h 3170 +,1 hunk ./c/metrics.h 3175 +,1 hunk ./c/metrics.h 3180 +,1 hunk ./c/metrics.h 3185 +,0 hunk ./c/metrics.h 3190 +,0 hunk ./c/metrics.h 3195 +,0 hunk ./c/metrics.h 3200 +,0 hunk ./c/metrics.h 3205 +,0 hunk ./c/metrics.h 3209 +,0 hunk ./Graphics/PDF/Text.hs 39 + , textBox hunk ./Graphics/PDF/Text.hs 54 +import Graphics.PDF.Shapes +import qualified Data.ByteString.Lazy.Char8 as B(words,unwords) hunk ./Graphics/PDF/Text.hs 98 + +-- | Tolerance value when text is too long. We accept to overflow a little +tolerance :: PDFFloat +tolerance = 0.2 + +-- | Format a text string inside a rectangle +textBox :: PDFFont -- ^ Font to use + -> PDFString -- ^ Text to draw + -> Rectangle -- ^ Where to draw + -> Draw () +textBox f@(PDFFont _ size) (PDFString s) (Rectangle xa ya xb yb) = do + let width = xb -xa + ws = textWidth f (toPDFString " ") + getLines c l [] = [B.unwords . reverse $ l] + getLines c l (h:t) = let c' = c + ws + textWidth f (PDFString h) in + if c' > width + tolerance * (fromIntegral size) + then + (B.unwords . reverse $ l):getLines 0 [] (h:t) + else + getLines c' (h:l) t + drawText $ do + setFont f + leading $ getHeight f + textStart xa (yb + getDescent f) + startNewLine + mapM_ (\x -> displayText x >> startNewLine) (map PDFString . getLines 0 [] $ (B.words s)) + + hunk ./Test/test.hs 132 - + page <- addPage Nothing + newSibling (toPDFString "TextBox") Nothing Nothing + drawWithPage page $ do + let rect = Rectangle 10 10 400 400 + stroke $ rect + textBox (PDFFont Times_Roman 48) (toPDFString "This is a long text to test the justification algorithm for the simplified text box") + rect hunk ./Graphics/PDF/Action.hs 16 - Action(..) + Action hunk ./Graphics/PDF/Action.hs 26 -data MediaAction = Play - | Stop - | Pause - | Resume - deriving(Enum) +--data MediaAction = Play +-- | Stop +-- | Pause +-- | Resume +-- deriving(Enum) hunk ./Graphics/PDF/Action.hs 37 -data Rendition = Rendition -instance PdfObject Rendition where - toPDF a = toPDF . PDFDictionary . M.fromList $ - [ (PDFName "Type",AnyPdfObject . PDFName $ "Rendition") - , (PDFName "S",AnyPdfObject . PDFName $ "MR") - , (PDFName "C",AnyPdfObject movie) - ] - where - movie = PDFDictionary . M.fromList $ - [ (PDFName "Type",AnyPdfObject . PDFName $ "MediaClip") - , (PDFName "S",AnyPdfObject . PDFName $ "MCD") - , (PDFName "CT",AnyPdfObject . toPDFString $ "video/3gpp") - , (PDFName "D",AnyPdfObject (toPDFString "17.3gp")) - ] +--data Rendition = Rendition +--instance PdfObject Rendition where +-- toPDF a = toPDF . PDFDictionary . M.fromList $ +-- [ (PDFName "Type",AnyPdfObject . PDFName $ "Rendition") +-- , (PDFName "S",AnyPdfObject . PDFName $ "MR") +-- , (PDFName "C",AnyPdfObject movie) +-- ] +-- where +-- movie = PDFDictionary . M.fromList $ +-- [ (PDFName "Type",AnyPdfObject . PDFName $ "MediaClip") +-- , (PDFName "S",AnyPdfObject . PDFName $ "MCD") +-- , (PDFName "CT",AnyPdfObject . toPDFString $ "video/3gpp") +-- , (PDFName "D",AnyPdfObject (toPDFString "17.3gp")) +-- ] hunk ./Graphics/PDF/Action.hs 53 -data ControlMedia = ControlMedia MediaAction Int (PDFReference Rendition) +--data ControlMedia = ControlMedia MediaAction Int (PDFReference Rendition) hunk ./Graphics/PDF/Action.hs 64 -instance PdfObject ControlMedia where - toPDF (ControlMedia operation relatedScreenAnnotation rendition) = toPDF . PDFDictionary . M.fromList $ - [ (PDFName "Type",AnyPdfObject . PDFName $ "Action") - , (PDFName "S",AnyPdfObject (PDFName "Rendition")) - , (PDFName "R",AnyPdfObject rendition) - , (PDFName "OP",AnyPdfObject . PDFInteger $ (fromEnum operation)) - , (PDFName "AN",AnyPdfObject $ (PDFReference relatedScreenAnnotation :: PDFReference AnyPdfObject)) - ] - -instance Action ControlMedia +--instance PdfObject ControlMedia where +-- toPDF (ControlMedia operation relatedScreenAnnotation rendition) = toPDF . PDFDictionary . M.fromList $ +-- [ (PDFName "Type",AnyPdfObject . PDFName $ "Action") +-- , (PDFName "S",AnyPdfObject (PDFName "Rendition")) +-- , (PDFName "R",AnyPdfObject rendition) +-- , (PDFName "OP",AnyPdfObject . PDFInteger $ (fromEnum operation)) +-- , (PDFName "AN",AnyPdfObject $ (PDFReference relatedScreenAnnotation :: PDFReference AnyPdfObject)) +-- ] +-- +--instance Action ControlMedia hunk ./Graphics/PDF/Annotation.hs 25 -import Graphics.PDF.Resources hunk ./Graphics/PDF/Annotation.hs 28 -import Graphics.PDF.Colors hunk ./Graphics/PDF/Annotation.hs 45 -getRgbTriple :: Color -> [Double] -getRgbTriple (Rgb r g b) = [r,g,b] -getRgbTriple (Hsv h s v) = let (r,g,b) = hsvToRgb (h,s,v) in [r,g,b] - hunk ./Graphics/PDF/Document.hs 32 - , drawXObject hunk ./Graphics/PDF/Document.hs 46 -import Graphics.PDF.Resources hunk ./Graphics/PDF/Draw.hs 76 -import Graphics.PDF.Data.PDFTree(PDFTree,Key) +import Graphics.PDF.Data.PDFTree(PDFTree) hunk ./Graphics/PDF/Draw.hs 96 + annotationType (AnyAnnotation a) = annotationType a + annotationContent (AnyAnnotation a) = annotationContent a + annotationRect (AnyAnnotation a) = annotationRect a + hunk ./Graphics/PDF/Draw.hs 253 - bounds <- asks xobjectb - return $ IM.findWithDefault (0.0,0.0) ref bounds + theBounds <- asks xobjectb + return $ IM.findWithDefault (0.0,0.0) ref theBounds hunk ./Graphics/PDF/Draw.hs 402 - toPDF (PDFOutline first last) = toPDF $ PDFDictionary. M.fromList $ [ + toPDF (PDFOutline first lasto) = toPDF $ PDFDictionary. M.fromList $ [ hunk ./Graphics/PDF/Draw.hs 405 - , (PDFName "Last",AnyPdfObject last) + , (PDFName "Last",AnyPdfObject lasto) hunk ./Graphics/PDF/Draw.hs 486 - toPDF (PDFPages c (Just parent) l) = toPDF $ PDFDictionary. M.fromList $ + toPDF (PDFPages c (Just theParent) l) = toPDF $ PDFDictionary. M.fromList $ hunk ./Graphics/PDF/Draw.hs 488 - , (PDFName "Parent",AnyPdfObject parent) + , (PDFName "Parent",AnyPdfObject theParent) hunk ./Graphics/PDF/Draw.hs 495 - toPDF (PDFPage (Just parent) box content rsrc d t annots) = toPDF $ PDFDictionary. M.fromList $ + toPDF (PDFPage (Just theParent) box content theRsrc d t theAnnots) = toPDF $ PDFDictionary. M.fromList $ hunk ./Graphics/PDF/Draw.hs 497 - , (PDFName "Parent",AnyPdfObject parent) + , (PDFName "Parent",AnyPdfObject theParent) hunk ./Graphics/PDF/Draw.hs 500 - , if isJust rsrc + , if isJust theRsrc hunk ./Graphics/PDF/Draw.hs 502 - (PDFName "Resources",AnyPdfObject . fromJust $ rsrc) + (PDFName "Resources",AnyPdfObject . fromJust $ theRsrc) hunk ./Graphics/PDF/Draw.hs 507 - ++ ((\x -> if null x then [] else [(PDFName "Annots",AnyPdfObject x)]) annots) + ++ ((\x -> if null x then [] else [(PDFName "Annots",AnyPdfObject x)]) theAnnots) hunk ./Graphics/PDF/Draw.hs 529 - toPDF (PDFOutlineEntry title parent prev next first last count dest color style) = + toPDF (PDFOutlineEntry title theParent prev next first theLast count dest color style) = hunk ./Graphics/PDF/Draw.hs 532 - , (PDFName "Parent",AnyPdfObject parent) + , (PDFName "Parent",AnyPdfObject theParent) hunk ./Graphics/PDF/Draw.hs 541 - maybe [] (\x -> [(PDFName "Last",AnyPdfObject x)]) last + maybe [] (\x -> [(PDFName "Last",AnyPdfObject x)]) theLast hunk ./Graphics/PDF/Image.hs 32 -import Text.Printf hunk ./Graphics/PDF/Image.hs 35 -m_sof0 = 0xc0 -m_sof1 = 0xc1 -m_sof2 = 0xc2 +m_sof0 :: Int +m_sof0 = 0xc0 +m_sof1 :: Int +m_sof1 = 0xc1 +--m_sof2 :: Int +--m_sof2 = 0xc2 +m_sof3 :: Int hunk ./Graphics/PDF/Image.hs 43 - -m_sof5 = 0xc5 -m_sof6 = 0xc6 +m_sof5 :: Int +m_sof5 = 0xc5 +m_sof6 :: Int +m_sof6 = 0xc6 +m_sof7 :: Int hunk ./Graphics/PDF/Image.hs 49 - -m_jpg = 0xc8 +--m_jpg :: Int +--m_jpg = 0xc8 +m_sof9 :: Int hunk ./Graphics/PDF/Image.hs 53 +m_sof10 :: Int hunk ./Graphics/PDF/Image.hs 55 +m_sof11 :: Int hunk ./Graphics/PDF/Image.hs 57 - +m_sof13 :: Int hunk ./Graphics/PDF/Image.hs 59 +m_sof14 :: Int hunk ./Graphics/PDF/Image.hs 61 +m_sof15 :: Int hunk ./Graphics/PDF/Image.hs 63 - -m_dht = 0xc4 - -m_dac = 0xcc - +--m_dht :: Int +--m_dht = 0xc4 +--m_dac :: Int +--m_dac = 0xcc +m_rst0 :: Int hunk ./Graphics/PDF/Image.hs 69 -m_rst1 = 0xd1 +m_rst1 :: Int +m_rst1 = 0xd1 +m_rst2 :: Int hunk ./Graphics/PDF/Image.hs 73 -m_rst3 = 0xd3 -m_rst4 = 0xd4 -m_rst5 = 0xd5 -m_rst6 = 0xd6 +m_rst3 :: Int +m_rst3 = 0xd3 +m_rst4 :: Int +m_rst4 = 0xd4 +m_rst5 :: Int +m_rst5 = 0xd5 +m_rst6 :: Int +m_rst6 = 0xd6 +m_rst7 :: Int hunk ./Graphics/PDF/Image.hs 83 - -m_soi = 0xd8 -m_eoi = 0xd9 -m_sos = 0xda -m_dqt = 0xdb -m_dnl = 0xdc -m_dri = 0xdd -m_dhp = 0xde -m_exp = 0xdf - -m_app0 = 0xe0 -m_app1 = 0xe1 -m_app2 = 0xe2 -m_app3 = 0xe3 -m_app4 = 0xe4 -m_app5 = 0xe5 -m_app6 = 0xe6 -m_app7 = 0xe7 -m_app8 = 0xe8 -m_app9 = 0xe9 -m_app10 = 0xea -m_app11 = 0xeb -m_app12 = 0xec -m_app13 = 0xed -m_app14 = 0xee -m_app15 = 0xef - -m_jpg0 = 0xf0 -m_jpg13 = 0xfd -m_com = 0xfe - +m_soi :: Int +m_soi = 0xd8 +m_eoi :: Int +m_eoi = 0xd9 +--m_sos :: Int +--m_sos = 0xda +--m_dqt :: Int +--m_dqt = 0xdb +--m_dnl :: Int +--m_dnl = 0xdc +--m_dri :: Int +--m_dri = 0xdd +--m_dhp :: Int +--m_dhp = 0xde +--m_exp :: Int +--m_exp = 0xdf +--m_app0 :: Int +--m_app0 = 0xe0 +--m_app1 :: Int +--m_app1 = 0xe1 +--m_app2 :: Int +--m_app2 = 0xe2 +--m_app3 :: Int +--m_app3 = 0xe3 +--m_app4 :: Int +--m_app4 = 0xe4 +--m_app5 :: Int +--m_app5 = 0xe5 +--m_app6 :: Int +--m_app6 = 0xe6 +--m_app7 :: Int +--m_app7 = 0xe7 +--m_app8 :: Int +--m_app8 = 0xe8 +--m_app9 :: Int +--m_app9 = 0xe9 +--m_app10 :: Int +--m_app10 = 0xea +--m_app11 :: Int +--m_app11 = 0xeb +--m_app12 :: Int +--m_app12 = 0xec +--m_app13 :: Int +--m_app13 = 0xed +--m_app14 :: Int +--m_app14 = 0xee +--m_app15 :: Int +--m_app15 = 0xef +--m_jpg0 :: Int +--m_jpg0 = 0xf0 +--m_jpg13 :: Int +--m_jpg13 = 0xfd +--m_com :: Int +--m_com = 0xfe +m_tem :: Int hunk ./Graphics/PDF/Image.hs 139 - -m_error = 0x100 +--m_error :: Int +--m_error = 0x100 hunk ./Graphics/PDF/Image.hs 143 -io = liftIO +io = FA . liftIO hunk ./Graphics/PDF/Image.hs 148 - deriving(Monad,MonadError String,MonadIO,Functor) + deriving(Monad,MonadError String,Functor) hunk ./Graphics/PDF/Image.hs 170 -optional :: FA (Maybe a) -> FA (Maybe a) -optional a = a --`catchError` (\e -> return Nothing) +--optional :: FA (Maybe a) -> FA (Maybe a) +--optional a = a --`catchError` (\e -> return Nothing) hunk ./Graphics/PDF/Image.hs 173 -jfif :: Handle -> FA (Maybe (Double,Double)) -jfif h = do - header <- readWord16 h - when (header /= 0x0FFE0) $ throwError (strMsg "No JFIF magic number") - readWord16 h - mapM_ check "JFIF" - readWord16 h - unit <- readWord8 h - width <- fromIntegral `fmap` readWord16 h - height <- fromIntegral `fmap` readWord16 h - case unit of - 1 -> return $ Just (width,height) - 2 -> return $ Just (width*2.54,height*2.54) - _ -> return $ Just (0,0) - where - check c' = do - c <- io $ hGetChar h - when (c /= c') $ throwError (strMsg "No JFIF header") +--jfif :: Handle -> FA (Maybe (Double,Double)) +--jfif h = do +-- header <- readWord16 h +-- when (header /= 0x0FFE0) $ throwError (strMsg "No JFIF magic number") +-- readWord16 h +-- mapM_ check "JFIF" +-- readWord16 h +-- unit <- readWord8 h +-- width <- fromIntegral `fmap` readWord16 h +-- height <- fromIntegral `fmap` readWord16 h +-- case unit of +-- 1 -> return $ Just (width,height) +-- 2 -> return $ Just (width*2.54,height*2.54) +-- _ -> return $ Just (0,0) +-- where +-- check c' = do +-- c <- io $ hGetChar h +-- when (c /= c') $ throwError (strMsg "No JFIF header") hunk ./Graphics/PDF/Image.hs 216 - fileLength <- io $ hTell h + --fileLength <- io $ hTell h hunk ./Graphics/PDF/Image.hs 262 + _ -> error "Jpeg color space not supported" hunk ./Graphics/PDF/LowLevel/Types.hs 27 -import Data.Bits hunk ./Graphics/PDF/LowLevel/Types.hs 125 - where - toHexa = B.concatMap hexaDigit - hexaDigit d = let hi = (d `shiftR` 4) .&. 0x0F - lo = d .&. 0x0F - chr n = if n >=0 && n <=9 then n + c2w '0' else (n-10) + c2w 'A' - in - B.pack [chr hi,chr lo] hunk ./Graphics/PDF/Navigation.hs 27 -import qualified Data.Map as M hunk ./Graphics/PDF/Navigation.hs 33 -newSibling s col style = do +newSibling myS col style = do hunk ./Graphics/PDF/Navigation.hs 39 - let value = (s,col,style,Destination aPage) + let myValue = (myS,col,style,Destination aPage) hunk ./Graphics/PDF/Navigation.hs 41 - Nothing -> modifyStrict $ \s -> s {outline = Just $ insertDown value (OutlineLoc (Node value []) Top)} - Just r -> modifyStrict $ \s -> s {outline = Just $ insertRight value r} + Nothing -> modifyStrict $ \s -> s {outline = Just $ insertDown myValue (OutlineLoc (Node myValue []) Top)} + Just r -> modifyStrict $ \s -> s {outline = Just $ insertRight myValue r} hunk ./Graphics/PDF/Navigation.hs 48 -newChild s col style = do +newChild myS col style = do hunk ./Graphics/PDF/Navigation.hs 54 - let value = (s,col,style,Destination aPage) + let myValue = (myS,col,style,Destination aPage) hunk ./Graphics/PDF/Navigation.hs 56 - Nothing -> modifyStrict $ \s -> s {outline = Just $ insertDown value (OutlineLoc (Node value []) Top)} - Just r -> modifyStrict $ \s -> s {outline = Just $ insertDown value r} + Nothing -> modifyStrict $ \s -> s {outline = Just $ insertDown myValue (OutlineLoc (Node myValue []) Top)} + Just r -> modifyStrict $ \s -> s {outline = Just $ insertDown myValue r} hunk ./Graphics/PDF/Pages.hs 41 -import qualified Data.Map as M hunk ./Graphics/PDF/Pages.hs 183 -insertRight t' (OutlineLoc _ Top) = error "Cannot insert right of the top node" +insertRight _ (OutlineLoc _ Top) = error "Cannot insert right of the top node" hunk ./Graphics/PDF/Pages.hs 189 - -insertLeft :: a -> OutlineLoc a -> OutlineLoc a -insertLeft t' (OutlineLoc _ Top) = error "Cannot insert left of the top node" -insertLeft t' (OutlineLoc t c ) = let c' = Child { value = value c - , parent = parent c - , rights = t : (rights c) - , lefts = lefts c } - in OutlineLoc (Node t' []) c' hunk ./Graphics/PDF/Pages.hs 208 - let (Node root l) = toTree r + let (Node _ l) = toTree r hunk ./Graphics/PDF/Pages.hs 231 - addEntry first end (prev,Just current,Node (title,col,style,dest) c,next) = do + addEntry _ _ (_,Nothing,_,_) = error "This pattern match in addEntry should never occur !" + addEntry _ _ (prev,Just current,Node (title,col,style,dest) c,next) = do hunk ./Graphics/PDF/Pattern.hs 122 - (newColorName,newColorMap) <- setResource "ColorSpace" PatternRGB colorMap + (newColorName,_) <- setResource "ColorSpace" PatternRGB colorMap hunk ./Graphics/PDF/Pattern.hs 134 - (newColorName,newColorMap) <- setResource "ColorSpace" PatternRGB colorMap + (newColorName,_) <- setResource "ColorSpace" PatternRGB colorMap hunk ./Graphics/PDF/Resources.hs 14 - PDFResource + PDFResource(..) hunk ./Graphics/PDF/Resources.hs 26 - , AnyPdfPattern(..) + , AnyPdfPattern hunk ./Graphics/PDF/Shading.hs 22 -import Graphics.PDF.Resources hunk ./Graphics/PDF/Text.hs 92 - , tf :: !PDFFloat hunk ./Graphics/PDF/Text.hs 96 -defaultParameters = TextParameter 0 0 100 0 0 0 (Set.empty) +defaultParameters = TextParameter 0 0 100 0 0 (Set.empty) hunk ./Graphics/PDF/Text.hs 107 -textBox f@(PDFFont _ size) (PDFString s) (Rectangle xa ya xb yb) = do +textBox f@(PDFFont _ size) (PDFString s) (Rectangle xa _ xb yb) = do hunk ./Graphics/PDF/Text.hs 110 - getLines c l [] = [B.unwords . reverse $ l] + getLines _ l [] = [B.unwords . reverse $ l] hunk ./Graphics/PDF/Text.hs 154 -setFont (PDFFont n s) = PDFText $ do +setFont (PDFFont n size) = PDFText $ do hunk ./Graphics/PDF/Text.hs 156 - writeCmd $ "\n/" ++ (show n) ++ " " ++ (show s) ++ " Tf" + writeCmd $ "\n/" ++ (show n) ++ " " ++ (show size) ++ " Tf" hunk ./Graphics/PDF.hs 95 - bounds <- gets xobjectBound + myBounds <- gets xobjectBound hunk ./Graphics/PDF.hs 97 - let (value,state',w') = runDrawing d (emptyEnvironment {streamId = r, xobjectb = bounds, currentp = maybe Nothing (\(PDFReference x) -> Just x) cp }) + let (_,state',w') = runDrawing d (emptyEnvironment {streamId = r, xobjectb = myBounds, currentp = maybe Nothing (\(PDFReference x) -> Just x) cp }) hunk ./Graphics/PDF.hs 140 - s <- gets streams - createStreams . IM.toList $ s + ls <- gets streams + createStreams . IM.toList $ ls hunk ./Test/Penrose.hs 15 +myBlue :: Color hunk ./Test/Penrose.hs 17 + +myGreen :: Color hunk ./Test/test.hs 143 - --simple - --testPenrose + simple + testPenrose hunk ./Graphics/PDF.hs 222 + , firstOutline = [True] hunk ./Graphics/PDF/Action.hs 25 --- | Media action +-- Media action hunk ./Graphics/PDF/Action.hs 34 --- | Action to go to an URL +-- | Action of going to an URL hunk ./Graphics/PDF/Action.hs 52 --- | Action to control a media +-- Action to control a media hunk ./Graphics/PDF/Annotation.hs 118 --- | Set alpha value for transparency +-- | Create a new annotation object hunk ./Graphics/PDF/Colors.hs 70 --- | Init the PDF color space to RGB. Required before being able to use the color functions. +-- | Init the PDF color space to RGB. hunk ./Graphics/PDF/Document.hs 20 - , findPage hunk ./Graphics/PDF/Draw.hs 130 --- | PDF Stream content ---data Draw a = Draw !B.ByteString !a +-- | The drawing monad hunk ./Graphics/PDF/Draw.hs 280 + , firstOutline :: [Bool] -- ^ Used to improve the outline API hunk ./Graphics/PDF/Image.hs 270 + , (PDFName "Interpolate", AnyPdfObject True) hunk ./Graphics/PDF/LowLevel/Types.hs 222 --- | A monad where path can be created +-- | A monad where paths can be created hunk ./Graphics/PDF/Navigation.hs 18 - , newSibling - , newChild - , moveToParent + , newSection + , newSectionWithPage hunk ./Graphics/PDF/Navigation.hs 27 +import Control.Monad(when) +import Data.Maybe(isNothing) hunk ./Graphics/PDF/Navigation.hs 30 +-- | True if we are adding the first outline to this level +isFirst :: [Bool] -> Bool +isFirst r = head r + +-- | Start a new outline level +startNew :: PDF () +startNew = modifyStrict $ \s -> s{firstOutline = True:(firstOutline s)} + +-- | We remember there are outlines at this level +addedOutline :: PDF () +addedOutline = modifyStrict $ \s -> s{firstOutline = False:tail (firstOutline s)} + +-- | Close an outline level +closeNew :: PDF() +closeNew = do + r <- gets firstOutline + when (not (isFirst r)) $ moveToParent + modifyStrict $ \s -> s{firstOutline = tail (firstOutline s)} + +-- | Create a new outline section pointing to the last created page +newSection :: PDFString -- ^ Outline title + -> Maybe Color -- ^ Outline color + -> Maybe OutlineStyle -- ^Outline style + -> PDF () + -> PDF () +newSection myS col style p = newSectionPrivate myS col style Nothing p + +-- | Create a new outline section pointing to a given page +newSectionWithPage :: PDFString -- ^ Outline title + -> Maybe Color -- ^ Outline color + -> Maybe OutlineStyle -- ^ Outline style + -> PDFReference PDFPage -- ^ Page reference + -> PDF () + -> PDF () +newSectionWithPage myS col style page p = newSectionPrivate myS col style (Just page) p + +newSectionPrivate :: PDFString -- ^ Outline title + -> Maybe Color -- ^ Outline color + -> Maybe OutlineStyle -- ^Outline style + -> Maybe (PDFReference PDFPage) + -> PDF () + -> PDF () +newSectionPrivate myS col style page p = do + let newlevel = do + startNew + p + closeNew + r <- gets firstOutline + if isFirst r + then do + if length r > 1 + then do + newChild myS col style page + addedOutline + newlevel + else do + newSibling myS col style page + newlevel + else do + newSibling myS col style page + newlevel + hunk ./Graphics/PDF/Navigation.hs 95 + -> Maybe (PDFReference PDFPage) hunk ./Graphics/PDF/Navigation.hs 97 -newSibling myS col style = do - p <- gets currentPage +newSibling myS col style page = do + p <- if isNothing page then gets currentPage else return page hunk ./Graphics/PDF/Navigation.hs 111 + -> Maybe (PDFReference PDFPage) hunk ./Graphics/PDF/Navigation.hs 113 -newChild myS col style = do - p <- gets currentPage +newChild myS col style page = do + p <- if isNothing page then gets currentPage else return page hunk ./Graphics/PDF/Text.hs 102 --- | Format a text string inside a rectangle +-- | Format a text string inside a rectangle. Experimental and will be replaced by a better typesetting +-- system in a next version addfile ./Graphics/PDF/Typesetting.hs hunk ./Graphics/PDF/Typesetting.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Typesetting +-- Work in progress +--------------------------------------------------------- + +module Graphics.PDF.Typesetting( + -- * Typesetting + Box(..) + , Paragraph + , B + , paragraph + ) where + +import Graphics.PDF.LowLevel.Types +import Graphics.PDF.Text +import qualified Data.ByteString.Lazy.Char8 as B(words,unwords) +import Data.List(intersperse) + +class Box a where + boxWidth :: a -> PDFFloat + +data B = forall a. Box a => B !a + | Glue !PDFFloat !PDFFloat !PDFFloat + | Penalty !PDFFloat !PDFFloat !Bool + +instance Box B where + boxWidth (B a) = boxWidth a + boxWidth (Glue w _ _) = w + boxWidth (Penalty w _ _) = w + +type Paragraph = [B] + +data T = T !PDFFont !PDFString + +instance Box T where + boxWidth (T f s) = textWidth f s + +infinity :: PDFFloat +infinity = 10000 + +endParagraphBoxes :: Paragraph +endParagraphBoxes = [Glue 0 infinity 0,Penalty 0 (-infinity) False] + +paragraph :: PDFFont -> PDFString -> Paragraph +paragraph f (PDFString t) = let ws = textWidth f (toPDFString " ") in + (intersperse (Glue ws 0 0) . map (B . T f . PDFString) . B.words $ t) ++ endParagraphBoxes hunk ./HPDF.cabal 10 -build-depends: base, haskell98,mtl,encoding,zlib +build-depends: base, haskell98,mtl,encoding >= 0.1 ,zlib >= 0.3 hunk ./LICENSE 26 -* UTF8.lhs : Copyright Sven Moritz Hallberg. See the comments in the file. hunk ./README.txt 7 -runghc Setup.hs configure or runghc Setup.hs configure -p if you also want to build the profiling version +runghc Setup.hs configure hunk ./README.txt 16 -make test : for a simpler test -make : to test the software with the installed library -make prof : to build a profiling version -make clean : to clean everything. - - +make demo : to build a demo pdf hunk ./Test/Makefile 3 - - -prof: - ghc -o test -ffi -prof -auto-all -cpp -funbox-strict-fields -fglasgow-exts -O2 -hidir interfaces -odir bin -i.. --make test.hs - -standard: + +demo: hunk ./Test/Makefile 23 + rm -rf c hunk ./Test/Makefile 25 + mkdir c hunk ./Test/Penrose.hs 1 -module Penrose where +module Penrose ( + penrose + )where hunk ./Test/Penrose.hs 5 -import System.Environment hunk ./Test/Penrose.hs 102 -penrose :: Int -> Draw () -penrose n = do - applyMatrix (rotate . Degree $ 36) - divide n B - divide n B' +penrose :: PDF () +penrose = do + page <- addPage (Just (PDFRect 0 0 (round (1.5*width)) (round width))) + newSection (toPDFString "Penrose") Nothing Nothing $ do + drawWithPage page $ do + applyMatrix (translate 20 5) + applyMatrix (rotate . Degree $ 36) + divide 4 B + divide 4 B' hunk ./Test/Penrose.hs 113 - -testPenrose :: IO () -testPenrose = - do nb <- getArgs - let rect = PDFRect 0 0 (round (1.5*width)) (round width) - runPdf ("penrose_" ++ (head nb) ++ ".pdf") (standardDocInfo {compressed=False}) rect $ do - page <- addPage Nothing - drawWithPage page $ do - applyMatrix (translate 20 5) - penrose ((read . head $ nb)::Int) - - + addfile ./Test/logo.jpg binary ./Test/logo.jpg oldhex * newhex *ffd8ffe000104a46494600010101004800480000ffe10139687474703a2f2f6e732e61646f6265 *2e636f6d2f7861702f312e302f003c3f787061636b657420626567696e3d27efbbbf272069643d *2757354d304d7043656869487a7265537a4e54637a6b633964273f3e3c783a786d706d65746120 *786d6c6e733a783d2761646f62653a6e733a6d6574612f2720783a786d70746b3d27584d502074 *6f6f6c6b697420322e392d392c206672616d65776f726b20312e36273e0a3c7264663a52444620 *786d6c6e733a7264663d27687474703a2f2f7777772e77332e6f72672f313939392f30322f3232 *2d7264662d73796e7461782d6e73232720786d6c6e733a69583d27687474703a2f2f6e732e6164 *6f62652e636f6d2f69582f312e302f273e0a0a3c2f7264663a5244463e0a3c2f783a786d706d65 *74613e0a3c3f787061636b657420656e643d2777273f3effdb0043000302020302020303030304 *030304050805050404050a070706080c0a0c0c0b0a0b0b0d0e12100d0e110e0b0b101610111314 *1515150c0f171816141812141514ffdb00430103040405040509050509140d0b0d141414141414 *141414141414141414141414141414141414141414141414141414141414141414141414141414 *1414141414ffc00011080039003c03012200021101031101ffc4001f0000010501010101010100 *000000000000000102030405060708090a0bffc400b5100002010303020403050504040000017d *01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a *161718191a25262728292a3435363738393a434445464748494a535455565758595a6364656667 *68696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3 *b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4 *f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0b *ffc400b51100020102040403040705040400010277000102031104052131061241510761711322 *328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a3536373839 *3a434445464748494a535455565758595a636465666768696a737475767778797a828384858687 *88898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9ca *d2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c0301000211031100 *3f00fd5118e9452f18cd7ce3fb51fed530fc1e65f0de80897be2eb88848c5fe68ac636c80cc3bb *9c1daa7b7cc78c06b841cdf2c4e6c46229e1a9ba951d923d47e2dfc63d0fe0d78786adabc37fa8 *6e95634b1d260fb45d3ee382c23041da31cb76af196ff82867c3f1204ff8467c7018f1ff002023 *d7f17af807e2cfc5fd52d74dbcf12f88efeeb53b991d630af29dd348c480b939c00013e800200e *82b1bc0fe31b1f1ac24dbcd19ba504c9002c1e323190cac011c1041190467a10457a74f091e5bc *ba1f3ab36c4d4a72af4a97b8bccfd07fd8e7f6cf8fe3a4dae786f5db2bb8757d16ea7857597b5f *22daee1590ac3e60dc445395233182412ac410302beb2c83f4afc71f0cfda7c091c49a0cb26991 *c44b2a40c40c939248cf249ea4e49ef5f55fc0ff00db52d7c396eb65e3dd422b1b18caa0bc9ce2 *3c938183ce093fc3d0e78c1eb8e230faf3535a1ae1f3ca75eafb39c796fb1f72d159379e26d274 *ff000e4bafdd6a56b6da2456c6f64d426995208e00bb8c8ce4e0285e724e3153e8bacd8f88b49b *3d534bbb8750d3af2259edeeaddc3c7346c32acac382083904579f667d31e3bf11746f15780fe2 *1ea9f15aebe205d7fc201a2e857124de0c36ca23795222415901192cc377cc0b02000402457e63 *69d77aff008975dd6bc41e25d53fb5754d5eee4bd794a9054bb160b824801410a00c00aaa00e2b *edefdbbbe1cf8b2cbc33e29f1f5bfc46d5a3f0c9b0b7d3a5f072c03ecadbe78919c38600672589 *6566c800301c57c37e07d1aef498ee3ed7a936a0934a648b729531a924e09248246401800600e2 *bd8c35b95bbea7ca67b55f2aa5cd656edbea74b37866c75b1682fad96e45adc25d421c9c2cab9d *ad807923278391ed5c978fa08747f8a9e09beb62a3529e3b98aee21c192d1543163ea54ee033d7 *271d2bd334b50c40e324f7af9d6e9b55f8c1f1535dd5742ba681ecd1ec7489d7955112b166c742 *18eef63e628aeca50536f9b44b538728c3fb69c9cdda093bfccfa0aeec42e71823d7b1ae3bc69e *1e5d7f40bfd38901a788ac6dfdd71ca1fc1803f856e7c3bf132f8c7e1e68ba99189de011cea7aa *c89f2b0fae467f1a76a000cff4ace32d6e8f12ac5e1aae9bc58ff09fc58f8b9f19fe157813e16b *78ab4a6d07c5faaa786a5d2ad6d186a56d6d0ec6b877931811850338c92188e99afd74d1b47b6d *0748b1d334f856d6c6ca04b682141858e3450aaa3d800057e73ffc13d3e055b7fc2f3d6bc7f2dc *a4f159dbce96764d11cdb4d36c124a1b76391bc6319f9cf3c57e9366b831d38ce4a104acbf367e *9b43110c5518ce1b3feadf2388f8dbe01ff85a3f097c59e15560b36a9a74b040e7a2cdb73193f4 *70a7f0afc8ef0d5d4c2d8417513db5edb3182e2de5055e2914957561d41041041e8457ed05f5ed *be99673de5dcf1dada5ba34b34f338448d1412cccc78000c924f402bf34ff6cbf09781f4bf13df *fc4ef0278d3c35a9d86a12236b9a3596ab6ef2c5331dbf6a891589657246f50321896e4336dcf0 *b2b4addcf1737c14b134d4e9abb89e07f16bc6ede0ff0087fa84b6f294d42f47d8ad48382aee08 *2c3fdd50c7ea052fc02f0dc7e14f0e2dc6144aca21465f620c841ef960173e918ac7b2f117843e *2439b3ba86d7537b5959521bc8c1c9e85932704103b738ed5dcd8cd069f690dadac496f6d0a848 *e2886d5451d000380057b3cce3070b5ae7cefd6de130af0ae2e3293bb6fb74380d3bc5b6ff000a *bc49e2fd0ee14b5b4d72754d36057542eb2824aa9620101f729e72300e0f6e9fc3dacdeeafe18b *1bcd4844b7b2a16905b83b33b881b724e4600c1efd7bd53f1f41e1fbcd3c6a1aee911eac96846d *3e4f98e81980270082547048e460138ad9f86fadf857c55e30d06cf53d6e0d13c37732ac726b97 *08458db1ce047238c08d8804286da0fa8192239528dd2d89aafebf4e2a8527cef77d345fd367df *7fb09782e6d13e1fde6b1711946bf971192304a8ea7f97e46be9e2326b1fc1fa4e99a1f8674db0 *d19a37d32085520789832baf5dd91c1cf527b926b64e2be7e72729b67dc60e87d56846975466f8 *8b4b935cf0fea7a7472c7049776d25bacb340b3a21652a19a36f95c027254f04707835f392fec8 *be258e3558fc75e1b4c0e83e1e699b7f218afa828a215250bd8ee4dad8fce4d1ff00e0977abf8e *bc7de24d5fc7de25b2d134e8ef1c694be14d36ded26bb507e5b895557645bb3cc6a339eac31cf5 *b71ff04ded6e0b90969f116de6b5cfdeb8d2d95c0f43894e7eb91f4afbb7d6815bbc55595b538b *1384a38bb7b58dec7c43abff00c13a2e20f08dd8d2fc662fbc56cd18b696fedbc9b08d4ba890bc *69b9d884de540600b000e0126a6f0eff00c13d750f03f9d6de1cf1cad937886ca5b4f166bd2d82 *3dd5cc476016f676d8fb3c08c036e9183c838c1e49afb5ff00869075a4b1357b9587c351c22fdc *c6c70df05fe0d7877e037806c7c21e164ba4d2ad4970d7970d348eed8dcc58fae3a0000ec05779 *49eb40e95cb2936f99eeceadd9ffd9 hunk ./Test/test.hs 1 ---------------------------------------------------------------------------- +--------------------------------------------------------- hunk ./Test/test.hs 3 --- Module : Main --- Copyright : (c) Christophe Favergeon, 2007 --- License : BSD-style --- --- Maintainer : c-favergeon-borgialli@ti.com --- Stability : experimental --- Portability : portable +-- Copyright : (c) alpha 2007 +-- License : BSD-style hunk ./Test/test.hs 6 --- Description +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable hunk ./Test/test.hs 10 --- Some text --- --- See below for examples. - ------------------------------------------------------------------------------ +-- Test +--------------------------------------------------------- hunk ./Test/test.hs 19 -import Graphics.PDF.Text hunk ./Test/test.hs 20 -triplet :: String -> PDF () -triplet s = do - addPage Nothing - newSibling (toPDFString $ "Page A" ++ s) (Just $ Rgb 1 0 0) Nothing - addPage Nothing - newChild (toPDFString $ "Page B" ++ s) Nothing (Just Italic) - addPage Nothing - newChild (toPDFString $ "Page C" ++ s) Nothing (Just Bold) - addPage Nothing - newSibling (toPDFString $ "Page D" ++ s) Nothing Nothing - moveToParent - moveToParent - - -simple :: IO () -simple = do - let rect = PDFRect 0 0 612 792 - --runPdf "test.pdf" (standardDocInfo { author=toPDFString $ "alpheccar (éèçà)" - -- , pageMode = FullScreen - -- , compressed = False - -- , viewerPreferences = standardViewerPrefs { - -- hideToolbar = True - -- } - -- }) rect $ do - runPdf "test.pdf" (standardDocInfo { author=toPDFString $ "alpheccar (éèçà)" - , compressed = False - }) rect $ do - r <- createPDFXForm 0 0 200 200 myDrawing - p <- createUncoloredTiling 0 0 100 50 100 50 ConstantSpacing pattern - cp <- createColoredTiling 0 0 100 50 100 50 ConstantSpacing cpattern - Right jpg <- createPDFJpeg "logo.jpg" - --page <- addPageWithTransition Nothing (Just 3.0) (Just (PDFTransition 1.0 Dissolve)) - page <- addPage Nothing - newSibling (toPDFString "Page Main") Nothing Nothing - drawWithPage page $ do - newAnnotation (URLLink (toPDFString "Test") [0,0,100,100] "http://www.alpheccar.org" True) - strokeColor (Rgb 1 0 0) - fillColor (Rgb 0 0 1) - (withNewContext $ do - applyMatrix (scale 0.5 0.5) - applyMatrix (translate 200 20) - drawXObject r - ) - drawText $ text (PDFFont Helvetica 12) 200 200 (toPDFString "This is a test éèçàù") - fillColor (Rgb 1 0 0) - setFillAlpha 0.4 - drawXObject r - setFillAlpha 1.0 - drawXObject jpg - --draw (Rect 0 0 300 100) - setWidth 2 - setDash $ DashPattern [3] 0 - stroke (RoundRectangle 32 16 0 0 300 200) - --setUncoloredFillPattern p (Rgb 1 0 0) - setColoredFillPattern cp - --paintWithShading (RadialShading 0 0 50 0 0 600 (Rgb 1 0 0) (Rgb 0 0 1)) (addShape $ Rectangle 0 0 300 300) - fill $ Rectangle 0 0 300 300 - return () - --mapM_ (\x -> do addPageWithTransition Nothing (Just 3) (Just (PDFTransition 1.0 Dissolve)) - -- newOutline (toPDFString $ "Page " ++ (show x)) - -- ) [1..10] - triplet "A" - triplet "B" - triplet "C" - return () - where - myDrawing = do - stroke (Line 0 0 100 100) - fill (Rectangle 100 100 200 200) - pattern = do - stroke (Ellipse 0 0 100 50) - cpattern = do - strokeColor (Rgb 0 0 1) - stroke (Ellipse 0 0 100 50) - -fontDebug :: PDFFont -> String -> PDF () -fontDebug f t' = do - let t = toPDFString t' - page <- addPage Nothing - newSibling t Nothing Nothing - drawWithPage page $ do - fillColor $ Rgb 0 0 0 + +fontDebug :: PDFFont -> PDFString -> Draw () +fontDebug f t = do hunk ./Test/test.hs 25 - textStart 10 400.0 + textStart 10 200.0 hunk ./Test/test.hs 32 - stroke $ Line 10 400 612 400 - fill $ Circle 10 400 10 - stroke $ Rectangle 10 (400.0 - (getDescent f)) (10.0 + textWidth f t) (400.0 - getDescent f + getHeight f) - -testText :: IO () -testText = do - let rect = PDFRect 0 0 612 792 - runPdf "text.pdf" (standardDocInfo { author=toPDFString $ "alpheccar (éèçà)" - , compressed = False - }) rect $ do - fontDebug (PDFFont Times_Roman 48) ("AbAVAVcéèHjpA¡ Test!") - fontDebug (PDFFont Helvetica 48) ( "AAAVAA") - fontDebug (PDFFont Times_BoldItalic 48) ( "AbAVAVcéèHjpA¡ Test!") - fontDebug (PDFFont Courier 48) ( "AbAVAVcéèHjpA¡ Test!") + stroke $ Line 10 200 612 200 + fill $ Circle 10 200 10 + stroke $ Rectangle 10 (200.0 - (getDescent f)) (10.0 + textWidth f t) (200.0 - getDescent f + getHeight f) + + +geometryTest :: Draw () +geometryTest = do + strokeColor red + stroke $ Rectangle 0 0 200 100 + fillColor blue + fill $ Ellipse 100 100 300 200 + fillAndStroke $ RoundRectangle 32 32 200 200 600 400 + +lineStyle ::Draw () +lineStyle = do + withNewContext $ do + setWidth 2 + setDash $ DashPattern [3] 0 + geometryTest + + +shadingTest :: Draw () +shadingTest = do + paintWithShading (RadialShading 0 0 50 0 0 600 (Rgb 1 0 0) (Rgb 0 0 1)) (addShape $ Rectangle 0 0 300 300) + paintWithShading (AxialShading 300 300 600 400 (Rgb 1 0 0) (Rgb 0 0 1)) (addShape $ Ellipse 300 300 600 400) + + +patternTest :: PDFReference PDFPage -> PDF () +patternTest page = do + p <- createUncoloredTiling 0 0 100 50 100 50 ConstantSpacing pattern + cp <- createColoredTiling 0 0 100 50 100 50 ConstantSpacing cpattern + drawWithPage page $ do + strokeColor green + setUncoloredFillPattern p (Rgb 1 0 0) + fillAndStroke $ Ellipse 0 0 300 300 + setColoredFillPattern cp + fillAndStroke $ Ellipse 300 300 600 400 + + where + myDrawing = do + stroke (Line 0 0 100 100) + fill (Rectangle 100 100 200 200) + pattern = do + stroke (Ellipse 0 0 100 50) + cpattern = do + strokeColor (Rgb 0 0 1) + stroke (Ellipse 0 0 100 50) + +testAnnotation :: Draw () +testAnnotation = do + strokeColor red + newAnnotation (URLLink (toPDFString "Go to my blog") [0,0,100,100] "http://www.alpheccar.org" True) + drawText $ text (PDFFont Times_Roman 12) 10 30 (toPDFString "Go to my blog") + stroke $ Rectangle 0 0 100 100 + newAnnotation (TextAnnotation (toPDFString "Key annotation") [100,100,130,130] Key) + +textTest :: Draw () +textTest = do + strokeColor red + fillColor blue + fontDebug (PDFFont Times_Roman 48) (toPDFString "This is a test !") + + +testImage :: PDFReference PDFPage -> PDF () +testImage page = do + Right jpg <- createPDFJpeg "logo.jpg" + drawWithPage page $ do + withNewContext $ do + setFillAlpha 0.4 + drawXObject jpg + withNewContext $ do + applyMatrix $ rotate (Degree 20) + applyMatrix $ translate 200 200 + applyMatrix $ scale 2 2 + drawXObject jpg + +testAll :: PDF () +testAll = do + page <- addPage Nothing + newSection (toPDFString "Shapes") Nothing Nothing $ do + + newSection (toPDFString "Geometry") Nothing Nothing $ do + drawWithPage page $ do + geometryTest + + page <- addPage Nothing + newSection (toPDFString "Line style") Nothing Nothing $ do + drawWithPage page $ do + lineStyle hunk ./Test/test.hs 122 - newSibling (toPDFString "TextBox") Nothing Nothing + newSection (toPDFString "Object reuse") Nothing Nothing $ do + r <- createPDFXForm 0 0 200 200 lineStyle + drawWithPage page $ do + drawXObject r + + page <- addPage Nothing + newSectionWithPage (toPDFString "Painting") Nothing Nothing page $ do + newSection (toPDFString "Patterns") Nothing Nothing $ do + patternTest page + page <- addPage Nothing + newSection (toPDFString "Shading") Nothing Nothing $ do + drawWithPage page $ do + shadingTest + page <- addPage Nothing + newSection (toPDFString "Media") Nothing Nothing $ do + newSection (toPDFString "image") Nothing Nothing $ do + testImage page + + page <- addPage Nothing + newSection (toPDFString "Annotations") Nothing Nothing $ do + drawWithPage page $ do + testAnnotation + page <- addPage Nothing + newSection (toPDFString "Text") Nothing Nothing $ do hunk ./Test/test.hs 147 - let rect = Rectangle 10 10 400 400 - stroke $ rect - textBox (PDFFont Times_Roman 48) (toPDFString "This is a long text to test the justification algorithm for the simplified text box") - rect - --- | Get options and set config + textTest + newSection (toPDFString "Fun") Nothing Nothing $ do + penrose + + + hunk ./Test/test.hs 155 - simple - testPenrose - testText + let rect = PDFRect 0 0 600 400 + runPdf "demo.pdf" (standardDocInfo { author=toPDFString $ "alpheccar"}) rect $ do + testAll + hunk ./README.txt 17 +./test : to run the demo hunk ./Graphics/PDF.hs 51 - + addfile ./Graphics/PDF/Demo.hs hunk ./Graphics/PDF/Demo.hs 1 - +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- PDF demo. Generate a file demo.pdf +--------------------------------------------------------- +module Graphics.PDF.Demo(demo) where + +import Graphics.PDF + +fontDebug :: PDFFont -> PDFString -> Draw () +fontDebug f t = do + drawText $ do + setFont f + textStart 10 200.0 + leading $ getHeight f + renderMode FillText + displayText t + startNewLine + displayText $ toPDFString "Another little test" + strokeColor $ Rgb 1 0 0 + stroke $ Line 10 200 612 200 + fill $ Circle 10 200 10 + stroke $ Rectangle 10 (200.0 - (getDescent f)) (10.0 + textWidth f t) (200.0 - getDescent f + getHeight f) + + +geometryTest :: Draw () +geometryTest = do + strokeColor red + stroke $ Rectangle 0 0 200 100 + fillColor blue + fill $ Ellipse 100 100 300 200 + fillAndStroke $ RoundRectangle 32 32 200 200 600 400 + +lineStyle ::Draw () +lineStyle = do + withNewContext $ do + setWidth 2 + setDash $ DashPattern [3] 0 + geometryTest + + +shadingTest :: Draw () +shadingTest = do + paintWithShading (RadialShading 0 0 50 0 0 600 (Rgb 1 0 0) (Rgb 0 0 1)) (addShape $ Rectangle 0 0 300 300) + paintWithShading (AxialShading 300 300 600 400 (Rgb 1 0 0) (Rgb 0 0 1)) (addShape $ Ellipse 300 300 600 400) + + +patternTest :: PDFReference PDFPage -> PDF () +patternTest page = do + p <- createUncoloredTiling 0 0 100 50 100 50 ConstantSpacing pattern + cp <- createColoredTiling 0 0 100 50 100 50 ConstantSpacing cpattern + drawWithPage page $ do + strokeColor green + setUncoloredFillPattern p (Rgb 1 0 0) + fillAndStroke $ Ellipse 0 0 300 300 + setColoredFillPattern cp + fillAndStroke $ Ellipse 300 300 600 400 + + where + myDrawing = do + stroke (Line 0 0 100 100) + fill (Rectangle 100 100 200 200) + pattern = do + stroke (Ellipse 0 0 100 50) + cpattern = do + strokeColor (Rgb 0 0 1) + stroke (Ellipse 0 0 100 50) + +testAnnotation :: Draw () +testAnnotation = do + strokeColor red + newAnnotation (URLLink (toPDFString "Go to my blog") [0,0,100,100] "http://www.alpheccar.org" True) + drawText $ text (PDFFont Times_Roman 12) 10 30 (toPDFString "Go to my blog") + stroke $ Rectangle 0 0 100 100 + newAnnotation (TextAnnotation (toPDFString "Key annotation") [100,100,130,130] Key) + +textTest :: Draw () +textTest = do + strokeColor red + fillColor blue + fontDebug (PDFFont Times_Roman 48) (toPDFString "This is a test !") + + +--testImage :: FilePath -> PDFReference PDFPage -> PDF () +--testImage logo page = do +-- Right jpg <- createPDFJpeg logo +-- drawWithPage page $ do +-- withNewContext $ do +-- setFillAlpha 0.4 +-- drawXObject jpg +-- withNewContext $ do +-- applyMatrix $ rotate (Degree 20) +-- applyMatrix $ translate 200 200 +-- applyMatrix $ scale 2 2 +-- drawXObject jpg + +testAll :: FilePath -> PDF () +testAll logo = do + page <- addPage Nothing + newSection (toPDFString "Shapes") Nothing Nothing $ do + + newSection (toPDFString "Geometry") Nothing Nothing $ do + drawWithPage page $ do + geometryTest + + page <- addPage Nothing + newSection (toPDFString "Line style") Nothing Nothing $ do + drawWithPage page $ do + lineStyle + page <- addPage Nothing + newSection (toPDFString "Object reuse") Nothing Nothing $ do + r <- createPDFXForm 0 0 200 200 lineStyle + drawWithPage page $ do + drawXObject r + + page <- addPage Nothing + newSectionWithPage (toPDFString "Painting") Nothing Nothing page $ do + newSection (toPDFString "Patterns") Nothing Nothing $ do + patternTest page + page <- addPage Nothing + newSection (toPDFString "Shading") Nothing Nothing $ do + drawWithPage page $ do + shadingTest + page <- addPage Nothing + --newSection (toPDFString "Media") Nothing Nothing $ do + -- newSection (toPDFString "image") Nothing Nothing $ do + -- testImage logo page + + page <- addPage Nothing + newSection (toPDFString "Annotations") Nothing Nothing $ do + drawWithPage page $ do + testAnnotation + page <- addPage Nothing + newSection (toPDFString "Text") Nothing Nothing $ do + drawWithPage page $ do + textTest + + +-- | Run the demo and create a demo.pdf file +demo :: IO() +demo = do + let rect = PDFRect 0 0 600 400 + runPdf "demo.pdf" (standardDocInfo { author=toPDFString $ "alpheccar"}) rect $ do + testAll "" + hunk ./HPDF.cabal 31 + Graphics.PDF.Demo hunk ./HPDF.cabal 39 + hunk ./HPDF.cabal 13 +extra-source-files: + c/ctext.h + c/metrics.h + Test/AFMParser.hs + Test/logo.jpg + Test/Makefile + Test/Penrose.hs + Test/test.hs + README.txt hunk ./Graphics/PDF/Document.hs 21 + , createPDFXForm hunk ./Graphics/PDF/Document.hs 28 - -- ** Drawings - , withNewContext - , emptyDrawing - , createPDFXForm hunk ./Graphics/PDF/Document.hs 35 + -- * Draw monad and drawing functions + -- ** Types + , Draw + , PDFXObject(drawXObject,bounds) + -- ** General drawing functions + , withNewContext + , emptyDrawing hunk ./Graphics/PDF.hs 29 - -- *** Draw monad - , Draw - , PDFXObject(drawXObject,bounds) hunk ./HPDF.cabal 9 -homepage: http://www.alpheccar.org +homepage: http://www.alpheccar.org/en/posts/show/80 hunk ./HPDF.cabal 13 +description: A PDF library allowing to generate multipage PDF documents with outlines, links ... hunk ./Graphics/PDF.hs 47 + -- ** Typesetting + , module Graphics.PDF.Typesetting hunk ./Graphics/PDF.hs 51 +import Graphics.PDF.Typesetting hunk ./HPDF.cabal 2 -Version: 1.0 +Version: 1.1 hunk ./HPDF.cabal 42 + Graphics.PDF.Typesetting hunk ./Graphics/PDF/Text.hs 237 - textStart x y + textStart x (y ) hunk ./Graphics/PDF/Typesetting.hs 19 - , paragraph + , newText + , displayWithBreaks hunk ./Graphics/PDF/Typesetting.hs 25 +import Graphics.PDF.Draw +import Graphics.PDF.Shapes +import Graphics.PDF.Colors hunk ./Graphics/PDF/Typesetting.hs 30 +import Debug.Trace hunk ./Graphics/PDF/Typesetting.hs 33 - boxWidth :: a -> PDFFloat + boxWidth :: a -> Maybe PDFFloat -> PDFFloat + boxHeight :: a -> PDFFloat + boxDescent :: a -> PDFFloat + strokeBox :: a -> Maybe PDFFloat -> PDFFloat -> PDFFloat -> Draw () hunk ./Graphics/PDF/Typesetting.hs 43 - boxWidth (B a) = boxWidth a - boxWidth (Glue w _ _) = w - boxWidth (Penalty w _ _) = w + boxWidth (B a) r = boxWidth a r + boxWidth (Glue w yi zi) Nothing = w + boxWidth (Glue w yi zi) (Just r) = + if r >= 0 + then + r*yi + w + else + r*zi + w + boxWidth (Penalty w _ _) _ = 0 hunk ./Graphics/PDF/Typesetting.hs 53 -type Paragraph = [B] + boxHeight (B a) = boxHeight a + boxHeight (Glue _ _ _) = 0 + boxHeight (Penalty _ _ _) = 0 + + boxDescent (B a) = boxDescent a + boxDescent (Glue _ _ _) = 0 + boxDescent (Penalty _ _ _) = 0 + + strokeBox (B a) r x y = strokeBox a r x y + strokeBox (Penalty _ _ _) r x y = do + withNewContext $ do + setWidth 0.5 + strokeColor black + stroke $ Line x (y-3) x (y+3) + return () + strokeBox (Glue w yi zi) Nothing x y = return () + strokeBox (Glue w yi zi) (Just r) x y = do + withNewContext $ do + setWidth 0.5 + strokeColor green + stroke $ Line x y (x+w) y + strokeColor blue + stroke $ Line (x+w) y (x+w+r*yi) y + strokeColor $ Rgb 1 1 0 + stroke $ Line (x+w) (y-2) (x+w+r*zi) (y-2) + return () + +instance Box a => Box [a] where + boxWidth l r = foldr (\x y -> y + boxWidth x r) 0.0 l + boxHeight l = maximum . map boxHeight $ l + boxDescent l = minimum . map boxDescent $ l + + strokeBox [] r x y = return () + strokeBox (a:l) r x y = do + strokeBox a r x y + strokeBox l r (x + boxWidth a r) y + +type Text = [B] +type TextLine = [B] +type Paragraph = [TextLine] hunk ./Graphics/PDF/Typesetting.hs 97 - boxWidth (T f s) = textWidth f s - + boxWidth (T f s) _ = textWidth f s + boxHeight (T f _) = getHeight f + boxDescent (T f _) = getDescent f + + strokeBox (T f s) r x y = do + withNewContext $ do + setWidth 0.5 + drawText $ text f x y s + strokeColor red + stroke $ Rectangle x (y - (getDescent f)) (x + textWidth f s) (y - getDescent f + getHeight f) + +-- | Value modeling infinity hunk ./Graphics/PDF/Typesetting.hs 112 -endParagraphBoxes :: Paragraph + +-- | Compute the line width. A penalty width is taken into account only at the end +lineWidth :: TextLine -> (PDFFloat,PDFFloat,PDFFloat) +lineWidth [] = (0,0,0) +lineWidth [Penalty w _ _] = (w,0,0) +lineWidth (a@(B _):l) = let (w',y',z') = lineWidth l in (w' + boxWidth a (Just 0.0), y',z' ) +lineWidth ((Glue w y z):l) = let (w',y',z') = lineWidth l in (w+w',y+y',z+z') +lineWidth (a@(Penalty _ _ _):l) = lineWidth l + +adjustRatio :: TextLine -- ^ Line + -> PDFFloat -- ^ Required width + -> Maybe PDFFloat -- ^ Adjustement ratio +adjustRatio l maxw = let (w,y,z) = lineWidth l in + if w == maxw + then Just 0.0 + else if w < maxw + then + if y > 0.0 then Just ((maxw - w) / y) else Nothing + else + if z > 0.0 then Just ((maxw - w) / z) else Nothing + +badness :: Maybe PDFFloat -> PDFFloat +badness Nothing = infinity +badness (Just r) = 100.0 * abs(r)^3 + +endParagraphBoxes :: TextLine hunk ./Graphics/PDF/Typesetting.hs 139 - -paragraph :: PDFFont -> PDFString -> Paragraph -paragraph f (PDFString t) = let ws = textWidth f (toPDFString " ") in - (intersperse (Glue ws 0 0) . map (B . T f . PDFString) . B.words $ t) ++ endParagraphBoxes + +-- | Convert a PDF string to a Text +newText :: PDFFont -> PDFString -> Text +newText f (PDFString t) = let ws = textWidth f (toPDFString " ") in + (intersperse (Glue ws (ws/2.0) (ws/3.0)) . map (B . T f . PDFString) . B.words $ t) ++ endParagraphBoxes + +-- | Display a list of boxes with the given line breaks +displayWithBreaks :: PDFFloat -> PDFFloat -> PDFFloat -> Text -> Int -> [Int] -> Draw () +displayWithBreaks maxw x y t _ [] = do + let y' = y + boxDescent t - boxHeight t + r = adjustRatio t maxw + strokeBox t r x y' +displayWithBreaks maxw x y t c (a:l) = do + let (theLine,t') = splitAt (a-c) t + h = boxHeight theLine + d = boxDescent theLine + y' = y + d - h + r = adjustRatio theLine maxw + strokeBox theLine r x y' + displayWithBreaks maxw x (y- h) (simplify t') a l + +simplify :: Text -> Text +simplify [] = [] +simplify ((Glue _ _ _):l) = simplify l +simplify ((Penalty _ _ _):l) = simplify l +simplify l = l hunk ./Test/test.hs 107 - + + +typesetTest :: PDFReference PDFPage -> PDF () +typesetTest page = do + let f = PDFFont Times_Roman 10 + --t = newText f (toPDFString "This is a test for the formatting and layout algorithm. I am sure it won't work.") + t = newText f (toPDFString "This is a test") + textStart = 300 - boxHeight t + boxDescent t + maxw = 100 + drawWithPage page $ do + strokeColor red + setWidth 0.5 + stroke $ Rectangle 10 300 (10+maxw) 0 + stroke $ Line 10 textStart (10+maxw) textStart + strokeColor black + --displayWithBreaks maxw 10 300 t 1 [6,10,14,20,29,33] + displayWithBreaks maxw 10 300 t 1 [6] + return () + hunk ./Test/test.hs 129 + newSection (toPDFString "Typesetting") Nothing Nothing $ do + typesetTest page + + page <- addPage Nothing hunk ./Graphics/PDF/LowLevel/Types.hs 72 -newtype PDFString = PDFString B.ByteString deriving(Eq,Ord) +newtype PDFString = PDFString B.ByteString deriving(Eq,Ord,Show) hunk ./Graphics/PDF/Resources.hs 67 -data PDFFont = PDFFont FontName FontSize deriving(Eq) +data PDFFont = PDFFont FontName FontSize deriving(Eq,Show) hunk ./Graphics/PDF/Typesetting.hs 19 - , newText - , displayWithBreaks + , displayFormattedText hunk ./Graphics/PDF/Typesetting.hs 28 -import Data.List(intersperse) -import Debug.Trace +import Data.List(intersperse,minimumBy) +import qualified Data.Map as Map hunk ./Graphics/PDF/Typesetting.hs 32 - boxWidth :: a -> Maybe PDFFloat -> PDFFloat + boxWidth :: a -> PDFFloat -> PDFFloat hunk ./Graphics/PDF/Typesetting.hs 35 - strokeBox :: a -> Maybe PDFFloat -> PDFFloat -> PDFFloat -> Draw () + strokeBox :: a -> PDFFloat -> PDFFloat -> PDFFloat -> Draw () hunk ./Graphics/PDF/Typesetting.hs 37 -data B = forall a. Box a => B !a +data B = forall a. (Show a,Box a) => B !a hunk ./Graphics/PDF/Typesetting.hs 41 +instance Show B where + show (B a) = "(B " ++ show a ++ ")" + show (Glue a b c) = "(Glue " ++ show a ++ " " ++ show b ++ " " ++ show c ++ ")" + show (Penalty a b c) = "(Penalty " ++ show a ++ " " ++ show b ++ " " ++ show c ++ ")" + + +type CB = (PDFFloat,PDFFloat,PDFFloat,Int,B) + +class PointedBox a where + isFlagged :: a -> Bool + penalty :: a -> PDFFloat + box :: a -> B + position :: a -> Int + cumulatedW :: a -> PDFFloat + cumulatedY :: a -> PDFFloat + cumulatedZ :: a -> PDFFloat + isForcedBreak :: a -> Bool + +instance PointedBox (PDFFloat,PDFFloat,PDFFloat,Int,B) where + isFlagged (_,_,_,_,Penalty _ _ f) = f + isFlagged _ = False + penalty (_,_,_,_,Penalty _ p _) = p + penalty _ = 0.0 + box (_,_,_,_,a) = a + position (_,_,_,p,_) = p + cumulatedW (w,_,_,_,_) = w + cumulatedY (_,y,_,_,_) = y + cumulatedZ (_,_,z,_,_) = z + isForcedBreak (_,_,_,_,Penalty _ p _) = p == (-infinity) + isForcedBreak _ = False + + +instance PointedBox ZList where + isFlagged (ZList _ b _) = isFlagged b + box (ZList _ b _) = box b + position (ZList _ b _) = position b + cumulatedW (ZList _ b _) = cumulatedW b + cumulatedY (ZList _ b _) = cumulatedY b + cumulatedZ (ZList _ b _) = cumulatedZ b + penalty (ZList _ b _) = penalty b + isForcedBreak (ZList _ b _) = isForcedBreak b + hunk ./Graphics/PDF/Typesetting.hs 85 - boxWidth (Glue w yi zi) Nothing = w - boxWidth (Glue w yi zi) (Just r) = + boxWidth (Glue w yi zi) r = hunk ./Graphics/PDF/Typesetting.hs 108 - strokeBox (Glue w yi zi) Nothing x y = return () - strokeBox (Glue w yi zi) (Just r) x y = do + strokeBox (Glue w yi zi) r x y = do hunk ./Graphics/PDF/Typesetting.hs 129 -type Text = [B] -type TextLine = [B] +type Text = [CB] +type TextLine = [CB] hunk ./Graphics/PDF/Typesetting.hs 133 -data T = T !PDFFont !PDFString +data T = T !PDFFont !PDFString deriving(Show) + +instance Box CB where + boxWidth (_,_,_,_,a) = boxWidth a + boxHeight (_,_,_,_,a) = boxHeight a + boxDescent (_,_,_,_,a) = boxDescent a + strokeBox (_,_,_,_,a) = strokeBox a + hunk ./Graphics/PDF/Typesetting.hs 158 +data BreakNode = BreakNode { totalWidth :: !PDFFloat + , totalStretch :: !PDFFloat + , totalShrink :: !PDFFloat + , demerit :: !PDFFloat + , flagged :: !Bool + , fitnessValue :: !Int + , ratio :: !PDFFloat + , previous :: Maybe (Int,Int,Int,BreakNode) + } + deriving(Show) + +type ActiveNodes = Map.Map (Int,Int,Int) BreakNode hunk ./Graphics/PDF/Typesetting.hs 171 --- | Compute the line width. A penalty width is taken into account only at the end -lineWidth :: TextLine -> (PDFFloat,PDFFloat,PDFFloat) -lineWidth [] = (0,0,0) -lineWidth [Penalty w _ _] = (w,0,0) -lineWidth (a@(B _):l) = let (w',y',z') = lineWidth l in (w' + boxWidth a (Just 0.0), y',z' ) -lineWidth ((Glue w y z):l) = let (w',y',z') = lineWidth l in (w+w',y+y',z+z') -lineWidth (a@(Penalty _ _ _):l) = lineWidth l - -adjustRatio :: TextLine -- ^ Line - -> PDFFloat -- ^ Required width - -> Maybe PDFFloat -- ^ Adjustement ratio -adjustRatio l maxw = let (w,y,z) = lineWidth l in +adjustRatio :: BreakNode + -> ZList + -> PDFFloat + -> PDFFloat +adjustRatio a l maxw = + let w = cumulatedW l - totalWidth a + penalty l + y = cumulatedY l - totalStretch a + z = cumulatedZ l - totalShrink a + in hunk ./Graphics/PDF/Typesetting.hs 181 - then Just 0.0 + then 0.0 hunk ./Graphics/PDF/Typesetting.hs 184 - if y > 0.0 then Just ((maxw - w) / y) else Nothing + if y > 0.0 then ((maxw - w) / y) else infinity hunk ./Graphics/PDF/Typesetting.hs 186 - if z > 0.0 then Just ((maxw - w) / z) else Nothing + if z > 0.0 then ((maxw - w) / z) else infinity hunk ./Graphics/PDF/Typesetting.hs 188 -badness :: Maybe PDFFloat -> PDFFloat -badness Nothing = infinity -badness (Just r) = 100.0 * abs(r)^3 +badness :: PDFFloat -> PDFFloat +badness r = if r < (-1) then infinity else 100.0 * abs(r)**3.0 hunk ./Graphics/PDF/Typesetting.hs 191 -endParagraphBoxes :: TextLine -endParagraphBoxes = [Glue 0 infinity 0,Penalty 0 (-infinity) False] +fitness :: PDFFloat -> Int +fitness r = + if r < (-0.5) + then + 0 + else if r <= (-0.5) + then + 1 + else + if r <= 1 + then + 2 + else + 3 hunk ./Graphics/PDF/Typesetting.hs 206 --- | Convert a PDF string to a Text -newText :: PDFFont -> PDFString -> Text -newText f (PDFString t) = let ws = textWidth f (toPDFString " ") in - (intersperse (Glue ws (ws/2.0) (ws/3.0)) . map (B . T f . PDFString) . B.words $ t) ++ endParagraphBoxes - +computeDemerit :: PDFFloat -- ^ adjust ratio + -> BreakNode -- ^ Flag for previous + -> ZList -- ^ Flag for current + -> Maybe(PDFFloat,Int) -- ^ Demerit for the breakpoint +computeDemerit r a z = + let b = badness r + p = penalty z + fitness' = fitness r + in + if (-1 <= r) && (r <= tolerance) + then + let fld = if isFlagged z && (flagged a) then flagged_demerit else 0.0 + fid = if fitness' /= (fitnessValue a) then fitness_demerit else 0.0 + dem = if p >= 0 + then + fld + (1.0 + b + p) ** 2.0 + else if p < 0 && p > (-infinity) + then + fld + (1.0 + b) ** 2.0 - p**2.0 + else + fld + (1.0 + b) ** 2.0 + in + Just (dem,fitness') + else + Nothing + +data ZList = ZList [CB] (PDFFloat,PDFFloat,PDFFloat,Int,B) [B] deriving(Show) + +createZList :: [B] -> ZList +createZList [] = error "List cannot be empty to create a zipper" +createZList l = ZList [] (0,0,0,1,head l) (tail l) + +theEnd :: ZList -> Bool +theEnd (ZList _ _ []) = True +theEnd _ = False + +createBreaknode :: Maybe (Int,Int,Int,BreakNode) -> ZList -> BreakNode +createBreaknode prev (ZList _ (w,y,z,_,Penalty _ _ f) _) = BreakNode w y z 0.0 f 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,a) _) = BreakNode w y z 0.0 False 0 0.0 prev + + +moveRight :: ZList -> ZList +moveRight (ZList l c@(w,y,z,p,Glue w' y' z') r) = + let w'' = w + w' + y''=y+y' + z''=z+z' + in + ZList (c:l) (w'',y'',z'',p+1,head r) (tail r) +moveRight (ZList l c@(w,y,z,p,a) r) = + let w' = boxWidth a 0.0 + w'' = w + w' + in + ZList (c:l) (w'',y,z,p+1,head r) (tail r) + +moveLeft :: ZList -> ZList +moveLeft (ZList l c r) = ZList (tail l) (head l) ((box c):r) + +fromZlist :: ZList -> [B] +fromZlist (ZList l c r) = (reverse . map box $ l) ++ [box c] ++ r + +isFeasibleBreakpoint :: ZList -> Bool +isFeasibleBreakpoint (ZList _ (_,_,_,_,Penalty _ p _) _) = p < infinity +isFeasibleBreakpoint (ZList [] _ _) = False +isFeasibleBreakpoint (ZList ((_,_,_,_,B _):_) (_,_,_,_,Glue _ _ _) _) = True +isFeasibleBreakpoint _ = False + + +endParagraphBoxes :: [B] +endParagraphBoxes = [Glue 0 infinity 0,Penalty 0 (-infinity) False] + hunk ./Graphics/PDF/Typesetting.hs 277 -displayWithBreaks :: PDFFloat -> PDFFloat -> PDFFloat -> Text -> Int -> [Int] -> Draw () -displayWithBreaks maxw x y t _ [] = do +displayWithBreaks :: PDFFloat -> PDFFloat -> [B] -> Int -> [(PDFFloat,Int)] -> Draw () +displayWithBreaks x y t _ [] = do hunk ./Graphics/PDF/Typesetting.hs 280 - r = adjustRatio t maxw - strokeBox t r x y' -displayWithBreaks maxw x y t c (a:l) = do - let (theLine,t') = splitAt (a-c) t + strokeBox t 0.0 x y' +displayWithBreaks x y t c ((ra,ba):l) = do + let (theLine,t') = splitAt (ba-c) t hunk ./Graphics/PDF/Typesetting.hs 286 - r = adjustRatio theLine maxw - strokeBox theLine r x y' - displayWithBreaks maxw x (y- h) (simplify t') a l + strokeBox theLine ra x y' + displayWithBreaks x (y- h) t' ba l + +looseness :: Int +looseness = 0 + +tolerance :: PDFFloat +tolerance = 1 + +fitness_demerit :: PDFFloat +fitness_demerit = 100 + +flagged_demerit :: PDFFloat +flagged_demerit = 100 + +getNewActiveBreakpoints :: PDFFloat -> ActiveNodes -> ZList -> ActiveNodes +getNewActiveBreakpoints maxw actives z = + if isFeasibleBreakpoint z + then + let analyzeActive key@(p,line,f) b newmap = + let r = adjustRatio b z maxw + in + if r < -1 || isForcedBreak z + then + if Map.size newmap > 1 then newmap else Map.insert key b newmap + else + let dem' = computeDemerit r b z in + case dem' of + Nothing -> Map.insert key b newmap + Just (d',f') -> + let b' = createBreaknode (Just (p,line,f,b)) z in + Map.insert key b $ Map.insert (position z,line+1,f') (b' {demerit = d',fitnessValue = f', ratio = r}) newmap + in + Map.foldWithKey analyzeActive Map.empty actives + else + actives + +genNodeList :: (Int,Int,Int,BreakNode) -> [(PDFFloat,Int)] +genNodeList b@(p,l,f,BreakNode _ _ _ _ _ _ r Nothing) = [(r,p)] +genNodeList b@(p,l,f,BreakNode _ _ _ _ _ _ r (Just previous)) = (r,p):genNodeList previous + +analyzeBoxes :: PDFFloat -> ActiveNodes -> ZList -> [(PDFFloat,Int)] +analyzeBoxes maxw actives z = + if theEnd z + then + let ((p,l,f),s) = minimumBy (\(ka,a) (kb,b) -> compare (demerit a) (demerit b)) . Map.toList $ actives in + genNodeList (p,l,f,s) + else + analyzeBoxes maxw (getNewActiveBreakpoints maxw actives z) (moveRight z) hunk ./Graphics/PDF/Typesetting.hs 336 -simplify :: Text -> Text -simplify [] = [] -simplify ((Glue _ _ _):l) = simplify l -simplify ((Penalty _ _ _):l) = simplify l -simplify l = l hunk ./Graphics/PDF/Typesetting.hs 337 +-- M.insert (0,0,1) (BreakNode 0 0 0 0) +formatText :: PDFFloat -> PDFFont -> [B] -> [(PDFFloat,Int)] +formatText maxw f boxes = + let active = Map.insert (0,0,1) (BreakNode 0 0 0 0 False 0 0.0 Nothing) Map.empty + in + tail . reverse $ analyzeBoxes maxw active (createZList boxes) + +displayFormattedText :: PDFFloat -> PDFFloat -> PDFFloat -> PDFFont -> PDFString -> Draw () +displayFormattedText x y maxw f (PDFString t) = do + let ws = textWidth f (toPDFString " ") + boxes = (intersperse (Glue ws (ws/2.0) (ws/2.0)) . map (B . T f . PDFString) . B.words $ t) ++ endParagraphBoxes + l = formatText maxw f boxes + displayWithBreaks x y boxes 1 l hunk ./Test/test.hs 19 - hunk ./Test/test.hs 112 - t = newText f (toPDFString "This is a test") - textStart = 300 - boxHeight t + boxDescent t - maxw = 100 + t = toPDFString "In olden times when wishing still helped one, there lived a king whose daughters were all beautiful; and the youngest was so beautiful that the sun itself, which has seen so much, was astonished whenever it shone in her face. Close by the king's castle lay a great dark forest, and under an old lime-tree in the forest was a well, and when the day was very warm, the king's child went out into the forest and sat down by the side of the cool fountain: and when she was bored she took a golden ball, and threw it up on high and caught it; and this ball was her favorite plaything." + textStart = 300 - getHeight f + getDescent f + maxw = 400 hunk ./Test/test.hs 121 - --displayWithBreaks maxw 10 300 t 1 [6,10,14,20,29,33] - displayWithBreaks maxw 10 300 t 1 [6] - return () + displayFormattedText 10 300 maxw f t hunk ./Graphics/PDF/Typesetting.hs 30 +import Debug.Trace hunk ./Graphics/PDF/Typesetting.hs 53 + isPenalty :: a -> Bool hunk ./Graphics/PDF/Typesetting.hs 64 + isPenalty (_,_,_,_,Penalty _ _ _) = True + isPenalty _ = False hunk ./Graphics/PDF/Typesetting.hs 78 + isPenalty (ZList _ b _) = isPenalty b hunk ./Graphics/PDF/Typesetting.hs 181 - let w = cumulatedW l - totalWidth a + penalty l + let w = cumulatedW l - totalWidth a + (if isPenalty l then boxWidth (box l) 0.0 else 0.0) hunk ./Graphics/PDF/Typesetting.hs 224 - dem = if p >= 0 - then - fld + (1.0 + b + p) ** 2.0 - else if p < 0 && p > (-infinity) + dem = if b == infinity + then + infinity + else + if p >= 0 hunk ./Graphics/PDF/Typesetting.hs 230 - fld + (1.0 + b) ** 2.0 - p**2.0 - else - fld + (1.0 + b) ** 2.0 + fld + (1.0 + b + p) ** 2.0 + else if p < 0 && p > (-infinity) + then + fld + (1.0 + b) ** 2.0 - p**2.0 + else + fld + (1.0 + b) ** 2.0 hunk ./Graphics/PDF/Typesetting.hs 243 + hunk ./Graphics/PDF/Typesetting.hs 252 +-- | We create a new breakpoint but we get the cumulated dimensions only at the next box following the break +-- since glues and penalties are removed at the beginning of a line hunk ./Graphics/PDF/Typesetting.hs 255 -createBreaknode prev (ZList _ (w,y,z,_,Penalty _ _ f) _) = BreakNode w y z 0.0 f 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,a) _) = BreakNode w y z 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,Penalty w' _ f) []) = BreakNode (w + w') (y) (z) 0.0 f 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,Glue w' y' z') []) = BreakNode (w + w') (y+y') (z+z') 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,a) []) = BreakNode (w + boxWidth a 0.0) (y) (z) 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,Penalty _ p f) _) | p == (-infinity) = BreakNode w y z 0.0 f 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,B _) _) = BreakNode w y z 0.0 False 0 0.0 prev +createBreaknode prev z = createBreaknode prev (moveRight z) hunk ./Graphics/PDF/Typesetting.hs 290 -endParagraphBoxes = [Glue 0 infinity 0,Penalty 0 (-infinity) False] +endParagraphBoxes = [Penalty 0 (infinity) False,Glue 0 infinity 0,Penalty 0 (-infinity) True] hunk ./Graphics/PDF/Typesetting.hs 303 - displayWithBreaks x (y- h) t' ba l + displayWithBreaks x (y- h) (simplify t') ba l + +simplify :: [B] -> [B] +simplify ((Glue _ _ _):l) = simplify l +simplify ((Penalty _ _ _):l) = simplify l +simplify l = l hunk ./Graphics/PDF/Typesetting.hs 322 +-- Update a feasible breakpoint remembering only the best one +type PossibleBreak = (Int,PDFFloat,BreakNode) -- Line, demerit and break node + +updateBreak :: CurrentBreaks + -> (Int,Int,PDFFloat,BreakNode) + -> CurrentBreaks +updateBreak (a,b,c,d) nb@(_,f',_,_) = + case f' of + 0 -> (updateSingle nb a,b,c,d) + 1 -> (a,updateSingle nb b,c,d) + 2 -> (a,b,updateSingle nb c,d) + 3 -> (a,b,c,updateSingle nb d) + _ -> error "impossible fitness value" + where + updateSingle (l,f,d,b) Nothing = Just (l,d,b) + updateSingle (l,f,d,b) old@(Just (l',d',b')) = if d < d' then Just (l,d,b) else old + +canAddBreaks :: [(Int,Maybe PossibleBreak)] -> Bool +canAddBreaks l = any demeritNotInfinite l + where + demeritNotInfinite (_,Nothing) = False + demeritNotInfinite (_,Just (_,d,_)) = d < infinity + +addBreaks :: Int -> [(Int,Maybe PossibleBreak)] -> ActiveNodes -> ActiveNodes +addBreaks pos br ac = foldr addABreak ac br + where + addABreak (_,Nothing) a = a + addABreak (f,Just (l,d,b)) a = Map.insert (pos,l,f) b a + +type CurrentBreaks = (Maybe PossibleBreak,Maybe PossibleBreak,Maybe PossibleBreak,Maybe PossibleBreak) + +breakList :: CurrentBreaks + -> [(Int,Maybe PossibleBreak)] +breakList (a,b,c,d) = [ (0,a) + , (1,b) + , (2,c) + , (3,d) + ] + +debug a = trace (show a) a + +-- | Check is a break point is possible +-- otherwise, if none is possible and there is only one remaining active point, +-- we force a breakpoint +updateWithNewRIfNoSolution :: PDFFloat -- ^ Old r + -> ZList -- ^ Current + -> (Int,Int,Int) + -> CurrentBreaks + -> ActiveNodes -- ^ Actives + -> (PDFFloat -> ActiveNodes -> (CurrentBreaks,ActiveNodes)) + -> (CurrentBreaks,ActiveNodes) +updateWithNewRIfNoSolution r z key newbreak newmap f = + if r < -1 || isForcedBreak z + then + if Map.size newmap > 1 then (newbreak,Map.delete key newmap) else f (-0.99) (Map.delete key newmap) + else + f r newmap + hunk ./Graphics/PDF/Typesetting.hs 382 - if isFeasibleBreakpoint z + if debug $ isFeasibleBreakpoint (trace (show . box $ z) $ z) hunk ./Graphics/PDF/Typesetting.hs 384 - let analyzeActive key@(p,line,f) b newmap = - let r = adjustRatio b z maxw + let analyzeActive key@(p,line,f) b (newbreak,newmap') = + let r' = debug $ adjustRatio b z maxw hunk ./Graphics/PDF/Typesetting.hs 387 - if r < -1 || isForcedBreak z - then - if Map.size newmap > 1 then newmap else Map.insert key b newmap - else - let dem' = computeDemerit r b z in - case dem' of - Nothing -> Map.insert key b newmap - Just (d',f') -> - let b' = createBreaknode (Just (p,line,f,b)) z in - Map.insert key b $ Map.insert (position z,line+1,f') (b' {demerit = d',fitnessValue = f', ratio = r}) newmap + updateWithNewRIfNoSolution r' z key newbreak newmap' $ + \r newmap -> let dem' = computeDemerit r b z in + case dem' of + Nothing -> (newbreak,newmap) + Just (d',f') -> + let b' = createBreaknode (Just (p,line,f,b)) z in + -- We keep only the best new break + (updateBreak newbreak (line+1,f,d',b' {demerit = d',fitnessValue = f', ratio = r}),newmap) hunk ./Graphics/PDF/Typesetting.hs 396 - Map.foldWithKey analyzeActive Map.empty actives + let (breaks',actives') = Map.foldWithKey analyzeActive ((Nothing,Nothing,Nothing,Nothing),actives) actives + -- We add the best new break to the active breaks + bl = breakList breaks' + in + if canAddBreaks bl + then + addBreaks (position z) bl actives' + else + actives' hunk ./Graphics/PDF/Typesetting.hs 412 + hunk ./Graphics/PDF/Typesetting.hs 415 - if theEnd z + if theEnd (trace (show . box $ z) $ z) hunk ./Graphics/PDF/Typesetting.hs 417 - let ((p,l,f),s) = minimumBy (\(ka,a) (kb,b) -> compare (demerit a) (demerit b)) . Map.toList $ actives in + let actives' = getNewActiveBreakpoints maxw actives z + ((p,l,f),s) = minimumBy (\(ka,a) (kb,b) -> compare (demerit a) (demerit b)) . Map.toList $ actives' in hunk ./Graphics/PDF/Typesetting.hs 433 - let ws = textWidth f (toPDFString " ") - boxes = (intersperse (Glue ws (ws/2.0) (ws/2.0)) . map (B . T f . PDFString) . B.words $ t) ++ endParagraphBoxes + let ws = textWidth f (toPDFString " ") + boxes = (intersperse (Glue ws (ws/2.0) (ws/3.0)) . map (B . T f . PDFString) . B.words $ t) ++ endParagraphBoxes hunk ./Test/test.hs 112 - t = toPDFString "In olden times when wishing still helped one, there lived a king whose daughters were all beautiful; and the youngest was so beautiful that the sun itself, which has seen so much, was astonished whenever it shone in her face. Close by the king's castle lay a great dark forest, and under an old lime-tree in the forest was a well, and when the day was very warm, the king's child went out into the forest and sat down by the side of the cool fountain: and when she was bored she took a golden ball, and threw it up on high and caught it; and this ball was her favorite plaything." + t = toPDFString . concat $ + [ + "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." + , "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure" + , "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non" + , "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + , "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." + , "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure" + , "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non" + , "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + , "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." + , "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure" + , "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non" + , "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + ] hunk ./Graphics/PDF/Typesetting.hs 20 + , txt + , paragraph + , TM + , setStyle + , endParagraph + , setHSpace + , setHStretch + , setHShrink hunk ./Graphics/PDF/Typesetting.hs 35 -import qualified Data.ByteString.Lazy.Char8 as B(words,unwords) +import qualified Data.ByteString.Lazy.Char8 as B(singleton,unwords) +import qualified Data.ByteString.Lazy as B(ByteString,null,splitWith) +import qualified Data.ByteString.Base as B(isSpaceWord8) hunk ./Graphics/PDF/Typesetting.hs 40 -import Debug.Trace +import Control.Monad.RWS + hunk ./Graphics/PDF/Typesetting.hs 84 - isForcedBreak (_,_,_,_,Penalty _ p _) = p == (-infinity) + isForcedBreak (_,_,_,_,Penalty _ p _) = p <= (-infinity) hunk ./Graphics/PDF/Typesetting.hs 119 - withNewContext $ do - setWidth 0.5 - strokeColor black - stroke $ Line x (y-3) x (y+3) + --withNewContext $ do + -- setWidth 0.5 + -- strokeColor black + -- stroke $ Line x (y-3) x (y+3) hunk ./Graphics/PDF/Typesetting.hs 125 - withNewContext $ do - setWidth 0.5 - strokeColor green - stroke $ Line x y (x+w) y - strokeColor blue - stroke $ Line (x+w) y (x+w+r*yi) y - strokeColor $ Rgb 1 1 0 - stroke $ Line (x+w) (y-2) (x+w+r*zi) (y-2) + --withNewContext $ do + -- setWidth 0.5 + -- strokeColor green + -- stroke $ Line x y (x+w) y + -- strokeColor blue + -- stroke $ Line (x+w) y (x+w+r*yi) y + -- strokeColor $ Rgb 1 1 0 + -- stroke $ Line (x+w) (y-2) (x+w+r*zi) (y-2) hunk ./Graphics/PDF/Typesetting.hs 138 - boxDescent l = minimum . map boxDescent $ l + boxDescent l = maximum . map boxDescent $ l hunk ./Graphics/PDF/Typesetting.hs 164 - withNewContext $ do - setWidth 0.5 - drawText $ text f x y s - strokeColor red - stroke $ Rectangle x (y - (getDescent f)) (x + textWidth f s) (y - getDescent f + getHeight f) + drawText $ text f x y s + --withNewContext $ do + -- setWidth 0.5 + -- drawText $ text f x y s + -- strokeColor red + -- stroke $ Rectangle x (y - (getDescent f)) (x + textWidth f s) (y - getDescent f + getHeight f) hunk ./Graphics/PDF/Typesetting.hs 175 +infix 4 =~ +(=~) :: PDFFloat -> PDFFloat -> Bool +a =~ b = abs (a-b) <= 1e-3 + hunk ./Graphics/PDF/Typesetting.hs 240 - dem = if b == infinity + dem = if b >= infinity hunk ./Graphics/PDF/Typesetting.hs 274 -createBreaknode prev (ZList _ (w,y,z,_,Penalty _ p f) _) | p == (-infinity) = BreakNode w y z 0.0 f 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,Penalty _ p f) _) | p <= (-infinity) = BreakNode w y z 0.0 f 0 0.0 prev hunk ./Graphics/PDF/Typesetting.hs 306 -endParagraphBoxes = [Penalty 0 (infinity) False,Glue 0 infinity 0,Penalty 0 (-infinity) True] +endParagraphBoxes = [Penalty 0 (infinity+1) False,Glue 0 (infinity+1) 0,Penalty 0 (-infinity -1) True] hunk ./Graphics/PDF/Typesetting.hs 312 - strokeBox t 0.0 x y' + strokeBox (simplify t) 0.0 x y' hunk ./Graphics/PDF/Typesetting.hs 318 - strokeBox theLine ra x y' - displayWithBreaks x (y- h) (simplify t') ba l + strokeBox (simplify theLine) ra x y' + displayWithBreaks x (y- h) t' ba l hunk ./Graphics/PDF/Typesetting.hs 339 -type PossibleBreak = (Int,PDFFloat,BreakNode) -- Line, demerit and break node +type PossibleBreak = ActiveNodes -- Line, demerit and break node hunk ./Graphics/PDF/Typesetting.hs 341 -updateBreak :: CurrentBreaks - -> (Int,Int,PDFFloat,BreakNode) - -> CurrentBreaks -updateBreak (a,b,c,d) nb@(_,f',_,_) = - case f' of - 0 -> (updateSingle nb a,b,c,d) - 1 -> (a,updateSingle nb b,c,d) - 2 -> (a,b,updateSingle nb c,d) - 3 -> (a,b,c,updateSingle nb d) - _ -> error "impossible fitness value" - where - updateSingle (l,f,d,b) Nothing = Just (l,d,b) - updateSingle (l,f,d,b) old@(Just (l',d',b')) = if d < d' then Just (l,d,b) else old - -canAddBreaks :: [(Int,Maybe PossibleBreak)] -> Bool -canAddBreaks l = any demeritNotInfinite l - where - demeritNotInfinite (_,Nothing) = False - demeritNotInfinite (_,Just (_,d,_)) = d < infinity +updateBreak :: BreakNode + -> BreakNode + -> BreakNode +updateBreak a b = if demerit a < demerit b then a else b hunk ./Graphics/PDF/Typesetting.hs 346 -addBreaks :: Int -> [(Int,Maybe PossibleBreak)] -> ActiveNodes -> ActiveNodes -addBreaks pos br ac = foldr addABreak ac br - where - addABreak (_,Nothing) a = a - addABreak (f,Just (l,d,b)) a = Map.insert (pos,l,f) b a + +addBreaks :: ActiveNodes -> ActiveNodes -> ActiveNodes +addBreaks a b = Map.union (Map.filter (\x -> demerit x < infinity) a) b hunk ./Graphics/PDF/Typesetting.hs 350 -type CurrentBreaks = (Maybe PossibleBreak,Maybe PossibleBreak,Maybe PossibleBreak,Maybe PossibleBreak) - -breakList :: CurrentBreaks - -> [(Int,Maybe PossibleBreak)] -breakList (a,b,c,d) = [ (0,a) - , (1,b) - , (2,c) - , (3,d) - ] - -debug a = trace (show a) a hunk ./Graphics/PDF/Typesetting.hs 357 - -> CurrentBreaks + -> PossibleBreak hunk ./Graphics/PDF/Typesetting.hs 359 - -> (PDFFloat -> ActiveNodes -> (CurrentBreaks,ActiveNodes)) - -> (CurrentBreaks,ActiveNodes) + -> (PDFFloat -> ActiveNodes -> (PossibleBreak,ActiveNodes)) + -> (PossibleBreak,ActiveNodes) hunk ./Graphics/PDF/Typesetting.hs 362 - if r < -1 || isForcedBreak z + if r < -1 hunk ./Graphics/PDF/Typesetting.hs 364 - if Map.size newmap > 1 then (newbreak,Map.delete key newmap) else f (-0.99) (Map.delete key newmap) - else - f r newmap + --if Map.size newmap > 1 then (newbreak,Map.delete key newmap) else f (-0.99) (Map.delete key newmap) + f (-0.99) (Map.delete key newmap) + else if isForcedBreak z + then + f r (Map.delete key newmap) + else + f r newmap hunk ./Graphics/PDF/Typesetting.hs 374 - if debug $ isFeasibleBreakpoint (trace (show . box $ z) $ z) + if isFeasibleBreakpoint z hunk ./Graphics/PDF/Typesetting.hs 377 - let r' = debug $ adjustRatio b z maxw + let r' = adjustRatio b z maxw hunk ./Graphics/PDF/Typesetting.hs 386 - (updateBreak newbreak (line+1,f,d',b' {demerit = d',fitnessValue = f', ratio = r}),newmap) + (Map.insertWith updateBreak (position z,line+1,f') (b' {demerit = d',fitnessValue = f', ratio = r}) newbreak ,newmap) hunk ./Graphics/PDF/Typesetting.hs 388 - let (breaks',actives') = Map.foldWithKey analyzeActive ((Nothing,Nothing,Nothing,Nothing),actives) actives - -- We add the best new break to the active breaks - bl = breakList breaks' + let (breaks',actives') = Map.foldWithKey analyzeActive (Map.empty,actives) actives + dmin = minimum . map demerit . Map.elems $ breaks' hunk ./Graphics/PDF/Typesetting.hs 391 - if canAddBreaks bl - then - addBreaks (position z) bl actives' - else - actives' + addBreaks (Map.filter (\x -> demerit x < dmin + fitness_demerit) breaks') actives' hunk ./Graphics/PDF/Typesetting.hs 402 - if theEnd (trace (show . box $ z) $ z) + if theEnd z hunk ./Graphics/PDF/Typesetting.hs 412 -formatText :: PDFFloat -> PDFFont -> [B] -> [(PDFFloat,Int)] -formatText maxw f boxes = +formatText :: PDFFloat -> [B] -> [(PDFFloat,Int)] +formatText maxw boxes = hunk ./Graphics/PDF/Typesetting.hs 418 -displayFormattedText :: PDFFloat -> PDFFloat -> PDFFloat -> PDFFont -> PDFString -> Draw () -displayFormattedText x y maxw f (PDFString t) = do - let ws = textWidth f (toPDFString " ") - boxes = (intersperse (Glue ws (ws/2.0) (ws/3.0)) . map (B . T f . PDFString) . B.words $ t) ++ endParagraphBoxes - l = formatText maxw f boxes +-- | Cut into words but keep spaces at beginning and end +getWords :: B.ByteString -> [B.ByteString] +getWords = B.splitWith B.isSpaceWord8 +{-# INLINE getWords #-} + +-- | Convert each string to a box and add the glue for the spaces (with beginning and ending space) +addSpacesToLine :: PDFFont -> B -> [B.ByteString] -> [B] +addSpacesToLine _ _ [] = [] +addSpacesToLine f g [x] | B.null x = [g] + | otherwise = [B . T f . PDFString $ x] +addSpacesToLine f g (x:xs) | B.null x = g : addSpacesToLine f g xs + | otherwise = (B . T f . PDFString $ x) : g : addSpacesToLine f g xs + +splitText :: PDFString -> TM () +splitText (PDFString t) = do + TMState f h y z <- get + let ws = (textWidth f (toPDFString " ") ) * h + tell $ addSpacesToLine f (Glue (ws) (y*ws/2.0) (z*ws/3.0)) . getWords $ t + + +endParagraph :: TM () +endParagraph = tell endParagraphBoxes + +displayFormattedText :: PDFFloat -> PDFFloat -> PDFFloat -> TM a -> Draw a +displayFormattedText x y maxw t = do + let (a, _, boxes) = (runRWS . unTM $ t) () (TMState (PDFFont Times_Roman 10) 1.0 1.0 1.0) + l = formatText maxw boxes hunk ./Graphics/PDF/Typesetting.hs 446 + return a + +data TMState = TMState { tmFont :: !PDFFont + , hspcWidth :: !PDFFloat -- Scaling factor for normal space size + , hStretch :: !PDFFloat + , hShrink :: !PDFFloat + } + +newtype TM a = TM { unTM :: RWS () [B] TMState a} deriving(Monad,MonadWriter [B], MonadState TMState, Functor) + +setStyle :: PDFFont -> TM () +setStyle f = modifyStrict $ \s -> s {tmFont = f} + +-- | Scale factor for the space size +setHSpace :: PDFFloat -> TM () +setHSpace h = modifyStrict $ \s -> s{ hspcWidth = h } + +-- | Scale factor for the strechability of spaces +setHStretch :: PDFFloat -> TM () +setHStretch h = modifyStrict $ \s -> s{ hStretch = h } + +-- | Scale factor for the shrinkability of spaces +setHShrink :: PDFFloat -> TM () +setHShrink h = modifyStrict $ \s -> s{ hShrink = h } + +paragraph :: String -> TM () +paragraph t = do + splitText (toPDFString t) + endParagraph + +txt :: String -> TM () +txt t = do + splitText (toPDFString t) + hunk ./Test/test.hs 111 - --t = newText f (toPDFString "This is a test for the formatting and layout algorithm. I am sure it won't work.") - t = toPDFString . concat $ - [ - "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." - , "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure" - , "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non" - , "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - , "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." - , "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure" - , "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non" - , "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - , "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." - , "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure" - , "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non" - , "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - ] + debugText = do + setHStretch 3.0 + txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor " + setStyle (PDFFont Times_Bold 12) + txt $ "incididunt ut labore et dolore magna aliqua." + setStyle (PDFFont Times_Roman 10) + txt $ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " + txt $ "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " + endParagraph + txt $ "Excepteur sint occaecat cupidatat non " + txt $ "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + endParagraph + myText = do + setHStretch 3 + txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + setStyle (PDFFont Times_Bold 12) + txt $ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " + setStyle (PDFFont Times_Roman 10) + txt $ "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " + txt $ "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + endParagraph + txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + txt $ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " + txt $ "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " + txt $ "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + endParagraph + txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + txt $ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " + txt $ "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " + txt $ "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + endParagraph hunk ./Test/test.hs 147 - stroke $ Rectangle 10 300 (10+maxw) 0 + stroke $ Rectangle 10 0 (10+maxw) 300 hunk ./Test/test.hs 150 - displayFormattedText 10 300 maxw f t + displayFormattedText 10 300 maxw myText hunk ./Graphics/PDF/Colors.hs 35 +import Data.ByteString.Lazy.Char8(singleton,pack) +import Control.Monad.Writer +import qualified Data.ByteString.Lazy as B(concat) hunk ./Graphics/PDF/Colors.hs 63 - writeCmd ("\n/" ++ newName ++ " gs") + tell . B.concat$[ pack "\n/" + , toByteString newName + , pack " gs" + ] hunk ./Graphics/PDF/Colors.hs 74 - writeCmd ("\n/" ++ newName ++ " gs") + tell . B.concat$[ pack "\n/" + , toByteString newName + , pack " gs" + ] hunk ./Graphics/PDF/Colors.hs 81 -setRGBColorSpace = writeCmd "\n/DeviceRGB CS\n/DeviceRGB cs\n" +setRGBColorSpace = tell . pack $ "\n/DeviceRGB CS\n/DeviceRGB cs\n" hunk ./Graphics/PDF/Colors.hs 89 - writeCmd $ "\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " rg" + tell . B.concat$[ pack "\n" + , toPDF r + , singleton ' ' + , toPDF g + , singleton ' ' + , toPDF b + , pack " rg" + ] + hunk ./Graphics/PDF/Colors.hs 100 - writeCmd $ "\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " rg" + tell . B.concat$[ pack "\n" + , toPDF r + , singleton ' ' + , toPDF g + , singleton ' ' + , toPDF b + , pack " rg" + ] hunk ./Graphics/PDF/Colors.hs 113 - writeCmd $ "\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " RG" + tell . B.concat$[ pack "\n" + , toPDF r + , singleton ' ' + , toPDF g + , singleton ' ' + , toPDF b + , pack " RG" + ] hunk ./Graphics/PDF/Colors.hs 123 - writeCmd $ "\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " RG" + tell . B.concat$[ pack "\n" + , toPDF r + , singleton ' ' + , toPDF g + , singleton ' ' + , toPDF b + , pack " RG" + ] hunk ./Graphics/PDF/Coordinates.hs 27 - +import Data.ByteString.Lazy.Char8(singleton,pack) +import Control.Monad.Writer +import qualified Data.ByteString.Lazy as B(concat) hunk ./Graphics/PDF/Coordinates.hs 69 - writeCmd $ "\n" ++ show (a) ++ " " ++ show (b) ++ " " ++ show (c) ++ " " ++ show (d) ++ " " ++ show (e) ++ " " ++ show (f) ++ " cm" - + tell . B.concat$[ singleton '\n' + , toPDF a + , singleton ' ' + , toPDF b + , singleton ' ' + , toPDF c + , singleton ' ' + , toPDF d + , singleton ' ' + , toPDF e + , singleton ' ' + , toPDF f + , pack " cm" + ] + hunk ./Graphics/PDF/Draw.hs 22 - , writeCmd +-- , writeCmd hunk ./Graphics/PDF/Draw.hs 78 +import Data.ByteString.Lazy.Char8(pack) hunk ./Graphics/PDF/Draw.hs 171 -writeCmd :: (MonadWriter B.ByteString m) => String -> m () -writeCmd = tell . toByteString +--writeCmd :: (MonadWriter B.ByteString m) => String -> m () +--writeCmd = tell . toByteString hunk ./Graphics/PDF/Draw.hs 198 - writeCmd "\nq" + tell . pack $ "\nq" hunk ./Graphics/PDF/Draw.hs 200 - writeCmd "\nQ" + tell . pack $ "\nQ" hunk ./Graphics/PDF/Draw.hs 226 - writeCmd ("\n/" ++ newName ++ " Do") + tell . B.concat $ [ pack "\n/" + , toByteString newName + , pack " Do" + ] hunk ./Graphics/PDF/LowLevel/Types.hs 28 +import Foreign.Ptr(Ptr) +import Data.Word(Word8) +import Data.ByteString.Base(createAndTrim,inlinePerformIO,LazyByteString(..)) + hunk ./Graphics/PDF/LowLevel/Types.hs 63 - toPDF (PDFInteger a) = toByteString (show a) - + toPDF (PDFInteger a) = LPS [inlinePerformIO (createAndTrim 12 (cshortToString a))] + +instance PdfObject Int where + toPDF a = LPS [inlinePerformIO (createAndTrim 12 (cshortToString a))] + hunk ./Graphics/PDF/LowLevel/Types.hs 69 - toPDF (PDFLength a) = toByteString (show a) + toPDF (PDFLength a) = toByteString (show a) hunk ./Graphics/PDF/LowLevel/Types.hs 71 +foreign import ccall "conversion.h c_floatToString" cfloatToString :: Double -> Ptr Word8 -> IO Int +foreign import ccall "conversion.h c_shortToString" cshortToString :: Int -> Ptr Word8 -> IO Int + hunk ./Graphics/PDF/LowLevel/Types.hs 75 - toPDF (PDFFloat a) = toByteString (show a) + toPDF (PDFFloat a) = LPS [inlinePerformIO (createAndTrim 12 (cfloatToString a))] + +instance PdfObject Double where + toPDF a = LPS [inlinePerformIO (createAndTrim 12 (cfloatToString a))] hunk ./Graphics/PDF/LowLevel/Types.hs 148 -instance PdfObject PDFArray where - toPDF l = B.concat $ (lbracket:intersperse bspace (map toPDF l)) ++ [bspace] ++ [rbracket] +instance PdfObject a => PdfObject [a] where + toPDF l = B.concat $ (lbracket:intersperse bspace (map toPDF l)) ++ [bspace] ++ [rbracket] hunk ./Graphics/PDF/Pattern.hs 32 +import Data.ByteString.Lazy.Char8(singleton,pack) +import Control.Monad.Writer +import qualified Data.ByteString.Lazy as B(concat) hunk ./Graphics/PDF/Pattern.hs 106 - writeCmd ("\n/Pattern cs") - writeCmd ("\n/" ++ newName ++ " scn") + tell . pack $ ("\n/Pattern cs") + tell . B.concat$[ pack "\n/" + , toByteString newName + , pack " scn" + ] hunk ./Graphics/PDF/Pattern.hs 118 - writeCmd ("\n/Pattern CS") - writeCmd ("\n/" ++ newName ++ " SCN") + tell . pack $ ("\n/Pattern CS") + tell . B.concat$[ pack "\n/" + , toByteString newName + , pack " SCN" + ] hunk ./Graphics/PDF/Pattern.hs 135 - writeCmd ("\n/" ++ newColorName ++ " cs") - writeCmd ("\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " /" ++ newName ++ " scn") + tell . B.concat$[ pack "\n/" + , toByteString newColorName + , pack " cs" + ] + tell . B.concat$[ singleton '\n' + , toPDF r + , singleton ' ' + , toPDF g + , singleton ' ' + , toPDF b + , singleton ' ' + , pack " /" + , toByteString newName + , pack " scn" + ] hunk ./Graphics/PDF/Pattern.hs 160 - writeCmd ("\n/" ++ newColorName ++ " CS") - writeCmd ("\n" ++ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " /" ++ newName ++ " SCN") - + tell . B.concat$[ pack "\n/" + , toByteString newColorName + , pack " CS" + ] + tell . B.concat$[ singleton '\n' + , toPDF r + , singleton ' ' + , toPDF g + , singleton ' ' + , toPDF b + , singleton ' ' + , pack " /" + , toByteString newName + , pack " SCN" + ] hunk ./Graphics/PDF/Shading.hs 23 +import Data.ByteString.Lazy.Char8(singleton,pack) +import Control.Monad.Writer +import qualified Data.ByteString.Lazy as B(concat) hunk ./Graphics/PDF/Shading.hs 33 - writeCmd ("\n/" ++ newName ++ " sh") + tell . B.concat$[ pack "\n/" + , toByteString newName + , pack " sh" + ] hunk ./Graphics/PDF/Shapes.hs 56 -import Data.List(intersperse) +import Data.ByteString.Lazy.Char8(singleton,pack) +import Control.Monad.Writer +import qualified Data.ByteString.Lazy as B(concat) hunk ./Graphics/PDF/Shapes.hs 153 -setWidth w = writeCmd $ "\n " ++ (show w) ++ " w" +setWidth w = tell . B.concat$[ pack "\n" + , toPDF w + , pack " w" + ] hunk ./Graphics/PDF/Shapes.hs 160 -setMiterLimit w = writeCmd $ "\n " ++ (show w) ++ " M" +setMiterLimit w = tell . B.concat$[ pack "\n" + , toPDF w + , pack " M" + ] hunk ./Graphics/PDF/Shapes.hs 179 -setLineCap w = writeCmd $ "\n " ++ (show . fromEnum $ w) ++ " J" +setLineCap w = tell . B.concat$[ pack "\n " + , toPDF (fromEnum w) + , pack " J" + ] hunk ./Graphics/PDF/Shapes.hs 186 -setLineJoin w = writeCmd $ "\n " ++ (show . fromEnum $ w) ++ " j" +setLineJoin w = tell . B.concat$[ pack "\n " + , toPDF (fromEnum w) + , pack " j" + ] hunk ./Graphics/PDF/Shapes.hs 195 -setDash (DashPattern a p) = writeCmd $ "\n " ++ show a ++ " " ++ (show p) ++ " d" +setDash (DashPattern a p) = + tell . B.concat$[ pack "\n " + , toPDF a + , singleton ' ' + , toPDF p + , pack " d" + ] hunk ./Graphics/PDF/Shapes.hs 215 -closePath = writeCmd $ "\nh" +closePath = tell . pack $ "\nh" hunk ./Graphics/PDF/Shapes.hs 228 -addBezierCubic x1 y1 x2 y2 x3 y3 = writeCmd $ "\n" ++ (concat . intersperse " ". map show $ [x1,y1,x2,y2,x3,y3]) ++ " c" - +addBezierCubic x1 y1 x2 y2 x3 y3 = + tell . B.concat$[ pack "\n" + , toPDF x1 + , singleton ' ' + , toPDF y1 + , singleton ' ' + , toPDF x2 + , singleton ' ' + , toPDF y2 + , singleton ' ' + , toPDF x3 + , singleton ' ' + , toPDF y3 + , pack " c" + ] + hunk ./Graphics/PDF/Shapes.hs 248 -moveto x y = writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " m" +moveto x y = + tell . B.concat$[ pack "\n" + , toPDF x + , singleton ' ' + , toPDF y + , pack " m" + ] hunk ./Graphics/PDF/Shapes.hs 260 -lineto x y = writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " l s" - +lineto x y = + tell . B.concat$[ pack "\n" + , toPDF x + , singleton ' ' + , toPDF y + , pack " l s" + ] + hunk ./Graphics/PDF/Shapes.hs 272 -addLineToPath x y = writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " l" +addLineToPath x y = + tell . B.concat$[ pack "\n" + , toPDF x + , singleton ' ' + , toPDF y + , pack " l" + ] + hunk ./Graphics/PDF/Shapes.hs 289 - mapM_ (\(x,y) -> writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " l") (tail l) + mapM_ (\(x,y) -> addLineToPath x y) (tail l) hunk ./Graphics/PDF/Shapes.hs 293 -strokePath = writeCmd "\nS" +strokePath = tell . pack $ "\nS" hunk ./Graphics/PDF/Shapes.hs 297 -fillPath = writeCmd "\nf" +fillPath = tell . pack $ "\nf" hunk ./Graphics/PDF/Shapes.hs 301 -fillAndStrokePath = writeCmd "\nB" +fillAndStrokePath = tell . pack $ "\nB" hunk ./Graphics/PDF/Shapes.hs 305 -setAsClipPathEO = writeCmd "\nW* n" +setAsClipPathEO = tell . pack $ "\nW* n" hunk ./Graphics/PDF/Shapes.hs 309 -setAsClipPath = writeCmd "\nW n" +setAsClipPath = tell . pack $ "\nW n" hunk ./Graphics/PDF/Shapes.hs 313 -fillPathEO = writeCmd "\nf*" +fillPathEO = tell . pack $ "\nf*" hunk ./Graphics/PDF/Shapes.hs 317 -fillAndStrokePathEO = writeCmd "\nB*" +fillAndStrokePathEO = tell . pack $ "\nB*" hunk ./Graphics/PDF/Text.hs 56 +import Data.ByteString.Lazy.Char8(singleton,pack) hunk ./Graphics/PDF/Text.hs 158 - writeCmd $ "\n/" ++ (show n) ++ " " ++ (show size) ++ " Tf" + tell . B.concat$[ pack "\n/" + , toByteString (show n) + , singleton ' ' + , toPDF size + , pack " Tf" + ] + hunk ./Graphics/PDF/Text.hs 172 - writeCmd "\nBT" + tell . pack $ "\nBT" hunk ./Graphics/PDF/Text.hs 174 - writeCmd "\nET" + tell . pack $ "\nET" hunk ./Graphics/PDF/Text.hs 183 -textStart x y = writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " Td" +textStart x y = tell . B.concat $ [ singleton '\n' + , toPDF x + , singleton ' ' + , toPDF y + , pack " Td" + ] + --writeCmd $ "\n" ++ (show x) ++ " " ++ (show y) ++ " Td" hunk ./Graphics/PDF/Text.hs 196 - writeCmd " Tj" + tell . pack $ " Tj" hunk ./Graphics/PDF/Text.hs 201 -startNewLine = writeCmd "\nT*" +startNewLine = tell . pack $ "\nT*" hunk ./Graphics/PDF/Text.hs 207 - writeCmd $ "\n" ++ (show v) ++ " TL" + tell . B.concat $ [ singleton '\n' + , toPDF v + , pack " TL" + ] hunk ./Graphics/PDF/Text.hs 216 - writeCmd $ "\n" ++ (show v) ++ " Tc" + tell . B.concat $ [ singleton '\n' + , toPDF v + , pack " Tc" + ] hunk ./Graphics/PDF/Text.hs 225 - writeCmd $ "\n" ++ (show v) ++ " Tw" + tell . B.concat $ [ singleton '\n' + , toPDF v + , pack " Tw" + ] hunk ./Graphics/PDF/Text.hs 234 - writeCmd $ "\n" ++ (show v) ++ " Tz" + tell . B.concat $ [ singleton '\n' + , toPDF v + , pack " Tz" + ] hunk ./Graphics/PDF/Text.hs 241 -renderMode v = writeCmd $ "\n" ++ (show . fromEnum $ v) ++ " Tr" +renderMode v = + tell . B.concat $ [ singleton '\n' + , toPDF (fromEnum v) + , pack " Tr" + ] hunk ./Graphics/PDF/Text.hs 251 - writeCmd $ "\n" ++ (show v) ++ " Ts" + tell . B.concat $ [ singleton '\n' + , toPDF v + , pack " Ts" + ] hunk ./Graphics/PDF/Text.hs 259 - writeCmd $ "\n" ++ show (a) ++ " " ++ show (b) ++ " " ++ show (c) ++ " " ++ show (d) ++ " " ++ show (e) ++ " " ++ show (f) ++ " Tm" - + tell . B.concat$[ singleton '\n' + , toPDF a + , singleton ' ' + , toPDF b + , singleton ' ' + , toPDF c + , singleton ' ' + , toPDF d + , singleton ' ' + , toPDF e + , singleton ' ' + , toPDF f + , pack " Tm" + ] + hunk ./Graphics/PDF/Typesetting.hs 35 -import qualified Data.ByteString.Lazy.Char8 as B(singleton,unwords) +import qualified Data.ByteString.Lazy.Char8 as B(unwords) hunk ./Graphics/PDF/Typesetting.hs 41 +import Data.ByteString.Lazy.Char8(pack) + hunk ./Graphics/PDF/Typesetting.hs 259 -data ZList = ZList [CB] (PDFFloat,PDFFloat,PDFFloat,Int,B) [B] deriving(Show) +data MaybeCB = NoCB + | OneCB !CB + deriving(Show) + +data ZList = ZList (MaybeCB) (PDFFloat,PDFFloat,PDFFloat,Int,B) [B] deriving(Show) hunk ./Graphics/PDF/Typesetting.hs 268 -createZList l = ZList [] (0,0,0,1,head l) (tail l) +createZList l = ZList NoCB (0,0,0,1,head l) (tail l) hunk ./Graphics/PDF/Typesetting.hs 291 - ZList (c:l) (w'',y'',z'',p+1,head r) (tail r) + ZList (OneCB c) (w'',y'',z'',p+1,head r) (tail r) hunk ./Graphics/PDF/Typesetting.hs 296 - ZList (c:l) (w'',y,z,p+1,head r) (tail r) + ZList (OneCB c) (w'',y,z,p+1,head r) (tail r) hunk ./Graphics/PDF/Typesetting.hs 298 -moveLeft :: ZList -> ZList -moveLeft (ZList l c r) = ZList (tail l) (head l) ((box c):r) +--moveLeft :: ZList -> ZList +--moveLeft (ZList l c r) = ZList (tail l) (head l) ((box c):r) hunk ./Graphics/PDF/Typesetting.hs 301 -fromZlist :: ZList -> [B] -fromZlist (ZList l c r) = (reverse . map box $ l) ++ [box c] ++ r +--fromZlist :: ZList -> [B] +--fromZlist (ZList l c r) = (reverse . map box $ l) ++ [box c] ++ r hunk ./Graphics/PDF/Typesetting.hs 306 -isFeasibleBreakpoint (ZList [] _ _) = False -isFeasibleBreakpoint (ZList ((_,_,_,_,B _):_) (_,_,_,_,Glue _ _ _) _) = True +isFeasibleBreakpoint (ZList NoCB _ _) = False +isFeasibleBreakpoint (ZList (OneCB (_,_,_,_,B _)) (_,_,_,_,Glue _ _ _) _) = True hunk ./HPDF.cabal 17 + c/conversion.h hunk ./HPDF.cabal 26 + c/conversion.c hunk ./HPDF.cabal 30 + conversion.h hunk ./Test/Makefile 2 - ghc -o test -ffi -cpp -Wall -funbox-strict-fields -fglasgow-exts -O2 -hidir interfaces -odir bin -optc-I../c -i.. ../c/metrics.c --make test.hs + ghc -o test -ffi -cpp -Wall -funbox-strict-fields -fglasgow-exts -O2 -hidir interfaces -odir bin -optc-I../c -i.. ../c/metrics.c ../c/conversion.c --make test.hs + +profile: + ghc -o test -prof -auto-all -ffi -cpp -Wall -funbox-strict-fields -fglasgow-exts -O2 -hidir interfaces -odir bin -optc-I../c -i.. ../c/metrics.c ../c/conversion.c --make test.hs + +runprof: + ./test +RTS -p hunk ./Test/test.hs 123 - myText = do - setHStretch 3 - txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " - setStyle (PDFFont Times_Bold 12) - txt $ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " - setStyle (PDFFont Times_Roman 10) - txt $ "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " - txt $ "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - endParagraph + par = do hunk ./Test/test.hs 129 + myText = do + setHStretch 3 hunk ./Test/test.hs 132 + setStyle (PDFFont Times_Bold 12) hunk ./Test/test.hs 134 + setStyle (PDFFont Times_Roman 10) hunk ./Test/test.hs 138 + -- Duplicate paragraph four times + mapM_ (const par) [1..1000] hunk ./Test/test.hs 202 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString $ "alpheccar"}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar"}) rect $ do addfile ./c/conversion.c hunk ./c/conversion.c 1 - +#include +#include +#include +#include "conversion.h" + + +short c_floatToString(double f,char* s) +{ + sprintf(s,"%.5f",f); + return(strlen(s)); +} + +short c_shortToString(short d,char* s) +{ + sprintf(s,"%d",d); + return(strlen(s)); +} addfile ./c/conversion.h hunk ./c/conversion.h 1 +#ifndef _CONVERSION_H_ +#define _CONVERSION_H_ +extern short c_floatToString(double f,char* s); +extern short c_shortToString(short d,char* s); +#endif hunk ./Graphics/PDF/Text.hs 57 +import Data.List(foldl') hunk ./Graphics/PDF/Text.hs 81 -textWidth (PDFFont n s) (PDFString t) = let w = sum . map (cgetAdvance (fromEnum n)) . B.unpack $ t in +textWidth (PDFFont n s) (PDFString t) = let w = foldl' (\a b -> a + cgetAdvance (fromEnum n) b) 0 . B.unpack $ t in hunk ./Graphics/PDF/Text.hs 84 - trueSize s (w + (sum . map getKern $ [(fromEnum n,ca,cb) | (ca,cb) <- B.zip t (B.tail t)])) + trueSize s (w + (foldl' (\a b -> a + getKern b) 0 $ [(fromEnum n,ca,cb) | (ca,cb) <- B.zip t (B.tail t)])) hunk ./Graphics/PDF/Typesetting.hs 44 - hunk ./Graphics/PDF/Typesetting.hs 190 - -type ActiveNodes = Map.Map (Int,Int,Int) BreakNode - + hunk ./Graphics/PDF/Typesetting.hs 226 -computeDemerit :: PDFFloat -- ^ adjust ratio +computeDemerit :: Bool + -> PDFFloat -- ^ adjust ratio hunk ./Graphics/PDF/Typesetting.hs 231 -computeDemerit r a z = +computeDemerit sndPass r a z = hunk ./Graphics/PDF/Typesetting.hs 235 + tolerance = if sndPass then 3.0 else 1.0 hunk ./Graphics/PDF/Typesetting.hs 316 - let y' = y + boxDescent t - boxHeight t - strokeBox (simplify t) 0.0 x y' + unless (null t) $ do + let y' = y + boxDescent t - boxHeight t + strokeBox (simplify t) 0.0 x y' hunk ./Graphics/PDF/Typesetting.hs 321 - h = boxHeight theLine - d = boxDescent theLine - y' = y + d - h - strokeBox (simplify theLine) ra x y' - displayWithBreaks x (y- h) t' ba l + unless (null theLine) $ do + let h = boxHeight theLine + d = boxDescent theLine + y' = y + d - h + strokeBox (simplify theLine) ra x y' + displayWithBreaks x (y- h) t' ba l hunk ./Graphics/PDF/Typesetting.hs 333 -looseness :: Int -looseness = 0 - -tolerance :: PDFFloat -tolerance = 1 - hunk ./Graphics/PDF/Typesetting.hs 341 +type ActiveNodes = Map.Map (Int,Int,Int) BreakNode hunk ./Graphics/PDF/Typesetting.hs 356 -updateWithNewRIfNoSolution :: PDFFloat -- ^ Old r +updateWithNewRIfNoSolution :: Bool + -> PDFFloat -- ^ Old r hunk ./Graphics/PDF/Typesetting.hs 364 -updateWithNewRIfNoSolution r z key newbreak newmap f = +updateWithNewRIfNoSolution sndPass r z key newbreak newmap f = hunk ./Graphics/PDF/Typesetting.hs 368 - f (-0.99) (Map.delete key newmap) + if sndPass + then + f (-0.99) (Map.delete key newmap) + else + (newbreak,Map.delete key newmap) hunk ./Graphics/PDF/Typesetting.hs 379 -getNewActiveBreakpoints :: PDFFloat -> ActiveNodes -> ZList -> ActiveNodes -getNewActiveBreakpoints maxw actives z = +getNewActiveBreakpoints :: Bool -> PDFFloat -> ActiveNodes -> ZList -> (PossibleBreak,ActiveNodes) +getNewActiveBreakpoints sndPass maxw actives z = hunk ./Graphics/PDF/Typesetting.hs 386 - updateWithNewRIfNoSolution r' z key newbreak newmap' $ - \r newmap -> let dem' = computeDemerit r b z in + updateWithNewRIfNoSolution sndPass r' z key newbreak newmap' $ + \r newmap -> let dem' = computeDemerit sndPass r b z in hunk ./Graphics/PDF/Typesetting.hs 398 - addBreaks (Map.filter (\x -> demerit x < dmin + fitness_demerit) breaks') actives' + (Map.filter (\x -> demerit x < dmin + fitness_demerit) breaks', actives') hunk ./Graphics/PDF/Typesetting.hs 400 - actives + (Map.empty,actives ) hunk ./Graphics/PDF/Typesetting.hs 407 -analyzeBoxes :: PDFFloat -> ActiveNodes -> ZList -> [(PDFFloat,Int)] -analyzeBoxes maxw actives z = - if theEnd z +analyzeBoxes :: Bool -> PDFFloat -> ActiveNodes -> ZList -> [(PDFFloat,Int)] +analyzeBoxes pass maxw actives z = + let getMinBreak b' = (\((x,y,z),w) -> (x,y,z,w)) . minimumBy (\(ka,a) (kb,b) -> compare (demerit a) (demerit b)) . Map.toList $ b' + (breaks',actives') = getNewActiveBreakpoints pass maxw actives z + newActives = Map.union breaks' actives' + getRightOrderNodeList = tail . reverse . genNodeList + getKey (a,b,c,_) = (a,b,c) + getNode (_,_,_,BreakNode a b c d e f r _) = BreakNode a b c d e f r Nothing + in + -- If forced breakpoint of no bearkpoint found + if Map.null actives' hunk ./Graphics/PDF/Typesetting.hs 419 - let actives' = getNewActiveBreakpoints maxw actives z - ((p,l,f),s) = minimumBy (\(ka,a) (kb,b) -> compare (demerit a) (demerit b)) . Map.toList $ actives' in - genNodeList (p,l,f,s) + -- If no breakpoint found + if Map.null breaks' + then + -- Second pass analysis + analyzeBoxes True maxw actives z + else + -- Forced breakpoint then we gen a list from it and continue the analysis + let minBreak = getMinBreak breaks' in + if theEnd z + then + getRightOrderNodeList minBreak + else + getRightOrderNodeList minBreak ++ analyzeBoxes pass maxw (Map.insert (getKey minBreak) (getNode minBreak) Map.empty) (moveRight z) + -- Normal feasible breakpoint hunk ./Graphics/PDF/Typesetting.hs 434 - analyzeBoxes maxw (getNewActiveBreakpoints maxw actives z) (moveRight z) - + let minBreak = getMinBreak breaks' in + -- If the end it must be a possible breakpoint + -- We should NEVER reach this part. The end should always be a forced breakpoint + if theEnd z + then + getRightOrderNodeList minBreak + else + -- We continue the analysis + analyzeBoxes pass maxw newActives (moveRight z) hunk ./Graphics/PDF/Typesetting.hs 449 - tail . reverse $ analyzeBoxes maxw active (createZList boxes) + analyzeBoxes False maxw active (createZList boxes) hunk ./Graphics/PDF.hs 88 -createStreams :: [(Int, (Maybe (PDFReference PDFPage),Draw ()))] -> PDF () -createStreams l = mapM_ addStream l +createStreams :: PDF () +createStreams = do + ls <- gets streams >>= return . IM.toList + modifyStrict $ \s -> s {streams = IM.empty} + mapM_ addStream ls hunk ./Graphics/PDF.hs 143 - ls <- gets streams - createStreams . IM.toList $ ls + -- Save streams to the object dictionary so that they are saved in the PDF document + createStreams hunk ./Graphics/PDF.hs 146 - -- Save pages and streams to the object dictionary so that they are saved in the PDF document + -- Save pages to the object dictionary so that they are saved in the PDF document hunk ./Graphics/PDF.hs 153 - modify $ \s -> s {catalog = cat} + modifyStrict $ \s -> s {catalog = cat} hunk ./Test/test.hs 130 - setHStretch 3 + --setHStretch 3 hunk ./Graphics/PDF/Document.hs 50 - +import qualified Data.ByteString.Lazy as B(append) hunk ./Graphics/PDF/Document.hs 116 - -> PDF () + -> PDF a hunk ./Graphics/PDF/Document.hs 125 - Nothing -> return () + Nothing -> error "Can't find the page to draw on it" hunk ./Graphics/PDF/Document.hs 130 - Nothing -> return() + Nothing -> error "Can't find a content for the page to draw on it" hunk ./Graphics/PDF/Document.hs 132 - Just (_,c) -> do + Just (_,(oldState,oldW)) -> do hunk ./Graphics/PDF/Document.hs 134 - modifyStrict $ \s -> s {streams = IM.insert streamRef (Just page,c >> draw >> return ()) lStreams} + myBounds <- gets xobjectBound + let (a,state',w') = runDrawing draw (emptyEnvironment {streamId = streamRef, xobjectb = myBounds}) oldState + modifyStrict $ \s -> s {streams = IM.insert streamRef (Just page,(state',B.append oldW w')) lStreams} + return a hunk ./Graphics/PDF/Draw.hs 65 + , emptyDrawState hunk ./Graphics/PDF/Draw.hs 124 - , currentp :: Maybe Int hunk ./Graphics/PDF/Draw.hs 127 -emptyEnvironment = DrawEnvironment 0 IM.empty Nothing +emptyEnvironment = DrawEnvironment 0 IM.empty hunk ./Graphics/PDF/Draw.hs 180 + +emptyDrawState :: Int -> DrawState +emptyDrawState ref = + let names = (map (("O" ++ (show ref)) ++ ) $ [replicate k ['a'..'z'] | k <- [1..]] >>= sequence) in + DrawState names emptyRsrc M.empty M.empty M.empty M.empty emptyDictionary [] M.empty M.empty M.empty hunk ./Graphics/PDF/Draw.hs 187 -runDrawing :: Draw a -> DrawEnvironment -> (a,DrawState,B.ByteString) -runDrawing drawing environment = - let names = (map (("O" ++ (show . streamId $ environment)) ++ ) $ [replicate k ['a'..'z'] | k <- [1..]] >>= sequence) - state = DrawState - names - emptyRsrc - M.empty M.empty M.empty M.empty - emptyDictionary [] M.empty M.empty M.empty - (a,state',w') = (runRWS . unDraw $ drawing) environment state - in - (a,state',w') +runDrawing :: Draw a -> DrawEnvironment -> DrawState -> (a,DrawState,B.ByteString) +runDrawing drawing environment state = (runRWS . unDraw $ drawing) environment state + hunk ./Graphics/PDF/Draw.hs 274 - , streams :: !(IM.IntMap ((Maybe (PDFReference PDFPage)),Draw ())) -- ^ Draw commands + , streams :: !(IM.IntMap ((Maybe (PDFReference PDFPage)),(DrawState,B.ByteString))) -- ^ Draw commands hunk ./Graphics/PDF/Media.hs 14 - -- * Images - -- ** Types - -- ** Functions - drawVideo - , newVideo hunk ./Graphics/PDF/Media.hs 34 -newVideo :: FilePath - -> PDF (PDFReference Rendition) -newVideo f = addObject Rendition - -drawVideo :: PDFReference Rendition - -> PDFFloat - -> PDFFloat - -> PDFFloat - -> PDFFloat - -> Draw () -drawVideo v xa ya xb yb = do - cp <- asks currentp - case cp of - Nothing -> return () - Just p -> newAnnotation $ Screen v (toPDFString "Test") [xa,ya,xb,yb] (PDFReference p) Nothing Nothing - return () +--newVideo :: FilePath +-- -> PDF (PDFReference Rendition) +--newVideo f = addObject Rendition +-- +--drawVideo :: PDFReference Rendition +-- -> PDFFloat +-- -> PDFFloat +-- -> PDFFloat +-- -> PDFFloat +-- -> Draw () +--drawVideo v xa ya xb yb = do +-- cp <- asks currentp +-- case cp of +-- Nothing -> return () +-- Just p -> newAnnotation $ Screen v (toPDFString "Test") [xa,ya,xb,yb] (PDFReference p) Nothing Nothing +-- return () hunk ./Graphics/PDF/Pages.hs 81 - modifyStrict $ \s -> s {streams = IM.insert streamref (page,d >> return ()) (streams s)} + myBounds <- gets xobjectBound + let (_,state',w') = runDrawing d (emptyEnvironment {streamId = streamref, xobjectb = myBounds}) (emptyDrawState streamref) + modifyStrict $ \s -> s {streams = IM.insert streamref (page,(state',w')) (streams s)} hunk ./Graphics/PDF/Shading.hs 23 -import Data.ByteString.Lazy.Char8(singleton,pack) +import Data.ByteString.Lazy.Char8(pack) hunk ./Graphics/PDF.hs 94 - addStream (k,(p,d)) = do + addStream (k,(p,(state',w'))) = do hunk ./Graphics/PDF.hs 98 - myBounds <- gets xobjectBound - cp <- gets currentPage - let (_,state',w') = runDrawing d (emptyEnvironment {streamId = r, xobjectb = myBounds, currentp = maybe Nothing (\(PDFReference x) -> Just x) cp }) - ref = PDFReference r :: PDFReference PDFLength + --myBounds <- gets xobjectBound + --cp <- gets currentPage + --let (_,state',w') = runDrawing d (emptyEnvironment {streamId = r, xobjectb = myBounds, currentp = maybe Nothing (\(PDFReference x) -> Just x) cp }) + let ref = PDFReference r :: PDFReference PDFLength hunk ./Test/test.hs 139 - mapM_ (const par) [1..1000] + mapM_ (const par) [1..100] hunk ./Test/test.hs 202 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar"}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = True}) rect $ do hunk ./Graphics/PDF/Draw.hs 409 -data OutlineStyle = Normal - | Italic - | Bold +data OutlineStyle = NormalOutline + | ItalicOutline + | BoldOutline hunk ./Graphics/PDF/Draw.hs 525 - toPDF Normal = toPDF (PDFInteger 0) - toPDF Italic = toPDF (PDFInteger 1) - toPDF Bold = toPDF (PDFInteger 2) + toPDF NormalOutline = toPDF (PDFInteger 0) + toPDF ItalicOutline = toPDF (PDFInteger 1) + toPDF BoldOutline = toPDF (PDFInteger 2) hunk ./Graphics/PDF/Pages.hs 249 - (maybe Normal id style) + (maybe NormalOutline id style) hunk ./Graphics/PDF/Text.hs 283 - textStart x (y ) + textStart x y hunk ./Graphics/PDF/Typesetting.hs 17 + , Style(..) + , TextStyle(..) + , StyleFunction(..) + , AnyStyle hunk ./Graphics/PDF/Typesetting.hs 29 - , setHSpace - , setHStretch - , setHShrink + , glue + , penalty + , addBox + , currentStyle hunk ./Graphics/PDF/Typesetting.hs 41 -import qualified Data.ByteString.Lazy as B(ByteString,null,splitWith) +import qualified Data.ByteString.Lazy as B(ByteString,null,splitWith,concat,empty,append) hunk ./Graphics/PDF/Typesetting.hs 46 -import Data.ByteString.Lazy.Char8(pack) +import Data.ByteString.Lazy.Char8(pack,singleton) +import Data.Maybe(isJust,fromJust) hunk ./Graphics/PDF/Typesetting.hs 49 +data TextStyle = TextStyle { textFont :: !PDFFont + , textStrokeColor :: !Color + , textFillColor :: !Color + , textMode :: !TextMode + , theTextWidth :: !PDFFloat + , scaleSpace :: !PDFFloat -- Scaling factor for normal space size + , scaleDilatation :: !PDFFloat + , scaleCompression :: !PDFFloat + } + deriving(Eq) + +-- | What kind of style drawing function is required for a word +-- when word styling is enabled +data StyleFunction = DrawBelowWord + | DrawOverWord + | DrawGlue + deriving(Eq) + +class Style a where + sentenceStyle :: a -> Rectangle -> Draw () + wordStyle :: a -> Maybe (Rectangle -> StyleFunction -> Draw ()) + textStyle :: a -> TextStyle + styleCode :: a -> Int + updateStyle :: a -> a + +data AnyStyle = forall a. (Style a) => AnyStyle a + +instance Style AnyStyle where + sentenceStyle (AnyStyle a) = sentenceStyle a + wordStyle (AnyStyle a) = wordStyle a + textStyle (AnyStyle a) = textStyle a + styleCode (AnyStyle a) = styleCode a + updateStyle (AnyStyle a) = AnyStyle $ updateStyle a hunk ./Graphics/PDF/Typesetting.hs 90 - | Glue !PDFFloat !PDFFloat !PDFFloat + | Glue !PDFFloat !PDFFloat !PDFFloat !(Maybe AnyStyle) hunk ./Graphics/PDF/Typesetting.hs 92 + | Text !AnyStyle !PDFString + hunk ./Graphics/PDF/Typesetting.hs 97 - show (Glue a b c) = "(Glue " ++ show a ++ " " ++ show b ++ " " ++ show c ++ ")" + show (Glue a b c _) = "(Glue " ++ show a ++ " " ++ show b ++ " " ++ show c ++ ")" hunk ./Graphics/PDF/Typesetting.hs 99 + show (Text s t) = "(Text " ++ show t ++ ")" hunk ./Graphics/PDF/Typesetting.hs 106 - penalty :: a -> PDFFloat + getPenalty :: a -> PDFFloat hunk ./Graphics/PDF/Typesetting.hs 120 - penalty (_,_,_,_,Penalty _ p _) = p - penalty _ = 0.0 + getPenalty (_,_,_,_,Penalty _ p _) = p + getPenalty _ = 0.0 hunk ./Graphics/PDF/Typesetting.hs 139 - penalty (ZList _ b _) = penalty b + getPenalty (ZList _ b _) = getPenalty b hunk ./Graphics/PDF/Typesetting.hs 142 +-- A penalty has no width unless you break on it so it needs a special processing +penaltyWidth :: B -> PDFFloat +penaltyWidth (Penalty w _ _) = w +penaltyWidth _ = 0 + hunk ./Graphics/PDF/Typesetting.hs 148 + boxWidth (Text style s) r = textWidth (textFont . textStyle $ style) s hunk ./Graphics/PDF/Typesetting.hs 150 - boxWidth (Glue w yi zi) r = + boxWidth (Glue w yi zi _) r = hunk ./Graphics/PDF/Typesetting.hs 156 - boxWidth (Penalty w _ _) _ = 0 + boxWidth (Penalty _ _ _) _ = 0 hunk ./Graphics/PDF/Typesetting.hs 158 + boxHeight (Text style _) = getHeight (textFont . textStyle $ style) hunk ./Graphics/PDF/Typesetting.hs 160 - boxHeight (Glue _ _ _) = 0 + boxHeight (Glue _ _ _ _) = 0 hunk ./Graphics/PDF/Typesetting.hs 163 + boxDescent (Text style _) = getDescent (textFont . textStyle $ style) hunk ./Graphics/PDF/Typesetting.hs 165 - boxDescent (Glue _ _ _) = 0 + boxDescent (Glue _ _ _ _) = 0 hunk ./Graphics/PDF/Typesetting.hs 168 + strokeBox (Text style s) r x y = drawText $ do + setFont (textFont . textStyle $ style) + strokeColor (textStrokeColor . textStyle $ style) + fillColor (textFillColor . textStyle $ style) + renderMode (textMode . textStyle $ style) + textStart x y + displayText s + hunk ./Graphics/PDF/Typesetting.hs 183 - strokeBox (Glue w yi zi) r x y = do + strokeBox (Glue w yi zi _) r x y = do hunk ./Graphics/PDF/Typesetting.hs 193 + +newText :: Monad m => B.ByteString -> m (a,b,B.ByteString) -> m (a,b,B.ByteString) +newText a b = do + (x,y,z) <- b + return (x,y,B.append a z) hunk ./Graphics/PDF/Typesetting.hs 199 -instance Box a => Box [a] where +instance Box [B] where hunk ./Graphics/PDF/Typesetting.hs 204 - strokeBox [] r x y = return () + strokeBox [] r x y = return () + + -- A text box is processed in a special way + strokeBox l@(a@(Text s (PDFString t)):nl) r x y = do + -- If word style + if (isJust . wordStyle $ s) + -- then we display all words and then apply the sentence style + then do + (l',x') <- wordAnalysis s l r x y + let de = getDescent . textFont . textStyle $ s + he = getHeight . textFont . textStyle $ s + sentenceStyle s (Rectangle x (y - de) x' (y - de + he)) + -- We render remaining boxes + strokeBox l' r x' y + -- No word style then we can work on the full sentence and draw it + else do + (l',x') <- drawText $ do + -- We set the text setting + setFont (textFont . textStyle $ s) + strokeColor (textStrokeColor . textStyle $ s) + fillColor (textFillColor . textStyle $ s) + renderMode (textMode . textStyle $ s) + --setWidth (theTextWidth . textStyle $ s) + -- Here we need to dilate the space to take into account r and the font setting + let ws = (textWidth (textFont . textStyle $ s) (toPDFString " ")) + h = scaleSpace . textStyle $ s + sy = scaleDilatation . textStyle $ s + sz = scaleCompression . textStyle $ s + dws = ws * h -- dilated space + gy = sy*dws / 2.0 + gz = sz*dws / 3.0 + delta = if r >= 0 then r*gy else r*gz + -- ws is the true font space. We use dws so we have a user overhead + -- and the overhead of the space dilatation + wordSpace (dws - ws + delta) + -- And we render the text + textStart x y + (l',x',t) <- textStroke s l r x y + displayText . PDFString $ t + return (l',x') + -- We call the drawing function for the style with a rectangle around the sentence + let de = getDescent . textFont . textStyle $ s + he = getHeight . textFont . textStyle $ s + sentenceStyle s (Rectangle x (y - de) x' (y - de + he)) + -- We render remaining boxes + strokeBox l' r x' y + where + -- wordAnalysis is used to detect a full sentence using the same style and return the new position + wordAnalysis style [] r x y = return ([],x) + wordAnalysis style l@(a@(Text s' (PDFString t')):l') r x y | styleCode style == styleCode s = do + let de = getDescent . textFont . textStyle $ s' + he = getHeight . textFont . textStyle $ s' + w = boxWidth a r + re = Rectangle x (y - de) (x+w) (y - de + he) + -- Draw word background + (fromJust . wordStyle $ s') re DrawBelowWord + -- Draw word + strokeBox a r x y + -- Draw over word + (fromJust . wordStyle $ s') re DrawOverWord + -- Draw other boxes + wordAnalysis style l' r (x + w) y + | otherwise = return (l,x) + wordAnalysis style l@(a@(Glue _ _ _ (Just s)):l') r x y | styleCode style == styleCode s = do + let de = getDescent . textFont . textStyle $ s + he = getHeight . textFont . textStyle $ s + w = boxWidth a r + re = Rectangle x (y - de) (x+w) (y - de + he) + -- Draw word background + (fromJust . wordStyle $ s) re DrawGlue + -- Draw other boxes + wordAnalysis style l' r (x + w) y + | otherwise = return (l,x) + wordAnalysis _ l _ x _ = return (l,x) + -- textStroke is used to build a sentence of words having the same style + -- When we have no more any text or the style is different + -- we display the concatenated text + -- return the new list of boxes and horizontal processing + + textStroke _ [] _ x _ = return ([],x,B.empty) + textStroke style l@(a@(Text s' (PDFString t')):l') r x y | styleCode s' == styleCode style = + t' `newText` (textStroke (updateStyle style) l' r (x + boxWidth a r) y) + | otherwise = return (l,x,B.empty) + -- That glue is special. It is just a space and we will processed as a space + textStroke style l@(a@(Glue _ _ _ (Just s)):l') r x y | styleCode style == styleCode s = (singleton ' ') `newText` (textStroke (updateStyle style) l' r (x + boxWidth a r) y) + | otherwise = return (l,x,B.empty) + textStroke _ l _ x _ = return (l,x,B.empty) + -- A normal box is drawn and we move to the next one hunk ./Graphics/PDF/Typesetting.hs 295 + hunk ./Graphics/PDF/Typesetting.hs 332 - , totalStretch :: !PDFFloat - , totalShrink :: !PDFFloat + , totalDilatation :: !PDFFloat + , totalCompression :: !PDFFloat hunk ./Graphics/PDF/Typesetting.hs 347 - let w = cumulatedW l - totalWidth a + (if isPenalty l then boxWidth (box l) 0.0 else 0.0) - y = cumulatedY l - totalStretch a - z = cumulatedZ l - totalShrink a + let w = cumulatedW l - totalWidth a + penaltyWidth (box l) + y = cumulatedY l - totalDilatation a + z = cumulatedZ l - totalCompression a hunk ./Graphics/PDF/Typesetting.hs 384 - p = penalty z + p = getPenalty z hunk ./Graphics/PDF/Typesetting.hs 428 -createBreaknode prev (ZList _ (w,y,z,_,Glue w' y' z') []) = BreakNode (w + w') (y+y') (z+z') 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,Glue w' y' z' _) []) = BreakNode (w + w') (y+y') (z+z') 0.0 False 0 0.0 prev hunk ./Graphics/PDF/Typesetting.hs 432 +createBreaknode prev (ZList _ (w,y,z,_,Text _ _) _) = BreakNode w y z 0.0 False 0 0.0 prev hunk ./Graphics/PDF/Typesetting.hs 437 -moveRight (ZList l c@(w,y,z,p,Glue w' y' z') r) = +moveRight (ZList l c@(w,y,z,p,Glue w' y' z' _) r) = hunk ./Graphics/PDF/Typesetting.hs 458 -isFeasibleBreakpoint (ZList (OneCB (_,_,_,_,B _)) (_,_,_,_,Glue _ _ _) _) = True +isFeasibleBreakpoint (ZList (OneCB (_,_,_,_,B _)) (_,_,_,_,Glue _ _ _ _) _) = True +isFeasibleBreakpoint (ZList (OneCB (_,_,_,_,Text _ _)) (_,_,_,_,Glue _ _ _ _) _) = True hunk ./Graphics/PDF/Typesetting.hs 464 -endParagraphBoxes = [Penalty 0 (infinity+1) False,Glue 0 (infinity+1) 0,Penalty 0 (-infinity -1) True] +endParagraphBoxes = [Penalty 0 (infinity+1) False,Glue 0 (infinity+1) 0 Nothing,Penalty 0 (-infinity -1) True] hunk ./Graphics/PDF/Typesetting.hs 482 -simplify ((Glue _ _ _):l) = simplify l +simplify ((Glue _ _ _ _):l) = simplify l hunk ./Graphics/PDF/Typesetting.hs 610 -addSpacesToLine :: PDFFont -> B -> [B.ByteString] -> [B] +addSpacesToLine :: AnyStyle -> B -> [B.ByteString] -> [B] hunk ./Graphics/PDF/Typesetting.hs 613 - | otherwise = [B . T f . PDFString $ x] + | otherwise = [Text f (PDFString x)] hunk ./Graphics/PDF/Typesetting.hs 615 - | otherwise = (B . T f . PDFString $ x) : g : addSpacesToLine f g xs + | otherwise = (Text f (PDFString x)) : g : addSpacesToLine f g xs hunk ./Graphics/PDF/Typesetting.hs 619 - TMState f h y z <- get - let ws = (textWidth f (toPDFString " ") ) * h - tell $ addSpacesToLine f (Glue (ws) (y*ws/2.0) (z*ws/3.0)) . getWords $ t + f <- gets tmStyle + let ws = (textWidth (textFont . textStyle $ f) (toPDFString " ") ) + h = scaleSpace . textStyle $ f + sy = scaleDilatation . textStyle $ f + sz = scaleCompression . textStyle $ f + tell $ addSpacesToLine f (Glue (ws*h) (h*sy*ws/2.0) (h*sz*ws/3.0) (Just f)) . getWords $ t hunk ./Graphics/PDF/Typesetting.hs 627 +-- | End the current paragraph hunk ./Graphics/PDF/Typesetting.hs 631 -displayFormattedText :: PDFFloat -> PDFFloat -> PDFFloat -> TM a -> Draw a -displayFormattedText x y maxw t = do - let (a, _, boxes) = (runRWS . unTM $ t) () (TMState (PDFFont Times_Roman 10) 1.0 1.0 1.0) +-- | Display a formatted text at a given position with a given default style +displayFormattedText :: Style d => PDFFloat -- ^ Horizontal position + -> PDFFloat -- ^ Vertical position + -> PDFFloat -- ^ Max width + -> d -- ^ Default style + -> TM a -- ^ Typesetting monad + -> Draw a -- ^ Draw monad +displayFormattedText x y maxw defaultStyle t = do + let (a, _, boxes) = (runRWS . unTM $ t >>= \x -> do {endParagraph ; return x} ) () (TMState (AnyStyle defaultStyle)) hunk ./Graphics/PDF/Typesetting.hs 644 -data TMState = TMState { tmFont :: !PDFFont - , hspcWidth :: !PDFFloat -- Scaling factor for normal space size - , hStretch :: !PDFFloat - , hShrink :: !PDFFloat - } +data TMState = TMState { tmStyle :: !AnyStyle} hunk ./Graphics/PDF/Typesetting.hs 648 -setStyle :: PDFFont -> TM () -setStyle f = modifyStrict $ \s -> s {tmFont = f} - --- | Scale factor for the space size -setHSpace :: PDFFloat -> TM () -setHSpace h = modifyStrict $ \s -> s{ hspcWidth = h } +-- | Set style of text +setStyle :: Style a => a -> TM () +setStyle f = modifyStrict $ \s -> s {tmStyle = AnyStyle f} hunk ./Graphics/PDF/Typesetting.hs 652 --- | Scale factor for the strechability of spaces -setHStretch :: PDFFloat -> TM () -setHStretch h = modifyStrict $ \s -> s{ hStretch = h } - --- | Scale factor for the shrinkability of spaces -setHShrink :: PDFFloat -> TM () -setHShrink h = modifyStrict $ \s -> s{ hShrink = h } +-- | Get current text style +currentStyle :: TM AnyStyle +currentStyle = gets tmStyle hunk ./Graphics/PDF/Typesetting.hs 656 +-- | Add a new paragraph to the text hunk ./Graphics/PDF/Typesetting.hs 662 +-- | Add a text line hunk ./Graphics/PDF/Typesetting.hs 667 +-- | Add a glue to the stream +glue :: PDFFloat -- ^ Glue width + -> PDFFloat -- ^ Glue dilatation + -> PDFFloat -- ^ Glue compression + -> TM () +glue w y z = tell ([Glue w y z Nothing]) + +-- | Add a penalty to the stream +penalty :: PDFFloat -- ^ Penalty width + -> PDFFloat -- ^ Penalty value + -> TM () +penalty w p = tell ([Penalty w p False]) + +-- | Add a box to the stream +addBox :: (Show a, Box a) => a -> TM () +addBox a = tell ([B a]) hunk ./Test/test.hs 107 - +data Normal = Normal deriving(Eq) +data Bold = Bold deriving(Eq) +data Crazy = Crazy deriving(Eq) + +instance Style Normal where + sentenceStyle _ (Rectangle xa ya xb yb) = return () + wordStyle _ = Nothing + textStyle _ = TextStyle (PDFFont Times_Roman 10) black black FillText 1.0 1.0 1.0 1.0 + styleCode _ = 1 + updateStyle = id + +instance Style Bold where + sentenceStyle _ (Rectangle xa ya xb yb) = return () + wordStyle _ = Nothing + textStyle _ = TextStyle (PDFFont Times_Bold 12) black black FillText 1.0 1.0 1.0 1.0 + styleCode _ = 2 + updateStyle = id + + +crazyWord :: Rectangle -> StyleFunction -> Draw () +crazyWord r DrawBelowWord = do + fillColor $ Rgb 0.6 1 0.6 + fill r +crazyWord (Rectangle xa ya xb yb) DrawOverWord = do + strokeColor $ Rgb 0 0 1 + let m = (ya+yb)/2.0 + stroke $ Line xa m xb m +crazyWord (Rectangle xa ya xb yb) DrawGlue = do + fillColor $ Rgb 0 0 1 + fill (Circle ((xa+xb)/2.0) ((ya+yb)/2.0) ((xb-xa)/2.0)) + +instance Style Crazy where + sentenceStyle _ r = do + strokeColor blue + stroke r + wordStyle _ = Just crazyWord + textStyle _ = TextStyle (PDFFont Times_Roman 10) red red FillText 1.0 1.0 1.0 1.0 + styleCode _ = 3 + updateStyle = id + hunk ./Test/test.hs 151 - setHStretch 3.0 hunk ./Test/test.hs 152 - setStyle (PDFFont Times_Bold 12) - txt $ "incididunt ut labore et dolore magna aliqua." - setStyle (PDFFont Times_Roman 10) + setStyle Bold + txt $ "incididunt ut labore et dolore magna aliqua. " + setStyle Normal hunk ./Test/test.hs 158 - txt $ "Excepteur sint occaecat cupidatat non " - txt $ "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + setStyle Crazy + txt $ "Excepteur sint occaecat cupidatat non" + setStyle Normal + txt $ " proident, sunt in culpa qui officia deserunt mollit anim id est laborum." hunk ./Test/test.hs 163 + par hunk ./Test/test.hs 171 - --setHStretch 3 hunk ./Test/test.hs 172 - setStyle (PDFFont Times_Bold 12) + setStyle Bold hunk ./Test/test.hs 174 - setStyle (PDFFont Times_Roman 10) + setStyle Normal hunk ./Test/test.hs 179 - mapM_ (const par) [1..100] + mapM_ (const par) [1..10] hunk ./Test/test.hs 188 - displayFormattedText 10 300 maxw myText + displayFormattedText 10 300 maxw Normal debugText hunk ./Test/test.hs 242 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = True}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = False}) rect $ do hunk ./Graphics/PDF/LowLevel/Types.hs 31 +import System.Random hunk ./Graphics/PDF/LowLevel/Types.hs 58 -newtype PDFFloat = PDFFloat Double deriving(Eq,Ord,Num,Fractional,Floating,RealFrac,Real) +newtype PDFFloat = PDFFloat Double deriving(Eq,Ord,Num,Fractional,Floating,RealFrac,Real,Random) hunk ./Graphics/PDF/Typesetting.hs 62 -data StyleFunction = DrawBelowWord - | DrawOverWord +data StyleFunction = DrawWord hunk ./Graphics/PDF/Typesetting.hs 68 - wordStyle :: a -> Maybe (Rectangle -> StyleFunction -> Draw ()) + wordStyle :: a -> Maybe (Rectangle -> StyleFunction -> Draw b -> Draw ()) hunk ./Graphics/PDF/Typesetting.hs 72 + wordTransform :: a -> B -> [B] + wordTransform _ x = [x] + styleHeight :: a -> PDFFloat + styleDescent :: a -> PDFFloat + styleHeight = getHeight . textFont . textStyle + styleDescent = getDescent . textFont . textStyle hunk ./Graphics/PDF/Typesetting.hs 87 + wordTransform (AnyStyle a) = wordTransform a + styleHeight (AnyStyle a) = styleHeight a + styleDescent (AnyStyle a) = styleDescent a hunk ./Graphics/PDF/Typesetting.hs 166 - boxHeight (Text style _) = getHeight (textFont . textStyle $ style) + boxHeight (Text style _) = styleHeight style hunk ./Graphics/PDF/Typesetting.hs 171 - boxDescent (Text style _) = getDescent (textFont . textStyle $ style) + boxDescent (Text style _) = styleDescent style hunk ./Graphics/PDF/Typesetting.hs 221 - let de = getDescent . textFont . textStyle $ s - he = getHeight . textFont . textStyle $ s + let de = styleDescent s + he = styleHeight s hunk ./Graphics/PDF/Typesetting.hs 253 - let de = getDescent . textFont . textStyle $ s - he = getHeight . textFont . textStyle $ s + let de = styleDescent s + he = styleHeight s hunk ./Graphics/PDF/Typesetting.hs 262 - let de = getDescent . textFont . textStyle $ s' - he = getHeight . textFont . textStyle $ s' + let de = styleDescent s' + he = styleHeight s' hunk ./Graphics/PDF/Typesetting.hs 267 - (fromJust . wordStyle $ s') re DrawBelowWord - -- Draw word - strokeBox a r x y - -- Draw over word - (fromJust . wordStyle $ s') re DrawOverWord + (fromJust . wordStyle $ s') re DrawWord (strokeBox a r x y) hunk ./Graphics/PDF/Typesetting.hs 272 - let de = getDescent . textFont . textStyle $ s - he = getHeight . textFont . textStyle $ s + let de = styleDescent s + he = styleHeight s hunk ./Graphics/PDF/Typesetting.hs 277 - (fromJust . wordStyle $ s) re DrawGlue + (fromJust . wordStyle $ s) re DrawGlue (return ()) hunk ./Graphics/PDF/Typesetting.hs 314 -instance Box T where - boxWidth (T f s) _ = textWidth f s - boxHeight (T f _) = getHeight f - boxDescent (T f _) = getDescent f - - strokeBox (T f s) r x y = do - drawText $ text f x y s - --withNewContext $ do - -- setWidth 0.5 - -- drawText $ text f x y s - -- strokeColor red - -- stroke $ Rectangle x (y - (getDescent f)) (x + textWidth f s) (y - getDescent f + getHeight f) +--instance Box T where +-- boxWidth (T f s) _ = textWidth f s +-- boxHeight (T f _) = getHeight f +-- boxDescent (T f _) = getDescent f +-- +-- strokeBox (T f s) r x y = do +-- drawText $ text f x y s +-- --withNewContext $ do +-- -- setWidth 0.5 +-- -- drawText $ text f x y s +-- -- strokeColor red +-- -- stroke $ Rectangle x (y - (getDescent f)) (x + textWidth f s) (y - getDescent f + getHeight f) hunk ./Graphics/PDF/Typesetting.hs 617 - | otherwise = [Text f (PDFString x)] + | otherwise = wordTransform f (Text f (PDFString x)) hunk ./Graphics/PDF/Typesetting.hs 619 - | otherwise = (Text f (PDFString x)) : g : addSpacesToLine f g xs + | otherwise = wordTransform f (Text f (PDFString x)) ++ [g] ++ addSpacesToLine f g xs hunk ./Test/test.hs 19 +import System.Random hunk ./Test/test.hs 111 +data SuperCrazy = SuperCrazy !([PDFFloat],[PDFFloat]) deriving(Eq) hunk ./Test/test.hs 128 -crazyWord :: Rectangle -> StyleFunction -> Draw () -crazyWord r DrawBelowWord = do +crazyWord :: Rectangle -> StyleFunction -> Draw a -> Draw () +crazyWord r@(Rectangle xa ya xb yb) DrawWord d = do hunk ./Test/test.hs 132 -crazyWord (Rectangle xa ya xb yb) DrawOverWord = do + d hunk ./Test/test.hs 136 -crazyWord (Rectangle xa ya xb yb) DrawGlue = do +crazyWord (Rectangle xa ya xb yb) DrawGlue d = do hunk ./Test/test.hs 149 + +superCrazy :: SuperCrazy +superCrazy = SuperCrazy (randomRs (PDFFloat 0.0,PDFFloat 4.0) (mkStdGen 10000),randomRs (PDFFloat (-10.0),PDFFloat 10.0) (mkStdGen 10000)) + +instance Style SuperCrazy where + styleCode _ = 4 + updateStyle (SuperCrazy (a,b)) = SuperCrazy $ (drop 8 a,tail b) + textStyle _ = TextStyle (PDFFont Times_Roman 14) black black FillText 1.0 3.0 0.33 0.33 + sentenceStyle _ _ = return () + styleHeight r = (getHeight . textFont . textStyle $ r) + 8.0 + styleDescent r = (getDescent . textFont . textStyle $ r) + 4 + + wordStyle (SuperCrazy (l,angl)) = Just ws + where + ws r DrawGlue _ = return () + ws (Rectangle xa ya xb yb) DrawWord draw = do + let [a,b,c,d,e,f,g,h] = take 8 $ l + angle = head angl + p = Polygon [ (xa-a,ya+b) + , (xb+c,ya+d) + , (xb+e,yb-f) + , (xa-g,yb-h) + , (xa-a,ya+b) + ] + strokeColor red + stroke p + fillColor $ Rgb 0.8 1.0 0.8 + fill p + withNewContext $ do + applyMatrix . rotate . Degree $ angle + draw + return () + + hunk ./Test/test.hs 194 - setStyle Crazy hunk ./Test/test.hs 195 - setStyle Normal hunk ./Test/test.hs 196 + setStyle superCrazy + txt $ " The end with a super crazy style to check the behavior of my implementation. " + setStyle Normal + txt $ "Return to a normal style :-)" hunk ./Test/test.hs 201 + setStyle Crazy hunk ./Test/test.hs 222 - strokeColor red - setWidth 0.5 - stroke $ Rectangle 10 0 (10+maxw) 300 - stroke $ Line 10 textStart (10+maxw) textStart + --strokeColor red + --setWidth 0.5 + --stroke $ Rectangle 10 0 (10+maxw) 300 + --stroke $ Line 10 textStart (10+maxw) textStart hunk ./Graphics/PDF/Typesetting.hs 261 - wordAnalysis style l@(a@(Text s' (PDFString t')):l') r x y | styleCode style == styleCode s = do + wordAnalysis style l@(a@(Text s' (PDFString t')):l') r x y | styleCode style == styleCode s' = do hunk ./Graphics/PDF/Typesetting.hs 267 - (fromJust . wordStyle $ s') re DrawWord (strokeBox a r x y) + (fromJust . wordStyle $ style) re DrawWord (strokeBox a r x y) hunk ./Graphics/PDF/Typesetting.hs 269 - wordAnalysis style l' r (x + w) y + wordAnalysis (updateStyle style) l' r (x + w) y hunk ./Graphics/PDF/Typesetting.hs 277 - (fromJust . wordStyle $ s) re DrawGlue (return ()) + (fromJust . wordStyle $ style) re DrawGlue (return ()) hunk ./Graphics/PDF/Typesetting.hs 279 - wordAnalysis style l' r (x + w) y + wordAnalysis (updateStyle style) l' r (x + w) y hunk ./Graphics/PDF/Typesetting.hs 289 - t' `newText` (textStroke (updateStyle style) l' r (x + boxWidth a r) y) + t' `newText` (textStroke style l' r (x + boxWidth a r) y) hunk ./Graphics/PDF/Typesetting.hs 292 - textStroke style l@(a@(Glue _ _ _ (Just s)):l') r x y | styleCode style == styleCode s = (singleton ' ') `newText` (textStroke (updateStyle style) l' r (x + boxWidth a r) y) + textStroke style l@(a@(Glue _ _ _ (Just s)):l') r x y | styleCode style == styleCode s = (singleton ' ') `newText` (textStroke style l' r (x + boxWidth a r) y) hunk ./Test/test.hs 111 -data SuperCrazy = SuperCrazy !([PDFFloat],[PDFFloat]) deriving(Eq) +data SuperCrazy = SuperCrazy !([Int],[PDFFloat]) deriving(Eq) hunk ./Test/test.hs 151 -superCrazy = SuperCrazy (randomRs (PDFFloat 0.0,PDFFloat 4.0) (mkStdGen 10000),randomRs (PDFFloat (-10.0),PDFFloat 10.0) (mkStdGen 10000)) +superCrazy = SuperCrazy (randomRs (0,32) (mkStdGen 0),randomRs (-10.0,10.0) (mkStdGen 10000)) hunk ./Test/test.hs 164 - ws (Rectangle xa ya xb yb) DrawWord draw = do - let [a,b,c,d,e,f,g,h] = take 8 $ l + ws (Rectangle xa ya xb yb) DrawWord drawWord = do + let [a,b,c,d,e,f,g,h] :: [PDFFloat] = map (\x -> x / 8.0) . map fromIntegral . take 8 $ l hunk ./Test/test.hs 178 - applyMatrix . rotate . Degree $ angle - draw + --applyMatrix . rotate . Degree $ angle + drawWord hunk ./Test/test.hs 281 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = False}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = True}) rect $ do hunk ./Graphics/PDF/Typesetting.hs 48 +--import Debug.Trace + +--debug s x = trace (show s ++ " : " ++ show x) x hunk ./Graphics/PDF/Typesetting.hs 56 - , theTextWidth :: !PDFFloat + , penWidth :: !PDFFloat hunk ./Graphics/PDF/Typesetting.hs 75 - wordTransform :: a -> B -> [B] - wordTransform _ x = [x] + wordTransform :: a -> [B] -> [B] + wordTransform _ x = x hunk ./Graphics/PDF/Typesetting.hs 237 - --setWidth (theTextWidth . textStyle $ s) + --setWidth (penWidth . textStyle $ s) hunk ./Graphics/PDF/Typesetting.hs 613 -getWords = B.splitWith B.isSpaceWord8 -{-# INLINE getWords #-} +getWords x = B.splitWith B.isSpaceWord8 $ x hunk ./Graphics/PDF/Typesetting.hs 619 - | otherwise = wordTransform f (Text f (PDFString x)) + | otherwise = wordTransform f [Text f (PDFString x)] hunk ./Graphics/PDF/Typesetting.hs 621 - | otherwise = wordTransform f (Text f (PDFString x)) ++ [g] ++ addSpacesToLine f g xs + | otherwise = if B.null . head $ xs + then + wordTransform f [Text f (PDFString x)] ++ addSpacesToLine f g xs + else + wordTransform f [Text f (PDFString x)] ++ [g] ++ addSpacesToLine f g xs hunk ./Test/test.hs 156 - textStyle _ = TextStyle (PDFFont Times_Roman 14) black black FillText 1.0 3.0 0.33 0.33 + textStyle _ = TextStyle (PDFFont Times_Roman 12) black black FillText 1.0 2.0 0.5 0.5 hunk ./Test/test.hs 158 - styleHeight r = (getHeight . textFont . textStyle $ r) + 8.0 - styleDescent r = (getDescent . textFont . textStyle $ r) + 4 + styleHeight r = (getHeight . textFont . textStyle $ r) + 4.0 + styleDescent r = (getDescent . textFont . textStyle $ r) + 2 hunk ./Test/test.hs 165 - let [a,b,c,d,e,f,g,h] :: [PDFFloat] = map (\x -> x / 8.0) . map fromIntegral . take 8 $ l + let [a,b,c,d,e,f,g,h] :: [PDFFloat] = map (\x -> x / 16.0) . map fromIntegral . take 8 $ l hunk ./Test/test.hs 197 - txt $ " The end with a super crazy style to check the behavior of my implementation. " + txt $ " And now, a super crazy style to test the code. " hunk ./Test/test.hs 201 + txt $ "More crazy styles ... " adddir ./Graphics/PDF/Typesetting hunk ./Graphics/PDF/Typesetting.hs 21 - , Paragraph hunk ./Graphics/PDF/Typesetting.hs 39 -import qualified Data.ByteString.Lazy.Char8 as B(unwords) -import qualified Data.ByteString.Lazy as B(ByteString,null,splitWith,concat,empty,append) +import qualified Data.ByteString.Lazy as B(ByteString,null,splitWith,empty,append) hunk ./Graphics/PDF/Typesetting.hs 41 -import Data.List(intersperse,minimumBy) -import qualified Data.Map as Map hunk ./Graphics/PDF/Typesetting.hs 42 -import Data.ByteString.Lazy.Char8(pack,singleton) +import Data.ByteString.Lazy.Char8(singleton) hunk ./Graphics/PDF/Typesetting.hs 44 +import Graphics.PDF.Typesetting.Breaking hunk ./Graphics/PDF/Typesetting.hs 49 -data TextStyle = TextStyle { textFont :: !PDFFont - , textStrokeColor :: !Color - , textFillColor :: !Color - , textMode :: !TextMode - , penWidth :: !PDFFloat - , scaleSpace :: !PDFFloat -- Scaling factor for normal space size - , scaleDilatation :: !PDFFloat - , scaleCompression :: !PDFFloat - } - deriving(Eq) - --- | What kind of style drawing function is required for a word --- when word styling is enabled -data StyleFunction = DrawWord - | DrawGlue - deriving(Eq) - -class Style a where - sentenceStyle :: a -> Rectangle -> Draw () - wordStyle :: a -> Maybe (Rectangle -> StyleFunction -> Draw b -> Draw ()) - textStyle :: a -> TextStyle - styleCode :: a -> Int - updateStyle :: a -> a - wordTransform :: a -> [B] -> [B] - wordTransform _ x = x - styleHeight :: a -> PDFFloat - styleDescent :: a -> PDFFloat - styleHeight = getHeight . textFont . textStyle - styleDescent = getDescent . textFont . textStyle - -data AnyStyle = forall a. (Style a) => AnyStyle a - -instance Style AnyStyle where - sentenceStyle (AnyStyle a) = sentenceStyle a - wordStyle (AnyStyle a) = wordStyle a - textStyle (AnyStyle a) = textStyle a - styleCode (AnyStyle a) = styleCode a - updateStyle (AnyStyle a) = AnyStyle $ updateStyle a - wordTransform (AnyStyle a) = wordTransform a - styleHeight (AnyStyle a) = styleHeight a - styleDescent (AnyStyle a) = styleDescent a - -class Box a where - boxWidth :: a -> PDFFloat -> PDFFloat - boxHeight :: a -> PDFFloat - boxDescent :: a -> PDFFloat - strokeBox :: a -> PDFFloat -> PDFFloat -> PDFFloat -> Draw () - -data B = forall a. (Show a,Box a) => B !a - | Glue !PDFFloat !PDFFloat !PDFFloat !(Maybe AnyStyle) - | Penalty !PDFFloat !PDFFloat !Bool - | Text !AnyStyle !PDFString - - -instance Show B where - show (B a) = "(B " ++ show a ++ ")" - show (Glue a b c _) = "(Glue " ++ show a ++ " " ++ show b ++ " " ++ show c ++ ")" - show (Penalty a b c) = "(Penalty " ++ show a ++ " " ++ show b ++ " " ++ show c ++ ")" - show (Text s t) = "(Text " ++ show t ++ ")" - - -type CB = (PDFFloat,PDFFloat,PDFFloat,Int,B) - -class PointedBox a where - isFlagged :: a -> Bool - getPenalty :: a -> PDFFloat - isPenalty :: a -> Bool - box :: a -> B - position :: a -> Int - cumulatedW :: a -> PDFFloat - cumulatedY :: a -> PDFFloat - cumulatedZ :: a -> PDFFloat - isForcedBreak :: a -> Bool - -instance PointedBox (PDFFloat,PDFFloat,PDFFloat,Int,B) where - isFlagged (_,_,_,_,Penalty _ _ f) = f - isFlagged _ = False - isPenalty (_,_,_,_,Penalty _ _ _) = True - isPenalty _ = False - getPenalty (_,_,_,_,Penalty _ p _) = p - getPenalty _ = 0.0 - box (_,_,_,_,a) = a - position (_,_,_,p,_) = p - cumulatedW (w,_,_,_,_) = w - cumulatedY (_,y,_,_,_) = y - cumulatedZ (_,_,z,_,_) = z - isForcedBreak (_,_,_,_,Penalty _ p _) = p <= (-infinity) - isForcedBreak _ = False - - -instance PointedBox ZList where - isPenalty (ZList _ b _) = isPenalty b - isFlagged (ZList _ b _) = isFlagged b - box (ZList _ b _) = box b - position (ZList _ b _) = position b - cumulatedW (ZList _ b _) = cumulatedW b - cumulatedY (ZList _ b _) = cumulatedY b - cumulatedZ (ZList _ b _) = cumulatedZ b - getPenalty (ZList _ b _) = getPenalty b - isForcedBreak (ZList _ b _) = isForcedBreak b - --- A penalty has no width unless you break on it so it needs a special processing -penaltyWidth :: B -> PDFFloat -penaltyWidth (Penalty w _ _) = w -penaltyWidth _ = 0 hunk ./Graphics/PDF/Typesetting.hs 50 -instance Box B where - boxWidth (Text style s) r = textWidth (textFont . textStyle $ style) s - boxWidth (B a) r = boxWidth a r - boxWidth (Glue w yi zi _) r = - if r >= 0 - then - r*yi + w - else - r*zi + w - boxWidth (Penalty _ _ _) _ = 0 - - boxHeight (Text style _) = styleHeight style - boxHeight (B a) = boxHeight a - boxHeight (Glue _ _ _ _) = 0 - boxHeight (Penalty _ _ _) = 0 - - boxDescent (Text style _) = styleDescent style - boxDescent (B a) = boxDescent a - boxDescent (Glue _ _ _ _) = 0 - boxDescent (Penalty _ _ _) = 0 - - strokeBox (Text style s) r x y = drawText $ do + +instance Style style => DisplayableBox (B style) where + strokeBox (Text style s) _ x y = drawText $ do hunk ./Graphics/PDF/Typesetting.hs 61 - strokeBox (Penalty _ _ _) r x y = do + strokeBox (Penalty _ _ _) _ _ _ = do hunk ./Graphics/PDF/Typesetting.hs 67 - strokeBox (Glue w yi zi _) r x y = do + strokeBox (Glue _ _ _ _) _ _ _ = do hunk ./Graphics/PDF/Typesetting.hs 83 -instance Box [B] where - boxWidth l r = foldr (\x y -> y + boxWidth x r) 0.0 l - boxHeight l = maximum . map boxHeight $ l - boxDescent l = maximum . map boxDescent $ l - - strokeBox [] r x y = return () + +-- wordAnalysis is used to detect a full sentence using the same style and return the new position +wordAnalysis :: Style style => style -- ^ Style + -> [B style] -- ^ List of box to display + -> PDFFloat -- ^ Adjustement ration + -> PDFFloat -- ^ x + -> PDFFloat -- ^ y + -> Draw ([B style],PDFFloat) -- ^ New list to process and new position +wordAnalysis _ [] _ x _ = return ([],x) +wordAnalysis style l@(a@(Text s' (PDFString _)):l') r x y | styleCode style == styleCode s' = do + let de = styleDescent s' + he = styleHeight s' + w = boxWidth a r + re = Rectangle x (y - de) (x+w) (y - de + he) + -- Draw word background + (fromJust . wordStyle $ style) re DrawWord (strokeBox a r x y) + -- Draw other boxes + wordAnalysis (updateStyle style) l' r (x + w) y + | otherwise = return (l,x) +wordAnalysis style l@(a@(Glue _ _ _ (Just s)):l') r x y | styleCode style == styleCode s = do + let de = styleDescent s + he = styleHeight s + w = boxWidth a r + re = Rectangle x (y - de) (x+w) (y - de + he) + -- Draw word background + (fromJust . wordStyle $ style) re DrawGlue (return ()) + -- Draw other boxes + wordAnalysis (updateStyle style) l' r (x + w) y + | otherwise = return (l,x) +wordAnalysis _ l _ x _ = return (l,x) + + +-- textStroke is used to build a sentence of words having the same style +-- When we have no more any text or the style is different +-- we display the concatenated text +-- return the new list of boxes and horizontal processing +textStroke:: Style style => style -- ^ Style + -> [B style] -- ^ List of box to display + -> PDFFloat -- ^ Adjustement ration + -> PDFFloat -- ^ x + -> PDFFloat -- ^ y + -> PDFText ([B style],PDFFloat, B.ByteString) -- ^ New list to process and new position and text to display +textStroke _ [] _ x _ = return ([],x,B.empty) +textStroke style l@(a@(Text s' (PDFString t')):l') r x y | styleCode s' == styleCode style = + t' `newText` (textStroke style l' r (x + boxWidth a r) y) + | otherwise = return (l,x,B.empty) +-- That glue is special. It is just a space and we will processed as a space +textStroke style l@(a@(Glue _ _ _ (Just s)):l') r x y | styleCode style == styleCode s = (singleton ' ') `newText` (textStroke style l' r (x + boxWidth a r) y) + | otherwise = return (l,x,B.empty) +textStroke _ l _ x _ = return (l,x,B.empty) + +-- List of box to display in horizontal mode +instance Style style => DisplayableBox [B style] where + strokeBox [] _ _ _ = return () hunk ./Graphics/PDF/Typesetting.hs 139 - strokeBox l@(a@(Text s (PDFString t)):nl) r x y = do + strokeBox l@((Text s (PDFString _)):_) r x y = do hunk ./Graphics/PDF/Typesetting.hs 182 - where - -- wordAnalysis is used to detect a full sentence using the same style and return the new position - wordAnalysis style [] r x y = return ([],x) - wordAnalysis style l@(a@(Text s' (PDFString t')):l') r x y | styleCode style == styleCode s' = do - let de = styleDescent s' - he = styleHeight s' - w = boxWidth a r - re = Rectangle x (y - de) (x+w) (y - de + he) - -- Draw word background - (fromJust . wordStyle $ style) re DrawWord (strokeBox a r x y) - -- Draw other boxes - wordAnalysis (updateStyle style) l' r (x + w) y - | otherwise = return (l,x) - wordAnalysis style l@(a@(Glue _ _ _ (Just s)):l') r x y | styleCode style == styleCode s = do - let de = styleDescent s - he = styleHeight s - w = boxWidth a r - re = Rectangle x (y - de) (x+w) (y - de + he) - -- Draw word background - (fromJust . wordStyle $ style) re DrawGlue (return ()) - -- Draw other boxes - wordAnalysis (updateStyle style) l' r (x + w) y - | otherwise = return (l,x) - wordAnalysis _ l _ x _ = return (l,x) - -- textStroke is used to build a sentence of words having the same style - -- When we have no more any text or the style is different - -- we display the concatenated text - -- return the new list of boxes and horizontal processing - - textStroke _ [] _ x _ = return ([],x,B.empty) - textStroke style l@(a@(Text s' (PDFString t')):l') r x y | styleCode s' == styleCode style = - t' `newText` (textStroke style l' r (x + boxWidth a r) y) - | otherwise = return (l,x,B.empty) - -- That glue is special. It is just a space and we will processed as a space - textStroke style l@(a@(Glue _ _ _ (Just s)):l') r x y | styleCode style == styleCode s = (singleton ' ') `newText` (textStroke style l' r (x + boxWidth a r) y) - | otherwise = return (l,x,B.empty) - textStroke _ l _ x _ = return (l,x,B.empty) + hunk ./Graphics/PDF/Typesetting.hs 188 - -type Text = [CB] -type TextLine = [CB] -type Paragraph = [TextLine] - -data T = T !PDFFont !PDFString deriving(Show) - -instance Box CB where - boxWidth (_,_,_,_,a) = boxWidth a - boxHeight (_,_,_,_,a) = boxHeight a - boxDescent (_,_,_,_,a) = boxDescent a - strokeBox (_,_,_,_,a) = strokeBox a - - ---instance Box T where --- boxWidth (T f s) _ = textWidth f s --- boxHeight (T f _) = getHeight f --- boxDescent (T f _) = getDescent f --- --- strokeBox (T f s) r x y = do --- drawText $ text f x y s --- --withNewContext $ do --- -- setWidth 0.5 --- -- drawText $ text f x y s --- -- strokeColor red --- -- stroke $ Rectangle x (y - (getDescent f)) (x + textWidth f s) (y - getDescent f + getHeight f) - --- | Value modeling infinity -infinity :: PDFFloat -infinity = 10000 - -infix 4 =~ -(=~) :: PDFFloat -> PDFFloat -> Bool -a =~ b = abs (a-b) <= 1e-3 - -data BreakNode = BreakNode { totalWidth :: !PDFFloat - , totalDilatation :: !PDFFloat - , totalCompression :: !PDFFloat - , demerit :: !PDFFloat - , flagged :: !Bool - , fitnessValue :: !Int - , ratio :: !PDFFloat - , previous :: Maybe (Int,Int,Int,BreakNode) - } - deriving(Show) - -adjustRatio :: BreakNode - -> ZList - -> PDFFloat - -> PDFFloat -adjustRatio a l maxw = - let w = cumulatedW l - totalWidth a + penaltyWidth (box l) - y = cumulatedY l - totalDilatation a - z = cumulatedZ l - totalCompression a - in - if w == maxw - then 0.0 - else if w < maxw - then - if y > 0.0 then ((maxw - w) / y) else infinity - else - if z > 0.0 then ((maxw - w) / z) else infinity - -badness :: PDFFloat -> PDFFloat -badness r = if r < (-1) then infinity else 100.0 * abs(r)**3.0 - -fitness :: PDFFloat -> Int -fitness r = - if r < (-0.5) - then - 0 - else if r <= (-0.5) - then - 1 - else - if r <= 1 - then - 2 - else - 3 - -computeDemerit :: Bool - -> PDFFloat -- ^ adjust ratio - -> BreakNode -- ^ Flag for previous - -> ZList -- ^ Flag for current - -> Maybe(PDFFloat,Int) -- ^ Demerit for the breakpoint -computeDemerit sndPass r a z = - let b = badness r - p = getPenalty z - fitness' = fitness r - tolerance = if sndPass then 3.0 else 1.0 - in - if (-1 <= r) && (r <= tolerance) - then - let fld = if isFlagged z && (flagged a) then flagged_demerit else 0.0 - fid = if fitness' /= (fitnessValue a) then fitness_demerit else 0.0 - dem = if b >= infinity - then - infinity - else - if p >= 0 - then - fld + (1.0 + b + p) ** 2.0 - else if p < 0 && p > (-infinity) - then - fld + (1.0 + b) ** 2.0 - p**2.0 - else - fld + (1.0 + b) ** 2.0 - in - Just (dem,fitness') - else - Nothing - -data MaybeCB = NoCB - | OneCB !CB - deriving(Show) - -data ZList = ZList (MaybeCB) (PDFFloat,PDFFloat,PDFFloat,Int,B) [B] deriving(Show) - - -createZList :: [B] -> ZList -createZList [] = error "List cannot be empty to create a zipper" -createZList l = ZList NoCB (0,0,0,1,head l) (tail l) - -theEnd :: ZList -> Bool -theEnd (ZList _ _ []) = True -theEnd _ = False - --- | We create a new breakpoint but we get the cumulated dimensions only at the next box following the break --- since glues and penalties are removed at the beginning of a line -createBreaknode :: Maybe (Int,Int,Int,BreakNode) -> ZList -> BreakNode -createBreaknode prev (ZList _ (w,y,z,_,Penalty w' _ f) []) = BreakNode (w + w') (y) (z) 0.0 f 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,Glue w' y' z' _) []) = BreakNode (w + w') (y+y') (z+z') 0.0 False 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,a) []) = BreakNode (w + boxWidth a 0.0) (y) (z) 0.0 False 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,Penalty _ p f) _) | p <= (-infinity) = BreakNode w y z 0.0 f 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,B _) _) = BreakNode w y z 0.0 False 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,Text _ _) _) = BreakNode w y z 0.0 False 0 0.0 prev -createBreaknode prev z = createBreaknode prev (moveRight z) - - -moveRight :: ZList -> ZList -moveRight (ZList l c@(w,y,z,p,Glue w' y' z' _) r) = - let w'' = w + w' - y''=y+y' - z''=z+z' - in - ZList (OneCB c) (w'',y'',z'',p+1,head r) (tail r) -moveRight (ZList l c@(w,y,z,p,a) r) = - let w' = boxWidth a 0.0 - w'' = w + w' - in - ZList (OneCB c) (w'',y,z,p+1,head r) (tail r) - ---moveLeft :: ZList -> ZList ---moveLeft (ZList l c r) = ZList (tail l) (head l) ((box c):r) - ---fromZlist :: ZList -> [B] ---fromZlist (ZList l c r) = (reverse . map box $ l) ++ [box c] ++ r - -isFeasibleBreakpoint :: ZList -> Bool -isFeasibleBreakpoint (ZList _ (_,_,_,_,Penalty _ p _) _) = p < infinity -isFeasibleBreakpoint (ZList NoCB _ _) = False -isFeasibleBreakpoint (ZList (OneCB (_,_,_,_,B _)) (_,_,_,_,Glue _ _ _ _) _) = True -isFeasibleBreakpoint (ZList (OneCB (_,_,_,_,Text _ _)) (_,_,_,_,Glue _ _ _ _) _) = True -isFeasibleBreakpoint _ = False - + hunk ./Graphics/PDF/Typesetting.hs 190 -endParagraphBoxes :: [B] -endParagraphBoxes = [Penalty 0 (infinity+1) False,Glue 0 (infinity+1) 0 Nothing,Penalty 0 (-infinity -1) True] +endParagraphBoxes :: [B s] +endParagraphBoxes = [Penalty 0 infinity False,Glue 0 10000.0 0 Nothing,Penalty 0 (-infinity) True] hunk ./Graphics/PDF/Typesetting.hs 193 --- | Display a list of boxes with the given line breaks -displayWithBreaks :: PDFFloat -> PDFFloat -> [B] -> Int -> [(PDFFloat,Int)] -> Draw () -displayWithBreaks x y t _ [] = do - unless (null t) $ do - let y' = y + boxDescent t - boxHeight t - strokeBox (simplify t) 0.0 x y' -displayWithBreaks x y t c ((ra,ba):l) = do - let (theLine,t') = splitAt (ba-c) t - unless (null theLine) $ do - let h = boxHeight theLine - d = boxDescent theLine - y' = y + d - h - strokeBox (simplify theLine) ra x y' - displayWithBreaks x (y- h) t' ba l +-- | Display a list of boxes +displayWithBreaks :: Style s => PDFFloat -- ^ x + -> PDFFloat -- ^ y + -> [(PDFFloat,[B s])] -- ^ Line and adaptation ratio + -> Draw () -- ^ Drawing +displayWithBreaks _ _ [] = return () +displayWithBreaks x y ((r,theLine):l) = do + let h = boxHeight theLine + y' = y + boxDescent theLine - h + strokeBox theLine r x y' + displayWithBreaks x (y - h) l hunk ./Graphics/PDF/Typesetting.hs 205 -simplify :: [B] -> [B] -simplify ((Glue _ _ _ _):l) = simplify l -simplify ((Penalty _ _ _):l) = simplify l -simplify l = l - -fitness_demerit :: PDFFloat -fitness_demerit = 100 - -flagged_demerit :: PDFFloat -flagged_demerit = 100 - --- Update a feasible breakpoint remembering only the best one -type PossibleBreak = ActiveNodes -- Line, demerit and break node -type ActiveNodes = Map.Map (Int,Int,Int) BreakNode - -updateBreak :: BreakNode - -> BreakNode - -> BreakNode -updateBreak a b = if demerit a < demerit b then a else b - +-- | Display a formatted text at a given position with a given default style +displayFormattedText :: Style d => PDFFloat -- ^ Horizontal position + -> PDFFloat -- ^ Vertical position + -> PDFFloat -- ^ Max width + -> d -- ^ Default style + -> TM a -- ^ Typesetting monad + -> Draw a -- ^ Draw monad +displayFormattedText x y maxw defaultStyle t = do + let (a, _, boxes) = (runRWS . unTM $ t >>= \x' -> do {endParagraph ; return x'} ) () (TMState (AnyStyle defaultStyle)) + l = formatList maxw boxes + displayWithBreaks x y l + return a hunk ./Graphics/PDF/Typesetting.hs 218 -addBreaks :: ActiveNodes -> ActiveNodes -> ActiveNodes -addBreaks a b = Map.union (Map.filter (\x -> demerit x < infinity) a) b - - --- | Check is a break point is possible --- otherwise, if none is possible and there is only one remaining active point, --- we force a breakpoint -updateWithNewRIfNoSolution :: Bool - -> PDFFloat -- ^ Old r - -> ZList -- ^ Current - -> (Int,Int,Int) - -> PossibleBreak - -> ActiveNodes -- ^ Actives - -> (PDFFloat -> ActiveNodes -> (PossibleBreak,ActiveNodes)) - -> (PossibleBreak,ActiveNodes) -updateWithNewRIfNoSolution sndPass r z key newbreak newmap f = - if r < -1 - then - --if Map.size newmap > 1 then (newbreak,Map.delete key newmap) else f (-0.99) (Map.delete key newmap) - if sndPass - then - f (-0.99) (Map.delete key newmap) - else - (newbreak,Map.delete key newmap) - else if isForcedBreak z - then - f r (Map.delete key newmap) - else - f r newmap - -getNewActiveBreakpoints :: Bool -> PDFFloat -> ActiveNodes -> ZList -> (PossibleBreak,ActiveNodes) -getNewActiveBreakpoints sndPass maxw actives z = - if isFeasibleBreakpoint z - then - let analyzeActive key@(p,line,f) b (newbreak,newmap') = - let r' = adjustRatio b z maxw - in - updateWithNewRIfNoSolution sndPass r' z key newbreak newmap' $ - \r newmap -> let dem' = computeDemerit sndPass r b z in - case dem' of - Nothing -> (newbreak,newmap) - Just (d',f') -> - let b' = createBreaknode (Just (p,line,f,b)) z in - -- We keep only the best new break - (Map.insertWith updateBreak (position z,line+1,f') (b' {demerit = d',fitnessValue = f', ratio = r}) newbreak ,newmap) - in - let (breaks',actives') = Map.foldWithKey analyzeActive (Map.empty,actives) actives - dmin = minimum . map demerit . Map.elems $ breaks' - in - (Map.filter (\x -> demerit x < dmin + fitness_demerit) breaks', actives') - else - (Map.empty,actives ) - -genNodeList :: (Int,Int,Int,BreakNode) -> [(PDFFloat,Int)] -genNodeList b@(p,l,f,BreakNode _ _ _ _ _ _ r Nothing) = [(r,p)] -genNodeList b@(p,l,f,BreakNode _ _ _ _ _ _ r (Just previous)) = (r,p):genNodeList previous - - -analyzeBoxes :: Bool -> PDFFloat -> ActiveNodes -> ZList -> [(PDFFloat,Int)] -analyzeBoxes pass maxw actives z = - let getMinBreak b' = (\((x,y,z),w) -> (x,y,z,w)) . minimumBy (\(ka,a) (kb,b) -> compare (demerit a) (demerit b)) . Map.toList $ b' - (breaks',actives') = getNewActiveBreakpoints pass maxw actives z - newActives = Map.union breaks' actives' - getRightOrderNodeList = tail . reverse . genNodeList - getKey (a,b,c,_) = (a,b,c) - getNode (_,_,_,BreakNode a b c d e f r _) = BreakNode a b c d e f r Nothing - in - -- If forced breakpoint of no bearkpoint found - if Map.null actives' - then - -- If no breakpoint found - if Map.null breaks' - then - -- Second pass analysis - analyzeBoxes True maxw actives z - else - -- Forced breakpoint then we gen a list from it and continue the analysis - let minBreak = getMinBreak breaks' in - if theEnd z - then - getRightOrderNodeList minBreak - else - getRightOrderNodeList minBreak ++ analyzeBoxes pass maxw (Map.insert (getKey minBreak) (getNode minBreak) Map.empty) (moveRight z) - -- Normal feasible breakpoint - else - let minBreak = getMinBreak breaks' in - -- If the end it must be a possible breakpoint - -- We should NEVER reach this part. The end should always be a forced breakpoint - if theEnd z - then - getRightOrderNodeList minBreak - else - -- We continue the analysis - analyzeBoxes pass maxw newActives (moveRight z) - --- M.insert (0,0,1) (BreakNode 0 0 0 0) -formatText :: PDFFloat -> [B] -> [(PDFFloat,Int)] -formatText maxw boxes = - let active = Map.insert (0,0,1) (BreakNode 0 0 0 0 False 0 0.0 Nothing) Map.empty - in - analyzeBoxes False maxw active (createZList boxes) - hunk ./Graphics/PDF/Typesetting.hs 223 -addSpacesToLine :: AnyStyle -> B -> [B.ByteString] -> [B] +addSpacesToLine :: AnyStyle -> B AnyStyle -> [B.ByteString] -> [B AnyStyle] hunk ./Graphics/PDF/Typesetting.hs 246 -endParagraph = tell endParagraphBoxes - --- | Display a formatted text at a given position with a given default style -displayFormattedText :: Style d => PDFFloat -- ^ Horizontal position - -> PDFFloat -- ^ Vertical position - -> PDFFloat -- ^ Max width - -> d -- ^ Default style - -> TM a -- ^ Typesetting monad - -> Draw a -- ^ Draw monad -displayFormattedText x y maxw defaultStyle t = do - let (a, _, boxes) = (runRWS . unTM $ t >>= \x -> do {endParagraph ; return x} ) () (TMState (AnyStyle defaultStyle)) - l = formatText maxw boxes - displayWithBreaks x y boxes 1 l - return a +endParagraph = TM $ tell endParagraphBoxes hunk ./Graphics/PDF/Typesetting.hs 250 -newtype TM a = TM { unTM :: RWS () [B] TMState a} deriving(Monad,MonadWriter [B], MonadState TMState, Functor) +newtype TM a = TM { unTM :: RWS () [B AnyStyle] TMState a} deriving(Monad,MonadWriter [B AnyStyle], MonadState TMState, Functor) hunk ./Graphics/PDF/Typesetting.hs 280 - -> PDFFloat -- ^ Penalty value + -> Int -- ^ Penalty value hunk ./Graphics/PDF/Typesetting.hs 285 -addBox :: (Show a, Box a) => a -> TM () +addBox :: (Show a, DisplayableBox a, Box a) => a -> TM () addfile ./Graphics/PDF/Typesetting/Breaking.hs hunk ./Graphics/PDF/Typesetting/Breaking.hs 1 - +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2006 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Breaking algorithm used to split a paragraph into lines +-- or a text into pages +--------------------------------------------------------- +-- #hide +module Graphics.PDF.Typesetting.Breaking ( +-- BreakNode(..) +-- , MaybeCB(..) +-- , ZList(..) +-- , PossibleBreak +-- , ActiveNodes(..) + B(..) +-- , CB +-- , adjustRatio +-- , badness +-- , fitness +-- , computeDemerit +-- , createZList +-- , theEnd +-- , createBreaknode +-- , moveRight +-- , isFeasibleBreakpoint +-- , fitness_demerit +-- , flagged_demerit +-- , updateBreak +-- , addBreaks +-- , updateWithNewRIfNoSolution +-- , getNewActiveBreakpoints +-- , genNodeList +-- , analyzeBoxes + , formatList +-- , infinity +-- , PointedBox(..) + , Box(..) +-- , penaltyWidth + , DisplayableBox(..) + , Style(..) + , TextStyle(..) + , StyleFunction(..) + , AnyStyle(..) +-- , cutList + , infinity + ) where + +import Graphics.PDF.LowLevel.Types +import Data.List(minimumBy) +import qualified Data.Map as Map +import Graphics.PDF.Text +import Graphics.PDF.Draw +import Graphics.PDF.Shapes +import Data.Maybe(fromJust) + +data TextStyle = TextStyle { textFont :: !PDFFont + , textStrokeColor :: !Color + , textFillColor :: !Color + , textMode :: !TextMode + , penWidth :: !PDFFloat + , scaleSpace :: !PDFFloat -- Scaling factor for normal space size + , scaleDilatation :: !PDFFloat + , scaleCompression :: !PDFFloat + } + deriving(Eq) + +-- | What kind of style drawing function is required for a word +-- when word styling is enabled +data StyleFunction = DrawWord + | DrawGlue + deriving(Eq) + +class Style a where + sentenceStyle :: a -> Rectangle -> Draw () + wordStyle :: a -> Maybe (Rectangle -> StyleFunction -> Draw b -> Draw ()) + textStyle :: a -> TextStyle + styleCode :: a -> Int + updateStyle :: a -> a + wordTransform :: a -> [B AnyStyle] -> [B AnyStyle] + wordTransform _ x = x + styleHeight :: a -> PDFFloat + styleDescent :: a -> PDFFloat + styleHeight = getHeight . textFont . textStyle + styleDescent = getDescent . textFont . textStyle + +data AnyStyle = forall a. (Style a) => AnyStyle a + +instance Style AnyStyle where + sentenceStyle (AnyStyle a) = sentenceStyle a + wordStyle (AnyStyle a) = wordStyle a + textStyle (AnyStyle a) = textStyle a + styleCode (AnyStyle a) = styleCode a + updateStyle (AnyStyle a) = AnyStyle $ updateStyle a + wordTransform (AnyStyle a) = wordTransform a + styleHeight (AnyStyle a) = styleHeight a + styleDescent (AnyStyle a) = styleDescent a + +class Box a where + boxWidth :: a -> PDFFloat -> PDFFloat + boxHeight :: a -> PDFFloat + boxDescent :: a -> PDFFloat + +class DisplayableBox a where + strokeBox :: a -> PDFFloat -> PDFFloat -> PDFFloat -> Draw () + +data B style = forall a. (Show a,Box a, DisplayableBox a) => B !a + | Glue !PDFFloat !PDFFloat !PDFFloat !(Maybe style) + | Penalty !PDFFloat !Int !Bool + | Text !style !PDFString + +instance Style style => Box (B style) where + boxWidth (Text style s) _ = textWidth (textFont . textStyle $ style) s + boxWidth (B a) r = boxWidth a r + boxWidth (Glue w yi zi _) r = + if r >= 0 + then + r*yi + w + else + r*zi + w + boxWidth (Penalty _ _ _) _ = 0 + + boxHeight (Text style _) = styleHeight style + boxHeight (B a) = boxHeight a + boxHeight (Glue _ _ _ _) = 0 + boxHeight (Penalty _ _ _) = 0 + + boxDescent (Text style _) = styleDescent style + boxDescent (B a) = boxDescent a + boxDescent (Glue _ _ _ _) = 0 + boxDescent (Penalty _ _ _) = 0 + +instance Style style => Box [B style] where + boxWidth l r = foldr (\x y -> y + boxWidth x r) 0.0 l + boxHeight l = maximum . map boxHeight $ l + boxDescent l = maximum . map boxDescent $ l + +instance Show (B style) where + show (B a) = "(B " ++ show a ++ ")" + show (Glue a b c _) = "(Glue " ++ show a ++ " " ++ show b ++ " " ++ show c ++ ")" + show (Penalty a b c) = "(Penalty " ++ show a ++ " " ++ show b ++ " " ++ show c ++ ")" + show (Text _ t) = "(Text " ++ show t ++ ")" + + +type CB a = (PDFFloat,PDFFloat,PDFFloat,Int,a) + +instance DisplayableBox a => DisplayableBox (CB a) where + strokeBox (_,_,_,_,a) = strokeBox a + +instance Box a => Box (CB a) where + boxWidth (_,_,_,_,a) = boxWidth a + boxHeight (_,_,_,_,a) = boxHeight a + boxDescent (_,_,_,_,a) = boxDescent a + +class PointedBox a style | a -> style where + isFlagged :: a -> Bool + getPenalty :: a -> Int + isPenalty :: a -> Bool + box :: a -> B style + position :: a -> Int + cumulatedW :: a -> PDFFloat + cumulatedY :: a -> PDFFloat + cumulatedZ :: a -> PDFFloat + isForcedBreak :: a -> Bool + +instance PointedBox (PDFFloat,PDFFloat,PDFFloat,Int,B style) style where + isFlagged (_,_,_,_,Penalty _ _ f) = f + isFlagged _ = False + isPenalty (_,_,_,_,Penalty _ _ _) = True + isPenalty _ = False + getPenalty (_,_,_,_,Penalty _ p _) = p + getPenalty _ = 0 + box (_,_,_,_,a) = a + position (_,_,_,p,_) = p + cumulatedW (w,_,_,_,_) = w + cumulatedY (_,y,_,_,_) = y + cumulatedZ (_,_,z,_,_) = z + isForcedBreak (_,_,_,_,Penalty _ p _) = p <= (-infinity) + isForcedBreak _ = False + + +instance PointedBox (ZList style) style where + isPenalty (ZList _ b _) = isPenalty b + isFlagged (ZList _ b _) = isFlagged b + box (ZList _ b _) = box b + position (ZList _ b _) = position b + cumulatedW (ZList _ b _) = cumulatedW b + cumulatedY (ZList _ b _) = cumulatedY b + cumulatedZ (ZList _ b _) = cumulatedZ b + getPenalty (ZList _ b _) = getPenalty b + isForcedBreak (ZList _ b _) = isForcedBreak b + +-- A penalty has no width unless you break on it so it needs a special processing +penaltyWidth :: B style -> PDFFloat +penaltyWidth (Penalty w _ _) = w +penaltyWidth _ = 0 + +data BreakNode = BreakNode { totalWidth :: !PDFFloat + , totalDilatation :: !PDFFloat + , totalCompression :: !PDFFloat + , demerit :: !PDFFloat + , flagged :: !Bool + , fitnessValue :: !Int + , ratio :: !PDFFloat + , previous :: Maybe (Int,Int,Int,BreakNode) + } + deriving(Show) + +adjustRatio :: BreakNode + -> ZList style + -> PDFFloat + -> PDFFloat +adjustRatio a l maxw = + let w = cumulatedW l - totalWidth a + penaltyWidth (box l) + y = cumulatedY l - totalDilatation a + z = cumulatedZ l - totalCompression a + in + if w == maxw + then 0.0 + else if w < maxw + then + if y > 0.0 then ((maxw - w) / y) else bigAdjustRatio + else + if z > 0.0 then ((maxw - w) / z) else bigAdjustRatio + +badness :: PDFFloat -> PDFFloat +badness r = if r < (-1) then bigAdjustRatio else 100.0 * abs(r)**3.0 + +fitness :: PDFFloat -> Int +fitness r = + if r < (-0.5) + then + 0 + else if r <= (-0.5) + then + 1 + else + if r <= 1 + then + 2 + else + 3 + +computeDemerit :: Bool + -> PDFFloat -- ^ adjust ratio + -> BreakNode -- ^ Flag for previous + -> ZList style -- ^ Flag for current + -> Maybe(PDFFloat,Int) -- ^ Demerit for the breakpoint +computeDemerit sndPass r a z = + let b = badness r + p = getPenalty z + fitness' = fitness r + tolerance = if sndPass then 3.0 else 1.0 + in + if (-1 <= r) && (r <= tolerance) + then + let fld = if isFlagged z && (flagged a) then flagged_demerit else 0.0 + fid = if fitness' /= (fitnessValue a) then fitness_demerit else 0.0 + dem = if p >= 0 + then + fid + fld + (1.0 + b + (fromIntegral p)) ** 2.0 + else if p < 0 && p > (-infinity) + then + fid + fld + (1.0 + b) ** 2.0 - (fromIntegral p)**2.0 + else + fid + fld + (1.0 + b) ** 2.0 + in + Just (dem,fitness') + else + Nothing + +data MaybeCB a = NoCB + | OneCB !(CB a) + deriving(Show) + +data ZList style = ZList (MaybeCB (B style)) (PDFFloat,PDFFloat,PDFFloat,Int,B style) [B style] deriving(Show) + + +createZList :: [B style] -> ZList style +createZList [] = error "List cannot be empty to create a zipper" +createZList l = ZList NoCB (0,0,0,1,head l) (tail l) + +theEnd :: ZList style -> Bool +theEnd (ZList _ _ []) = True +theEnd _ = False + +-- | We create a new breakpoint but we get the cumulated dimensions only at the next box following the break +-- since glues and penalties are removed at the beginning of a line +createBreaknode :: Style style => Maybe (Int,Int,Int,BreakNode) -> ZList style -> BreakNode +createBreaknode prev (ZList _ (w,y,z,_,Penalty w' _ f) []) = BreakNode (w + w') (y) (z) 0.0 f 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,Glue w' y' z' _) []) = BreakNode (w + w') (y+y') (z+z') 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,a) []) = BreakNode (w + boxWidth a 0.0) (y) (z) 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,Penalty _ p f) _) | p <= (-infinity) = BreakNode w y z 0.0 f 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,B _) _) = BreakNode w y z 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,Text _ _) _) = BreakNode w y z 0.0 False 0 0.0 prev +createBreaknode prev z = createBreaknode prev (moveRight z) + + +moveRight :: Style style => ZList style -> ZList style +moveRight (ZList _ c@(w,y,z,p,Glue w' y' z' _) r) = + let w'' = w + w' + y''=y+y' + z''=z+z' + in + ZList (OneCB c) (w'',y'',z'',p+1,head r) (tail r) +moveRight (ZList _ c@(w,y,z,p,a) r) = + let w' = boxWidth a 0.0 + w'' = w + w' + in + ZList (OneCB c) (w'',y,z,p+1,head r) (tail r) + +--moveLeft :: ZList -> ZList +--moveLeft (ZList l c r) = ZList (tail l) (head l) ((box c):r) + +--fromZlist :: ZList -> [B] +--fromZlist (ZList l c r) = (reverse . map box $ l) ++ [box c] ++ r + +isFeasibleBreakpoint :: ZList style -> Bool +isFeasibleBreakpoint (ZList _ (_,_,_,_,Penalty _ p _) _) = p < infinity +isFeasibleBreakpoint (ZList NoCB _ _) = False +isFeasibleBreakpoint (ZList (OneCB (_,_,_,_,B _)) (_,_,_,_,Glue _ _ _ _) _) = True +isFeasibleBreakpoint (ZList (OneCB (_,_,_,_,Text _ _)) (_,_,_,_,Glue _ _ _ _) _) = True +isFeasibleBreakpoint _ = False + + +fitness_demerit :: PDFFloat +fitness_demerit = 100 + +flagged_demerit :: PDFFloat +flagged_demerit = 100 + +-- Update a feasible breakpoint remembering only the best one +type PossibleBreak = ActiveNodes -- Line, demerit and break node +type ActiveNodes = Map.Map (Int,Int,Int) BreakNode + +updateBreak :: BreakNode + -> BreakNode + -> BreakNode +updateBreak a b = if demerit a < demerit b then a else b + +-- | Check is a break point is possible +-- otherwise, if none is possible and there is only one remaining active point, +-- we force a breakpoint +updateWithNewRIfNoSolution :: Bool + -> PDFFloat -- ^ Old r + -> ZList style -- ^ Current + -> (Int,Int,Int) + -> PossibleBreak + -> ActiveNodes -- ^ Actives + -> (PDFFloat -> ActiveNodes -> (PossibleBreak,ActiveNodes)) + -> (PossibleBreak,ActiveNodes) +updateWithNewRIfNoSolution sndPass r z key newbreak newmap f = + if r < -1 + then + --if Map.size newmap > 1 then (newbreak,Map.delete key newmap) else f (-0.99) (Map.delete key newmap) + if sndPass + then + f (-0.99) (Map.delete key newmap) + else + (newbreak,Map.delete key newmap) + else if isForcedBreak z + then + f r (Map.delete key newmap) + else + f r newmap + +getNewActiveBreakpoints :: Style style => Bool -> PDFFloat -> ActiveNodes -> ZList style -> (PossibleBreak,ActiveNodes) +getNewActiveBreakpoints sndPass maxw actives z = + if isFeasibleBreakpoint z + then + let analyzeActive key@(p,line,f) b (newbreak,newmap') = + let r' = adjustRatio b z maxw + in + updateWithNewRIfNoSolution sndPass r' z key newbreak newmap' $ + \r newmap -> let dem' = computeDemerit sndPass r b z in + case dem' of + Nothing -> (newbreak,newmap) + Just (d',f') -> + let b' = createBreaknode (Just (p,line,f,b)) z in + -- We keep only the best new break + (Map.insertWith updateBreak (position z,line+1,f') (b' {demerit = d',fitnessValue = f', ratio = r}) newbreak ,newmap) + in + let (breaks',actives') = Map.foldWithKey analyzeActive (Map.empty,actives) actives + dmin = minimum . map demerit . Map.elems $ breaks' + in + (Map.filter (\x -> demerit x < dmin + fitness_demerit) breaks', actives') + else + (Map.empty,actives ) + +-- (position, line, fitness) -> (adjust ratio, break position) +genNodeList :: (Int,Int,Int,BreakNode) -> [(PDFFloat,Int)] +genNodeList (p,_,_,b@(BreakNode _ _ _ _ _ _ _ Nothing)) = [(ratio b,p)] +genNodeList (p,_,_,b@(BreakNode _ _ _ _ _ _ _ (Just _))) = (ratio b,p):genNodeList (fromJust . previous $ b) + + +analyzeBoxes :: Style style => Bool -> PDFFloat -> ActiveNodes -> ZList style -> [(PDFFloat,Int)] +analyzeBoxes pass maxw actives z = + let getMinBreak b' = (\((xc,yc,zc),w) -> (xc,yc,zc,w)) . minimumBy (\(_,a) (_,b) -> compare (demerit a) (demerit b)) . Map.toList $ b' + (breaks',actives') = getNewActiveBreakpoints pass maxw actives z + newActives = Map.union breaks' actives' + getRightOrderNodeList = tail . reverse . genNodeList + getKey (a,b,c,_) = (a,b,c) + getNode (_,_,_,BreakNode a b c d e f r _) = BreakNode a b c d e f r Nothing + in + -- If forced breakpoint of no bearkpoint found + if Map.null actives' + then + -- If no breakpoint found + if Map.null breaks' + then + -- Second pass analysis + analyzeBoxes True maxw actives z + else + -- Forced breakpoint then we gen a list from it and continue the analysis + let minBreak = getMinBreak breaks' in + if theEnd z + then + getRightOrderNodeList minBreak + else + getRightOrderNodeList minBreak ++ analyzeBoxes pass maxw (Map.insert (getKey minBreak) (getNode minBreak) Map.empty) (moveRight z) + -- Normal feasible breakpoint + else + let minBreak = getMinBreak breaks' in + -- If the end it must be a possible breakpoint + -- We should NEVER reach this part. The end should always be a forced breakpoint + if theEnd z + then + getRightOrderNodeList minBreak + else + -- We continue the analysis + analyzeBoxes pass maxw newActives (moveRight z) + +simplify :: [B s] -> [B s] +simplify ((Glue _ _ _ _):l) = simplify l +simplify ((Penalty _ _ _):l) = simplify l +simplify l = l + +cutList :: [B style] -> Int -> [(PDFFloat,Int)] -> [(PDFFloat,[B style])] +cutList t _ [] = [(0.0,simplify t)] +cutList t c ((ra,ba):l) = + let (theLine,t') = splitAt (ba-c) t in + if null theLine + then + [] + else + (ra,simplify theLine) : cutList t' ba l + +formatList :: Style style => PDFFloat -> [B style] -> [(PDFFloat,[B style])] +formatList maxw boxes = + let active = Map.insert (0,0,1) (BreakNode 0 0 0 0 False 0 0.0 Nothing) Map.empty + theBreaks = analyzeBoxes False maxw active (createZList boxes) + in + cutList boxes 1 theBreaks + +-- | Value modeling infinity +infinity :: Int +infinity = 10000 + +bigAdjustRatio :: PDFFloat +bigAdjustRatio = 10000.0 hunk ./HPDF.cabal 53 + Graphics.PDF.Typesetting.Breaking hunk ./Graphics/PDF/Typesetting/Breaking.hs 51 + , createTextBox + , glue + , penalty + , spaceGlue + , asAny + , horizontalPostProcess + , isSameStyle hunk ./Graphics/PDF/Typesetting/Breaking.hs 66 -import Data.Maybe(fromJust) +import Data.Maybe(isJust,fromJust) +import Graphics.PDF.Colors +import Data.ByteString.Lazy.Char8(singleton) +import qualified Data.ByteString.Lazy as B(ByteString,append) hunk ./Graphics/PDF/Typesetting/Breaking.hs 89 - sentenceStyle :: a -> Rectangle -> Draw () + sentenceStyle :: a -> Maybe (Rectangle -> Draw b -> Draw ()) hunk ./Graphics/PDF/Typesetting/Breaking.hs 124 - | Text !style !PDFString + | Text !style !PDFString !PDFFloat hunk ./Graphics/PDF/Typesetting/Breaking.hs 126 + + hunk ./Graphics/PDF/Typesetting/Breaking.hs 129 - boxWidth (Text style s) _ = textWidth (textFont . textStyle $ style) s + boxWidth (Text _ _ w) _ = w hunk ./Graphics/PDF/Typesetting/Breaking.hs 139 - boxHeight (Text style _) = styleHeight style + boxHeight (Text style _ _) = styleHeight style hunk ./Graphics/PDF/Typesetting/Breaking.hs 144 - boxDescent (Text style _) = styleDescent style + boxDescent (Text style _ _) = styleDescent style hunk ./Graphics/PDF/Typesetting/Breaking.hs 147 - boxDescent (Penalty _ _ _) = 0 + boxDescent (Penalty _ _ _) = 0 + +-- Draw a text box +drawTheTextBox :: Style style => style + -> PDFFloat + -> PDFFloat + -> PDFFloat + -> PDFString + -> Draw () +drawTheTextBox style r x y t = drawText $ do + setFont (textFont . textStyle $ style) + strokeColor (textStrokeColor . textStyle $ style) + fillColor (textFillColor . textStyle $ style) + renderMode (textMode . textStyle $ style) + --setWidth (penWidth . textStyle $ s) + -- Here we need to dilate the space to take into account r and the font setting + let ws = (textWidth (textFont . textStyle $ style) (toPDFString " ")) + h = scaleSpace . textStyle $ style + sy = scaleDilatation . textStyle $ style + sz = scaleCompression . textStyle $ style + dws = ws * h -- dilated space + gy = sy*dws / 2.0 + gz = sz*dws / 3.0 + delta = if r >= 0 then r*gy else r*gz + -- ws is the true font space. We use dws so we have a user overhead + -- and the overhead of the space dilatation + wordSpace (dws - ws + delta) + -- And we render the text + textStart x y + displayText t + +instance Style style => DisplayableBox (B style) where + strokeBox (Glue w _ _ (Just style)) _ x y = do + let de = styleDescent style + he = styleHeight style + -- In word mode we have to apply a special function to the word + -- otherwise we apply a different function to the sentence + if (isJust . wordStyle $ style) + then + (fromJust . wordStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) DrawGlue (return ()) + else + return () + + strokeBox (Text style t w) r x y = do + let de = styleDescent style + he = styleHeight style + -- In word mode we have to apply a special function to the word + -- otherwise we apply a different function to the sentence + if (isJust . wordStyle $ style) + then + (fromJust . wordStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) DrawWord (drawTheTextBox style r x y t) + else + if (isJust . sentenceStyle $ style) + then + (fromJust . sentenceStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) (drawTheTextBox style r x y t) + else + drawTheTextBox style r x y t + + strokeBox (B a) r x y = strokeBox a r x y + strokeBox (Penalty _ _ _) _ _ _ = return () + strokeBox (Glue _ _ _ _) _ _ _ = return () + +-- No special display for a simple list of boxes +instance (Style s) => DisplayableBox [B s] where + strokeBox [] _ _ _ = return () + + strokeBox (a:l) r x y = do + strokeBox a r x y + strokeBox l r (x + boxWidth a r) y hunk ./Graphics/PDF/Typesetting/Breaking.hs 217 -instance Style style => Box [B style] where +instance Box a => Box [a] where hunk ./Graphics/PDF/Typesetting/Breaking.hs 226 - show (Text _ t) = "(Text " ++ show t ++ ")" + show (Text _ t _) = "(Text " ++ show t ++ ")" hunk ./Graphics/PDF/Typesetting/Breaking.hs 379 -createBreaknode prev (ZList _ (w,y,z,_,Text _ _) _) = BreakNode w y z 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,Text _ _ _) _) = BreakNode w y z 0.0 False 0 0.0 prev hunk ./Graphics/PDF/Typesetting/Breaking.hs 406 -isFeasibleBreakpoint (ZList (OneCB (_,_,_,_,Text _ _)) (_,_,_,_,Glue _ _ _ _) _) = True +isFeasibleBreakpoint (ZList (OneCB (_,_,_,_,Text _ _ _)) (_,_,_,_,Glue _ _ _ _) _) = True hunk ./Graphics/PDF/Typesetting/Breaking.hs 517 +-- Remove glues and penalties at the beginning of a line hunk ./Graphics/PDF/Typesetting/Breaking.hs 523 +-- Use a list of breakpoint and adjustement ratios to generate a list of lines hunk ./Graphics/PDF/Typesetting/Breaking.hs 525 -cutList t _ [] = [(0.0,simplify t)] +cutList t _ [] = [(0.0,t)] hunk ./Graphics/PDF/Typesetting/Breaking.hs 532 - (ra,simplify theLine) : cutList t' ba l + (ra,theLine) : cutList t' ba l hunk ./Graphics/PDF/Typesetting/Breaking.hs 534 +-- Compute the breakpoints and generate a list of lines with the adjustement ratios +-- The line are not interpreted. Some additional postprocessing is required +-- for horizontal lines of vertical boxes hunk ./Graphics/PDF/Typesetting/Breaking.hs 550 + +-- | Add a glue to the stream +glue :: Style style => PDFFloat -- ^ Glue width + -> PDFFloat -- ^ Glue dilatation + -> PDFFloat -- ^ Glue compression + -> B style +glue w y z = Glue w y z Nothing + +-- | Add a glue to the stream +spaceGlue :: Style style => style -- ^ The style + -> B style +spaceGlue s = + let ws = (textWidth (textFont . textStyle $ s) (toPDFString " ") ) + h = scaleSpace . textStyle $ s + sy = scaleDilatation . textStyle $ s + sz = scaleCompression . textStyle $ s + in + Glue (ws*h) (h*sy*ws/2.0) (h*sz*ws/3.0) (Just s) + +-- | Add a penalty to the stream +penalty :: Style style => PDFFloat -- ^ Penalty width + -> Int -- ^ Penalty value + -> B style +penalty w p = Penalty w p False + +createTextBox :: Style style => style -> PDFString -> B style +createTextBox s t = Text s t (textWidth (textFont . textStyle $ s) t) + +-- | Forget the style +asAny :: Style style => B style -> B AnyStyle +asAny (Text s t w) = Text (AnyStyle s) t w +asAny (Glue w y z (Just r)) = Glue w y z (Just (AnyStyle r)) +asAny (Glue w y z Nothing) = Glue w y z Nothing +asAny (Penalty w p f) = Penalty w p f +asAny (B a) = B a + +-- Concat consecutive words and glue that have the same style to draw the sentence with one PDF command +concatHMode :: Style s => PDFFloat -> s -> (B.ByteString,PDFFloat) -> [B s] -> [B s] +concatHMode r style (t,w) l@((Text s (PDFString t') w'):l') | styleCode style == styleCode s = concatHMode r style (B.append t t', w + w') l' + | otherwise = Text style (PDFString t) w : simplifyHMode r l +-- That glue is special. It is just a space and we will processed as a space +concatHMode r style (t,w) l@(a@(Glue _ _ _ (Just s)):l') | styleCode style == styleCode s = concatHMode r style (B.append t (singleton ' '), w + boxWidth a r) l' + | otherwise = Text style (PDFString t) w : simplifyHMode r l +concatHMode r style (t,w) l = Text style (PDFString t) w : simplifyHMode r l + + +-- Simplification for improving the generated PDF code. We concatenate words when the word style is not enabled +-- and the style is the same +simplifyHMode :: Style s => PDFFloat -> [B s] -> [B s] +simplifyHMode _ [] = [] +simplifyHMode r (a@(Text s (PDFString t) w):l) = + if (isJust . wordStyle $ s) + then + a:simplifyHMode r l + else + concatHMode r s (t,w) l +simplifyHMode r (a:l) = a:simplifyHMode r l + +-- | horizontalPostProcess +horizontalPostProcess :: Style style => [(PDFFloat,[B style])] -> [(PDFFloat,[B style])] +horizontalPostProcess l = map processHLine l + where + processHLine (r,l') = (r,simplifyHMode r . simplify $ l') + + -- Test is a box has same style +isSameStyle :: Style s => s + -> B s + -> Bool +isSameStyle s (Text style _ _) = styleCode s == styleCode style +isSameStyle s (Glue _ _ _ (Just style)) = styleCode s == styleCode style +isSameStyle _ _ = False hunk ./Graphics/PDF/Typesetting.hs 37 -import Graphics.PDF.Shapes -import Graphics.PDF.Colors -import qualified Data.ByteString.Lazy as B(ByteString,null,splitWith,empty,append) +import qualified Data.ByteString.Lazy as B(ByteString,null,splitWith) hunk ./Graphics/PDF/Typesetting.hs 40 -import Data.ByteString.Lazy.Char8(singleton) -import Data.Maybe(isJust,fromJust) hunk ./Graphics/PDF/Typesetting.hs 41 +import Graphics.PDF.Shapes +import Data.Maybe(isJust,fromJust) + hunk ./Graphics/PDF/Typesetting.hs 49 - -instance Style style => DisplayableBox (B style) where - strokeBox (Text style s) _ x y = drawText $ do - setFont (textFont . textStyle $ style) - strokeColor (textStrokeColor . textStyle $ style) - fillColor (textFillColor . textStyle $ style) - renderMode (textMode . textStyle $ style) - textStart x y - displayText s - - strokeBox (B a) r x y = strokeBox a r x y - strokeBox (Penalty _ _ _) _ _ _ = do - --withNewContext $ do - -- setWidth 0.5 - -- strokeColor black - -- stroke $ Line x (y-3) x (y+3) - return () - strokeBox (Glue _ _ _ _) _ _ _ = do - --withNewContext $ do - -- setWidth 0.5 - -- strokeColor green - -- stroke $ Line x y (x+w) y - -- strokeColor blue - -- stroke $ Line (x+w) y (x+w+r*yi) y - -- strokeColor $ Rgb 1 1 0 - -- stroke $ Line (x+w) (y-2) (x+w+r*zi) (y-2) - return () - -newText :: Monad m => B.ByteString -> m (a,b,B.ByteString) -> m (a,b,B.ByteString) -newText a b = do - (x,y,z) <- b - return (x,y,B.append a z) hunk ./Graphics/PDF/Typesetting.hs 50 +endParagraphBoxes :: Style s => [B s] +endParagraphBoxes = [penalty 0 infinity,glue 0 10000.0 0,penalty 0 (-infinity)] + +newtype HBox a = HBox [a] +newtype VBox a = VBox [(PDFFloat,HBox a)] hunk ./Graphics/PDF/Typesetting.hs 56 --- wordAnalysis is used to detect a full sentence using the same style and return the new position -wordAnalysis :: Style style => style -- ^ Style - -> [B style] -- ^ List of box to display - -> PDFFloat -- ^ Adjustement ration - -> PDFFloat -- ^ x - -> PDFFloat -- ^ y - -> Draw ([B style],PDFFloat) -- ^ New list to process and new position -wordAnalysis _ [] _ x _ = return ([],x) -wordAnalysis style l@(a@(Text s' (PDFString _)):l') r x y | styleCode style == styleCode s' = do - let de = styleDescent s' - he = styleHeight s' - w = boxWidth a r - re = Rectangle x (y - de) (x+w) (y - de + he) - -- Draw word background - (fromJust . wordStyle $ style) re DrawWord (strokeBox a r x y) - -- Draw other boxes - wordAnalysis (updateStyle style) l' r (x + w) y - | otherwise = return (l,x) -wordAnalysis style l@(a@(Glue _ _ _ (Just s)):l') r x y | styleCode style == styleCode s = do - let de = styleDescent s - he = styleHeight s - w = boxWidth a r - re = Rectangle x (y - de) (x+w) (y - de + he) - -- Draw word background - (fromJust . wordStyle $ style) re DrawGlue (return ()) - -- Draw other boxes - wordAnalysis (updateStyle style) l' r (x + w) y - | otherwise = return (l,x) -wordAnalysis _ l _ x _ = return (l,x) - +instance Box a => Box (HBox a) where + boxWidth (HBox a) = boxWidth a + boxHeight (HBox a) = boxHeight a + boxDescent (HBox a) = boxDescent a + +createVBoxes :: Style style => [(PDFFloat,[B style])] -> VBox (B style) +createVBoxes = VBox . map (\(r,l) -> (r, HBox l)) hunk ./Graphics/PDF/Typesetting.hs 64 --- textStroke is used to build a sentence of words having the same style --- When we have no more any text or the style is different --- we display the concatenated text --- return the new list of boxes and horizontal processing -textStroke:: Style style => style -- ^ Style - -> [B style] -- ^ List of box to display - -> PDFFloat -- ^ Adjustement ration - -> PDFFloat -- ^ x - -> PDFFloat -- ^ y - -> PDFText ([B style],PDFFloat, B.ByteString) -- ^ New list to process and new position and text to display -textStroke _ [] _ x _ = return ([],x,B.empty) -textStroke style l@(a@(Text s' (PDFString t')):l') r x y | styleCode s' == styleCode style = - t' `newText` (textStroke style l' r (x + boxWidth a r) y) - | otherwise = return (l,x,B.empty) --- That glue is special. It is just a space and we will processed as a space -textStroke style l@(a@(Glue _ _ _ (Just s)):l') r x y | styleCode style == styleCode s = (singleton ' ') `newText` (textStroke style l' r (x + boxWidth a r) y) - | otherwise = return (l,x,B.empty) -textStroke _ l _ x _ = return (l,x,B.empty) - --- List of box to display in horizontal mode -instance Style style => DisplayableBox [B style] where - strokeBox [] _ _ _ = return () - - -- A text box is processed in a special way - strokeBox l@((Text s (PDFString _)):_) r x y = do - -- If word style - if (isJust . wordStyle $ s) - -- then we display all words and then apply the sentence style - then do - (l',x') <- wordAnalysis s l r x y - let de = styleDescent s - he = styleHeight s - sentenceStyle s (Rectangle x (y - de) x' (y - de + he)) - -- We render remaining boxes - strokeBox l' r x' y - -- No word style then we can work on the full sentence and draw it - else do - (l',x') <- drawText $ do - -- We set the text setting - setFont (textFont . textStyle $ s) - strokeColor (textStrokeColor . textStyle $ s) - fillColor (textFillColor . textStyle $ s) - renderMode (textMode . textStyle $ s) - --setWidth (penWidth . textStyle $ s) - -- Here we need to dilate the space to take into account r and the font setting - let ws = (textWidth (textFont . textStyle $ s) (toPDFString " ")) - h = scaleSpace . textStyle $ s - sy = scaleDilatation . textStyle $ s - sz = scaleCompression . textStyle $ s - dws = ws * h -- dilated space - gy = sy*dws / 2.0 - gz = sz*dws / 3.0 - delta = if r >= 0 then r*gy else r*gz - -- ws is the true font space. We use dws so we have a user overhead - -- and the overhead of the space dilatation - wordSpace (dws - ws + delta) - -- And we render the text - textStart x y - (l',x',t) <- textStroke s l r x y - displayText . PDFString $ t - return (l',x') - -- We call the drawing function for the style with a rectangle around the sentence - let de = styleDescent s - he = styleHeight s - sentenceStyle s (Rectangle x (y - de) x' (y - de + he)) - -- We render remaining boxes - strokeBox l' r x' y +instance (Style s) => DisplayableBox (VBox (B s)) where + strokeBox (VBox []) _ _ _ = return () hunk ./Graphics/PDF/Typesetting.hs 68 - strokeBox (a:l) r x y = do - strokeBox a r x y - strokeBox l r (x + boxWidth a r) y + strokeBox (VBox((ra,theLine):l)) _ x y = do + let h = boxHeight theLine + y' = y + boxDescent theLine - h + strokeBox theLine ra x y' + strokeBox (VBox l) ra x (y - h) hunk ./Graphics/PDF/Typesetting.hs 74 - +-- HBox processing must be special since we need to take into account the sentence style +instance (Style s) => DisplayableBox (HBox (B s)) where + strokeBox (HBox []) _ _ _ = return () hunk ./Graphics/PDF/Typesetting.hs 78 -endParagraphBoxes :: [B s] -endParagraphBoxes = [Penalty 0 infinity False,Glue 0 10000.0 0 Nothing,Penalty 0 (-infinity) True] - --- | Display a list of boxes -displayWithBreaks :: Style s => PDFFloat -- ^ x - -> PDFFloat -- ^ y - -> [(PDFFloat,[B s])] -- ^ Line and adaptation ratio - -> Draw () -- ^ Drawing -displayWithBreaks _ _ [] = return () -displayWithBreaks x y ((r,theLine):l) = do - let h = boxHeight theLine - y' = y + boxDescent theLine - h - strokeBox theLine r x y' - displayWithBreaks x (y - h) l + -- A normal box is drawn and we move to the next one + strokeBox (HBox(l@(a@(Text style _ _):nl))) r x y = do + if (isJust . sentenceStyle $ style) + then do + let de = styleDescent style + he = styleHeight style + (l',l'') = span (isSameStyle style) l + w = boxWidth l' r + (fromJust . sentenceStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) (strokeBox l' r x y) + strokeBox (HBox l'') r (x+w) y + else do + strokeBox a r x y + strokeBox (HBox nl) r (x + boxWidth a r) y + + strokeBox (HBox(a:l)) r x y = do + strokeBox a r x y + strokeBox (HBox l) r (x + boxWidth a r) y hunk ./Graphics/PDF/Typesetting.hs 105 + -- Cut the text into lines and get a list of lines hunk ./Graphics/PDF/Typesetting.hs 107 - displayWithBreaks x y l + -- Apply the gorizontal postprocessing and package everything as a list of VBox. Each line being a list of HBox + strokeBox (createVBoxes . horizontalPostProcess $ l) 1.0 x y hunk ./Graphics/PDF/Typesetting.hs 119 - | otherwise = wordTransform f [Text f (PDFString x)] + | otherwise = wordTransform f [createTextBox f $ (PDFString x)] hunk ./Graphics/PDF/Typesetting.hs 123 - wordTransform f [Text f (PDFString x)] ++ addSpacesToLine f g xs + wordTransform f [createTextBox f $ (PDFString x)] ++ addSpacesToLine f g xs hunk ./Graphics/PDF/Typesetting.hs 125 - wordTransform f [Text f (PDFString x)] ++ [g] ++ addSpacesToLine f g xs + wordTransform f [createTextBox f $ (PDFString x)] ++ [g] ++ addSpacesToLine f g xs hunk ./Graphics/PDF/Typesetting.hs 130 - let ws = (textWidth (textFont . textStyle $ f) (toPDFString " ") ) - h = scaleSpace . textStyle $ f - sy = scaleDilatation . textStyle $ f - sz = scaleCompression . textStyle $ f - tell $ addSpacesToLine f (Glue (ws*h) (h*sy*ws/2.0) (h*sz*ws/3.0) (Just f)) . getWords $ t + tell $ addSpacesToLine f (spaceGlue f) . getWords $ t hunk ./Graphics/PDF/Typesetting.hs 160 --- | Add a glue to the stream -glue :: PDFFloat -- ^ Glue width - -> PDFFloat -- ^ Glue dilatation - -> PDFFloat -- ^ Glue compression - -> TM () -glue w y z = tell ([Glue w y z Nothing]) - --- | Add a penalty to the stream -penalty :: PDFFloat -- ^ Penalty width - -> Int -- ^ Penalty value - -> TM () -penalty w p = tell ([Penalty w p False]) - hunk ./Test/test.hs 114 - sentenceStyle _ (Rectangle xa ya xb yb) = return () + sentenceStyle _ = Nothing hunk ./Test/test.hs 121 - sentenceStyle _ (Rectangle xa ya xb yb) = return () + sentenceStyle _ = Nothing hunk ./Test/test.hs 141 - sentenceStyle _ r = do + sentenceStyle _ = Just $ \r d -> do + d hunk ./Test/test.hs 158 - sentenceStyle _ _ = return () + sentenceStyle _ = Nothing hunk ./Test/test.hs 283 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = True}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = False}) rect $ do hunk ./Graphics/PDF/Typesetting.hs 32 + , nullBox hunk ./Graphics/PDF/Typesetting.hs 38 -import qualified Data.ByteString.Lazy as B(ByteString,null,splitWith) -import qualified Data.ByteString.Base as B(isSpaceWord8) hunk ./Graphics/PDF/Typesetting.hs 41 -import Data.Maybe(isJust,fromJust) +import Graphics.PDF.Typesetting.Horizontal +import Graphics.PDF.Typesetting.Vertical + hunk ./Graphics/PDF/Typesetting.hs 50 - -endParagraphBoxes :: Style s => [B s] -endParagraphBoxes = [penalty 0 infinity,glue 0 10000.0 0,penalty 0 (-infinity)] - -newtype HBox a = HBox [a] -newtype VBox a = VBox [(PDFFloat,HBox a)] - -instance Box a => Box (HBox a) where - boxWidth (HBox a) = boxWidth a - boxHeight (HBox a) = boxHeight a - boxDescent (HBox a) = boxDescent a - -createVBoxes :: Style style => [(PDFFloat,[B style])] -> VBox (B style) -createVBoxes = VBox . map (\(r,l) -> (r, HBox l)) - -instance (Style s) => DisplayableBox (VBox (B s)) where - strokeBox (VBox []) _ _ _ = return () hunk ./Graphics/PDF/Typesetting.hs 51 - -- A normal box is drawn and we move to the next one - strokeBox (VBox((ra,theLine):l)) _ x y = do - let h = boxHeight theLine - y' = y + boxDescent theLine - h - strokeBox theLine ra x y' - strokeBox (VBox l) ra x (y - h) - --- HBox processing must be special since we need to take into account the sentence style -instance (Style s) => DisplayableBox (HBox (B s)) where - strokeBox (HBox []) _ _ _ = return () + hunk ./Graphics/PDF/Typesetting.hs 53 - -- A normal box is drawn and we move to the next one - strokeBox (HBox(l@(a@(Text style _ _):nl))) r x y = do - if (isJust . sentenceStyle $ style) - then do - let de = styleDescent style - he = styleHeight style - (l',l'') = span (isSameStyle style) l - w = boxWidth l' r - (fromJust . sentenceStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) (strokeBox l' r x y) - strokeBox (HBox l'') r (x+w) y - else do - strokeBox a r x y - strokeBox (HBox nl) r (x + boxWidth a r) y - - strokeBox (HBox(a:l)) r x y = do - strokeBox a r x y - strokeBox (HBox l) r (x + boxWidth a r) y - hunk ./Graphics/PDF/Typesetting.hs 68 --- | Cut into words but keep spaces at beginning and end -getWords :: B.ByteString -> [B.ByteString] -getWords x = B.splitWith B.isSpaceWord8 $ x - --- | Convert each string to a box and add the glue for the spaces (with beginning and ending space) -addSpacesToLine :: AnyStyle -> B AnyStyle -> [B.ByteString] -> [B AnyStyle] -addSpacesToLine _ _ [] = [] -addSpacesToLine f g [x] | B.null x = [g] - | otherwise = wordTransform f [createTextBox f $ (PDFString x)] -addSpacesToLine f g (x:xs) | B.null x = g : addSpacesToLine f g xs - | otherwise = if B.null . head $ xs - then - wordTransform f [createTextBox f $ (PDFString x)] ++ addSpacesToLine f g xs - else - wordTransform f [createTextBox f $ (PDFString x)] ++ [g] ++ addSpacesToLine f g xs - +-- | split a line into boxes hunk ./Graphics/PDF/Typesetting.hs 73 - - + hunk ./Graphics/PDF/Typesetting.hs 80 -newtype TM a = TM { unTM :: RWS () [B AnyStyle] TMState a} deriving(Monad,MonadWriter [B AnyStyle], MonadState TMState, Functor) +newtype TM a = TM { unTM :: RWS () [B AnyStyle] TMState a} +#ifndef __HADDOCK__ + deriving(Monad,MonadWriter [B AnyStyle], MonadState TMState, Functor) +#else +instance Monad TM +instance MonadWriter [B AnyStyle] TM +instance MonadState TMState TM +instance Functor TM +#endif hunk ./Graphics/PDF/Typesetting/Breaking.hs 15 --- BreakNode(..) --- , MaybeCB(..) --- , ZList(..) --- , PossibleBreak --- , ActiveNodes(..) hunk ./Graphics/PDF/Typesetting/Breaking.hs 16 --- , CB --- , adjustRatio --- , badness --- , fitness --- , computeDemerit --- , createZList --- , theEnd --- , createBreaknode --- , moveRight --- , isFeasibleBreakpoint --- , fitness_demerit --- , flagged_demerit --- , updateBreak --- , addBreaks --- , updateWithNewRIfNoSolution --- , getNewActiveBreakpoints --- , genNodeList --- , analyzeBoxes hunk ./Graphics/PDF/Typesetting/Breaking.hs 17 --- , infinity --- , PointedBox(..) hunk ./Graphics/PDF/Typesetting/Breaking.hs 18 --- , penaltyWidth hunk ./Graphics/PDF/Typesetting/Breaking.hs 23 --- , cutList hunk ./Graphics/PDF/Typesetting/Breaking.hs 28 + , nullBox hunk ./Graphics/PDF/Typesetting/Breaking.hs 30 - , horizontalPostProcess hunk ./Graphics/PDF/Typesetting/Breaking.hs 41 -import Data.ByteString.Lazy.Char8(singleton) -import qualified Data.ByteString.Lazy as B(ByteString,append) hunk ./Graphics/PDF/Typesetting/Breaking.hs 42 + + +-- | Text style used by PDF operators hunk ./Graphics/PDF/Typesetting/Breaking.hs 50 - , scaleSpace :: !PDFFloat -- Scaling factor for normal space size - , scaleDilatation :: !PDFFloat - , scaleCompression :: !PDFFloat + , scaleSpace :: !PDFFloat -- ^ Scaling factor for normal space size (scale also the dilation and compression factors) + , scaleDilatation :: !PDFFloat -- ^ Scale the dilation factor of glues + , scaleCompression :: !PDFFloat -- ^ Scale the compression factor of glues hunk ./Graphics/PDF/Typesetting/Breaking.hs 58 -data StyleFunction = DrawWord - | DrawGlue +data StyleFunction = DrawWord -- ^ Must style a word + | DrawGlue -- ^ Must style a glue hunk ./Graphics/PDF/Typesetting/Breaking.hs 61 - + +-- | Style of text hunk ./Graphics/PDF/Typesetting/Breaking.hs 64 - sentenceStyle :: a -> Maybe (Rectangle -> Draw b -> Draw ()) - wordStyle :: a -> Maybe (Rectangle -> StyleFunction -> Draw b -> Draw ()) + -- ^ Modify the look of a sentence (sequence of words using the same style on a line) + sentenceStyle :: a -- ^ The style + -> Maybe (Rectangle -> Draw b -> Draw ()) -- ^ Function receiving the bounding rectangle and the commands drawing the sentence + -- ^ Modify the look of a word + wordStyle :: a -- ^ The style + -> Maybe (Rectangle -> StyleFunction -> Draw b -> Draw ()) -- ^ Word styling function hunk ./Graphics/PDF/Typesetting/Breaking.hs 71 + -- | All styles used in a document must have different style codes hunk ./Graphics/PDF/Typesetting/Breaking.hs 73 + -- | A style may contain data changed from word to word hunk ./Graphics/PDF/Typesetting/Breaking.hs 75 + + -- | A style may add boxes before and after the word hunk ./Graphics/PDF/Typesetting/Breaking.hs 79 + + -- | A style may change the height of words hunk ./Graphics/PDF/Typesetting/Breaking.hs 82 + + -- | A style may change the descent of lines hunk ./Graphics/PDF/Typesetting/Breaking.hs 100 +-- | A box with dimensions hunk ./Graphics/PDF/Typesetting/Breaking.hs 102 - boxWidth :: a -> PDFFloat -> PDFFloat + -- | Box width + boxWidth :: a -- ^ Box + -> PDFFloat -- ^ Box adjustement ratio + -> PDFFloat -- ^ Width with adjustement + -- | Bow height hunk ./Graphics/PDF/Typesetting/Breaking.hs 108 + -- | Distance between bow bottom and point where the base of the text line is hunk ./Graphics/PDF/Typesetting/Breaking.hs 111 +-- | A box that cna be displayed hunk ./Graphics/PDF/Typesetting/Breaking.hs 113 - strokeBox :: a -> PDFFloat -> PDFFloat -> PDFFloat -> Draw () + -- | Draw a bow + strokeBox :: a -- ^ The box + -> PDFFloat -- ^ Adjustement ratio + -> PDFFloat -- ^ Horizontal position + -> PDFFloat -- ^ Vertical position + -> Draw () + +data NullBox = NullBox deriving(Show) + +-- | Create a null box +nullBox :: B NullBox +nullBox = B NullBox + +instance Box NullBox where + boxWidth _ _ = 0 + boxHeight _ = 0 + boxDescent _ = 0 + +instance DisplayableBox NullBox where + strokeBox _ _ _ _ = return () + hunk ./Graphics/PDF/Typesetting/Breaking.hs 135 +-- | A box hunk ./Graphics/PDF/Typesetting/Breaking.hs 495 +-- Analyze the boxes to compute breaks hunk ./Graphics/PDF/Typesetting/Breaking.hs 533 --- Remove glues and penalties at the beginning of a line -simplify :: [B s] -> [B s] -simplify ((Glue _ _ _ _):l) = simplify l -simplify ((Penalty _ _ _):l) = simplify l -simplify l = l - hunk ./Graphics/PDF/Typesetting/Breaking.hs 585 +-- | Create a box containing text hunk ./Graphics/PDF/Typesetting/Breaking.hs 597 --- Concat consecutive words and glue that have the same style to draw the sentence with one PDF command -concatHMode :: Style s => PDFFloat -> s -> (B.ByteString,PDFFloat) -> [B s] -> [B s] -concatHMode r style (t,w) l@((Text s (PDFString t') w'):l') | styleCode style == styleCode s = concatHMode r style (B.append t t', w + w') l' - | otherwise = Text style (PDFString t) w : simplifyHMode r l --- That glue is special. It is just a space and we will processed as a space -concatHMode r style (t,w) l@(a@(Glue _ _ _ (Just s)):l') | styleCode style == styleCode s = concatHMode r style (B.append t (singleton ' '), w + boxWidth a r) l' - | otherwise = Text style (PDFString t) w : simplifyHMode r l -concatHMode r style (t,w) l = Text style (PDFString t) w : simplifyHMode r l - - --- Simplification for improving the generated PDF code. We concatenate words when the word style is not enabled --- and the style is the same -simplifyHMode :: Style s => PDFFloat -> [B s] -> [B s] -simplifyHMode _ [] = [] -simplifyHMode r (a@(Text s (PDFString t) w):l) = - if (isJust . wordStyle $ s) - then - a:simplifyHMode r l - else - concatHMode r s (t,w) l -simplifyHMode r (a:l) = a:simplifyHMode r l hunk ./Graphics/PDF/Typesetting/Breaking.hs 598 --- | horizontalPostProcess -horizontalPostProcess :: Style style => [(PDFFloat,[B style])] -> [(PDFFloat,[B style])] -horizontalPostProcess l = map processHLine l - where - processHLine (r,l') = (r,simplifyHMode r . simplify $ l') addfile ./Graphics/PDF/Typesetting/Horizontal.hs hunk ./Graphics/PDF/Typesetting/Horizontal.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2006 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Horizontal mode +--------------------------------------------------------- +-- #hide +module Graphics.PDF.Typesetting.Horizontal ( + HBox(..) + , horizontalPostProcess + , endParagraphBoxes + , addSpacesToLine + , getWords + ) where + +import Graphics.PDF.LowLevel.Types +import Graphics.PDF.Typesetting.Breaking +import Data.ByteString.Lazy.Char8(singleton) +import Graphics.PDF.Shapes +import qualified Data.ByteString.Lazy as B(ByteString,null,splitWith,append) +import qualified Data.ByteString.Base as B(isSpaceWord8) +import Data.Maybe(isJust,fromJust) + +-- Concat consecutive words and glue that have the same style to draw the sentence with one PDF command +concatHMode :: Style s => PDFFloat -> s -> (B.ByteString,PDFFloat) -> [B s] -> [B s] +concatHMode r style (t,w) l@((Text s (PDFString t') w'):l') | styleCode style == styleCode s = concatHMode r style (B.append t t', w + w') l' + | otherwise = Text style (PDFString t) w : simplifyHMode r l +-- That glue is special. It is just a space and we will processed as a space +concatHMode r style (t,w) l@(a@(Glue _ _ _ (Just s)):l') | styleCode style == styleCode s = concatHMode r style (B.append t (singleton ' '), w + boxWidth a r) l' + | otherwise = Text style (PDFString t) w : simplifyHMode r l +-- Penalties are invisible in the final document +concatHMode r style (t,w) ((Penalty _ _ _):l') = concatHMode r style (t,w) l' +concatHMode r style (t,w) l = Text style (PDFString t) w : simplifyHMode r l + + +-- Simplification for improving the generated PDF code. We concatenate words when the word style is not enabled +-- and the style is the same +simplifyHMode :: Style s => PDFFloat -> [B s] -> [B s] +simplifyHMode _ [] = [] +simplifyHMode r (a@(Text s (PDFString t) w):l) = + if (isJust . wordStyle $ s) + then + a:simplifyHMode r l + else + concatHMode r s (t,w) l +simplifyHMode r (a:l) = a:simplifyHMode r l + +-- Remove glues and penalties at the beginning of a line +simplify :: [B s] -> [B s] +simplify ((Glue _ _ _ _):l) = simplify l +simplify ((Penalty _ _ _):l) = simplify l +simplify l = l + +-- | horizontalPostProcess +horizontalPostProcess :: Style style => [(PDFFloat,[B style])] -> [(PDFFloat,[B style])] +horizontalPostProcess l = map processHLine l + where + processHLine (r,l') = (r,simplifyHMode r . simplify $ l') + + +newtype HBox a = HBox [a] + +instance Box a => Box (HBox a) where + boxWidth (HBox a) = boxWidth a + boxHeight (HBox a) = boxHeight a + boxDescent (HBox a) = boxDescent a + +-- HBox processing must be special since we need to take into account the sentence style +instance (Style s) => DisplayableBox (HBox (B s)) where + strokeBox (HBox []) _ _ _ = return () + + -- A normal box is drawn and we move to the next one + strokeBox (HBox(l@(a@(Text style _ _):nl))) r x y = do + if (isJust . sentenceStyle $ style) + then do + let de = styleDescent style + he = styleHeight style + (l',l'') = span (isSameStyle style) l + w = boxWidth l' r + (fromJust . sentenceStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) (strokeBox l' r x y) + strokeBox (HBox l'') r (x+w) y + else do + strokeBox a r x y + strokeBox (HBox nl) r (x + boxWidth a r) y + + strokeBox (HBox(a:l)) r x y = do + strokeBox a r x y + strokeBox (HBox l) r (x + boxWidth a r) y + +endParagraphBoxes :: Style s => [B s] +endParagraphBoxes = [glue 0 10000.0 0,penalty 0 (-infinity)] + +-- | Cut into words but keep spaces at beginning and end +getWords :: B.ByteString -> [B.ByteString] +getWords x = B.splitWith B.isSpaceWord8 $ x + +-- | Convert each string to a box and add the glue for the spaces (with beginning and ending space) +addSpacesToLine :: AnyStyle -> B AnyStyle -> [B.ByteString] -> [B AnyStyle] +addSpacesToLine _ _ [] = [] +addSpacesToLine f g [x] | B.null x = [g] + | otherwise = wordTransform f [createTextBox f $ (PDFString x)] +addSpacesToLine f g (x:xs) | B.null x = g : addSpacesToLine f g xs + | otherwise = if B.null . head $ xs + then + wordTransform f [createTextBox f $ (PDFString x)] ++ addSpacesToLine f g xs + else + wordTransform f [createTextBox f $ (PDFString x)] ++ [g] ++ addSpacesToLine f g xs + + addfile ./Graphics/PDF/Typesetting/Vertical.hs hunk ./Graphics/PDF/Typesetting/Vertical.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2006 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Vertical mode +--------------------------------------------------------- +-- #hide +module Graphics.PDF.Typesetting.Vertical ( + VBox(..) + , createVBoxes + ) where + +import Graphics.PDF.LowLevel.Types +import Graphics.PDF.Typesetting.Breaking +import Graphics.PDF.Typesetting.Horizontal(HBox(..)) + +newtype VBox a = VBox [(PDFFloat,HBox a)] + +instance (Style s) => DisplayableBox (VBox (B s)) where + strokeBox (VBox []) _ _ _ = return () + + -- A normal box is drawn and we move to the next one + strokeBox (VBox((ra,theLine):l)) _ x y = do + let h = boxHeight theLine + y' = y + boxDescent theLine - h + strokeBox theLine ra x y' + strokeBox (VBox l) ra x (y - h) + +createVBoxes :: Style style => [(PDFFloat,[B style])] -> VBox (B style) +createVBoxes = VBox . map (\(r,l) -> (r, HBox l)) hunk ./HPDF.cabal 54 - + Graphics.PDF.Typesetting.Horizontal + Graphics.PDF.Typesetting.Vertical + hunk ./Test/test.hs 205 + setStyle Normal hunk ./Graphics/PDF/Typesetting/Breaking.hs 466 -getNewActiveBreakpoints :: Style style => Bool -> PDFFloat -> ActiveNodes -> ZList style -> (PossibleBreak,ActiveNodes) -getNewActiveBreakpoints sndPass maxw actives z = +getNewActiveBreakpoints :: Style style => Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList style -> (PossibleBreak,ActiveNodes) +getNewActiveBreakpoints sndPass fmaxw actives z = hunk ./Graphics/PDF/Typesetting/Breaking.hs 471 - let r' = adjustRatio b z maxw + let r' = adjustRatio b z (fmaxw (line+1)) hunk ./Graphics/PDF/Typesetting/Breaking.hs 496 -analyzeBoxes :: Style style => Bool -> PDFFloat -> ActiveNodes -> ZList style -> [(PDFFloat,Int)] -analyzeBoxes pass maxw actives z = +analyzeBoxes :: Style style => Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList style -> [(PDFFloat,Int)] +analyzeBoxes pass fmaxw actives z = hunk ./Graphics/PDF/Typesetting/Breaking.hs 499 - (breaks',actives') = getNewActiveBreakpoints pass maxw actives z + (breaks',actives') = getNewActiveBreakpoints pass fmaxw actives z hunk ./Graphics/PDF/Typesetting/Breaking.hs 512 - analyzeBoxes True maxw actives z + analyzeBoxes True fmaxw actives z hunk ./Graphics/PDF/Typesetting/Breaking.hs 520 - getRightOrderNodeList minBreak ++ analyzeBoxes pass maxw (Map.insert (getKey minBreak) (getNode minBreak) Map.empty) (moveRight z) + getRightOrderNodeList minBreak ++ analyzeBoxes pass fmaxw (Map.insert (getKey minBreak) (getNode minBreak) Map.empty) (moveRight z) hunk ./Graphics/PDF/Typesetting/Breaking.hs 531 - analyzeBoxes pass maxw newActives (moveRight z) + analyzeBoxes pass fmaxw newActives (moveRight z) hunk ./Graphics/PDF/Typesetting/Breaking.hs 547 -formatList :: Style style => PDFFloat -> [B style] -> [(PDFFloat,[B style])] -formatList maxw boxes = +formatList :: Style style => (Int -> PDFFloat) -> [B style] -> [(PDFFloat,[B style])] +formatList fmaxw boxes = hunk ./Graphics/PDF/Typesetting/Breaking.hs 550 - theBreaks = analyzeBoxes False maxw active (createZList boxes) + theBreaks = analyzeBoxes False fmaxw active (createZList boxes) hunk ./Graphics/PDF/Typesetting/Vertical.hs 16 + , strokeVBoxes hunk ./Graphics/PDF/Typesetting/Vertical.hs 22 +import Graphics.PDF.Draw hunk ./Graphics/PDF/Typesetting/Vertical.hs 26 -instance (Style s) => DisplayableBox (VBox (B s)) where - strokeBox (VBox []) _ _ _ = return () - - -- A normal box is drawn and we move to the next one - strokeBox (VBox((ra,theLine):l)) _ x y = do - let h = boxHeight theLine - y' = y + boxDescent theLine - h - strokeBox theLine ra x y' - strokeBox (VBox l) ra x (y - h) hunk ./Graphics/PDF/Typesetting/Vertical.hs 30 +strokeVBoxes :: Style s => VBox (B s) + -> PDFFloat -- ^ Adjustement ratio + -> (Int -> PDFFloat) -- ^ x + -> PDFFloat -- ^ y + -> Draw () +strokeVBoxes b _ fx y' = recurseStrokeVBoxes 1 b y' + where + recurseStrokeVBoxes _ (VBox []) _ = return () + recurseStrokeVBoxes nb (VBox((ra,theLine):l)) y = do + let h = boxHeight theLine + y' = y + boxDescent theLine - h + strokeBox theLine ra (fx nb) y' + recurseStrokeVBoxes (nb+1) (VBox l) (y - h) + hunk ./Graphics/PDF/Typesetting.hs 33 + , TextArea(..) + , rectangleArea hunk ./Graphics/PDF/Typesetting.hs 42 -import Graphics.PDF.Shapes hunk ./Graphics/PDF/Typesetting.hs 45 +-- | Pair of functions describing the shape of a text areas : horizontal position of each line, vertical top of the area, width of each line +-- First line is 1 +data TextArea = TextArea (Int -> PDFFloat) PDFFloat (Int -> PDFFloat) hunk ./Graphics/PDF/Typesetting.hs 49 +rectangleArea :: PDFFloat -- ^ x + -> PDFFloat -- ^ y + -> PDFFloat -- ^ w + -> TextArea -- ^ Text area +rectangleArea x y w = TextArea (const x) y (const w) + hunk ./Graphics/PDF/Typesetting.hs 60 - - - hunk ./Graphics/PDF/Typesetting.hs 61 -displayFormattedText :: Style d => PDFFloat -- ^ Horizontal position - -> PDFFloat -- ^ Vertical position - -> PDFFloat -- ^ Max width +displayFormattedText :: Style d => TextArea -- ^ Text area hunk ./Graphics/PDF/Typesetting.hs 65 -displayFormattedText x y maxw defaultStyle t = do +displayFormattedText (TextArea fx y fmaxw) defaultStyle t = do hunk ./Graphics/PDF/Typesetting.hs 68 - l = formatList maxw boxes + l = formatList fmaxw boxes hunk ./Graphics/PDF/Typesetting.hs 70 - strokeBox (createVBoxes . horizontalPostProcess $ l) 1.0 x y + strokeVBoxes (createVBoxes . horizontalPostProcess $ l) 1.0 fx y hunk ./Test/test.hs 183 +triangleArea x y = let ws = textWidth (PDFFont Times_Roman 10) (toPDFString " ") in + TextArea (\l -> x + 300.0 - ws * 5.0 * (fromIntegral (l-1))) y (\l -> ws*10.0 + 10.0*ws*(fromIntegral (l-1))) hunk ./Test/test.hs 232 - displayFormattedText 10 300 maxw Normal debugText + --displayFormattedText (rectangleArea 10 300 maxw) Normal debugText + displayFormattedText (triangleArea 10 300) Normal debugText hunk ./Test/test.hs 287 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = False}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = True}) rect $ do hunk ./Graphics/PDF/Typesetting/Breaking.hs 31 + , hyphenPenalty + , hyphenBox hunk ./Graphics/PDF/Typesetting/Breaking.hs 140 - | Penalty !PDFFloat !Int !Bool + | FlaggedPenalty !PDFFloat !Int !style + | Penalty !Int hunk ./Graphics/PDF/Typesetting/Breaking.hs 155 - boxWidth (Penalty _ _ _) _ = 0 + boxWidth (FlaggedPenalty _ _ _) _ = 0 + boxWidth (Penalty _) _ = 0 hunk ./Graphics/PDF/Typesetting/Breaking.hs 161 - boxHeight (Penalty _ _ _) = 0 + boxHeight (FlaggedPenalty _ _ _) = 0 + boxHeight (Penalty _) = 0 hunk ./Graphics/PDF/Typesetting/Breaking.hs 167 - boxDescent (Penalty _ _ _) = 0 + boxDescent (FlaggedPenalty _ _ _) = 0 + boxDescent (Penalty _) = 0 hunk ./Graphics/PDF/Typesetting/Breaking.hs 200 - strokeBox (Glue w _ _ (Just style)) _ x y = do + strokeBox b@(Glue _ _ _ (Just style)) r x y = do hunk ./Graphics/PDF/Typesetting/Breaking.hs 203 + w = boxWidth b r hunk ./Graphics/PDF/Typesetting/Breaking.hs 228 - strokeBox (Penalty _ _ _) _ _ _ = return () + strokeBox (FlaggedPenalty _ _ _) _ _ _ = return () + strokeBox (Penalty _) _ _ _ = return () hunk ./Graphics/PDF/Typesetting/Breaking.hs 248 - show (Penalty a b c) = "(Penalty " ++ show a ++ " " ++ show b ++ " " ++ show c ++ ")" + show (FlaggedPenalty a b _) = "(FlaggedPenalty " ++ show a ++ " " ++ show b ++ ")" + show (Penalty a) = "(Penalty " ++ show a ++ ")" hunk ./Graphics/PDF/Typesetting/Breaking.hs 275 - isFlagged (_,_,_,_,Penalty _ _ f) = f + isFlagged (_,_,_,_,FlaggedPenalty _ _ _) = True hunk ./Graphics/PDF/Typesetting/Breaking.hs 277 - isPenalty (_,_,_,_,Penalty _ _ _) = True + isPenalty (_,_,_,_,FlaggedPenalty _ _ _) = True + isPenalty (_,_,_,_,Penalty _) = True hunk ./Graphics/PDF/Typesetting/Breaking.hs 280 - getPenalty (_,_,_,_,Penalty _ p _) = p + getPenalty (_,_,_,_,FlaggedPenalty _ p _) = p + getPenalty (_,_,_,_,Penalty p) = p hunk ./Graphics/PDF/Typesetting/Breaking.hs 288 - isForcedBreak (_,_,_,_,Penalty _ p _) = p <= (-infinity) + isForcedBreak (_,_,_,_,FlaggedPenalty _ p _) = p <= (-infinity) + isForcedBreak (_,_,_,_,Penalty p) = p <= (-infinity) hunk ./Graphics/PDF/Typesetting/Breaking.hs 306 -penaltyWidth (Penalty w _ _) = w +penaltyWidth (FlaggedPenalty w _ _) = w hunk ./Graphics/PDF/Typesetting/Breaking.hs 309 -data BreakNode = BreakNode { totalWidth :: !PDFFloat +data BreakNode = + BreakNode { totalWidth :: !PDFFloat hunk ./Graphics/PDF/Typesetting/Breaking.hs 355 + +firstPassTolerance :: PDFFloat +firstPassTolerance = 2.0 + +secondPassTolerance :: PDFFloat +secondPassTolerance = 2.0 + hunk ./Graphics/PDF/Typesetting/Breaking.hs 372 - tolerance = if sndPass then 3.0 else 1.0 + tolerance = if sndPass then secondPassTolerance else firstPassTolerance hunk ./Graphics/PDF/Typesetting/Breaking.hs 409 -createBreaknode prev (ZList _ (w,y,z,_,Penalty w' _ f) []) = BreakNode (w + w') (y) (z) 0.0 f 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,FlaggedPenalty _ _ _) []) = BreakNode (w) (y) (z) 0.0 True 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,Penalty _) []) = BreakNode w (y) (z) 0.0 False 0 0.0 prev hunk ./Graphics/PDF/Typesetting/Breaking.hs 413 -createBreaknode prev (ZList _ (w,y,z,_,Penalty _ p f) _) | p <= (-infinity) = BreakNode w y z 0.0 f 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,FlaggedPenalty _ p _) _) | p <= (-infinity) = BreakNode w y z 0.0 True 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,Penalty p) _) | p <= (-infinity) = BreakNode w y z 0.0 False 0 0.0 prev hunk ./Graphics/PDF/Typesetting/Breaking.hs 419 +-- | Create an hyphen box for current style +hyphenBox :: Style s => s -> B s +hyphenBox s = createTextBox s (toPDFString "-") + +-- | Create an hyphen penalty +hyphenPenalty :: Style s => s -> B s +hyphenPenalty s = FlaggedPenalty (boxWidth (hyphenBox s) 1.0) 0 s hunk ./Graphics/PDF/Typesetting/Breaking.hs 446 -isFeasibleBreakpoint :: ZList style -> Bool -isFeasibleBreakpoint (ZList _ (_,_,_,_,Penalty _ p _) _) = p < infinity -isFeasibleBreakpoint (ZList NoCB _ _) = False -isFeasibleBreakpoint (ZList (OneCB (_,_,_,_,B _)) (_,_,_,_,Glue _ _ _ _) _) = True -isFeasibleBreakpoint (ZList (OneCB (_,_,_,_,Text _ _ _)) (_,_,_,_,Glue _ _ _ _) _) = True -isFeasibleBreakpoint _ = False +isFeasibleBreakpoint :: Bool -- ^ Second pass + -> ZList style -- ^ Current analyzed box + -> Bool -- ^ Result +isFeasibleBreakpoint True (ZList _ (_,_,_,_,FlaggedPenalty _ p _) _) = p < infinity +isFeasibleBreakpoint False (ZList _ (_,_,_,_,FlaggedPenalty _ _ _) _) = False +isFeasibleBreakpoint _ (ZList _ (_,_,_,_,Penalty p) _) = p < infinity +isFeasibleBreakpoint _ (ZList NoCB _ _) = False +isFeasibleBreakpoint _ (ZList (OneCB (_,_,_,_,B _)) (_,_,_,_,Glue _ _ _ _) _) = True +isFeasibleBreakpoint _ (ZList (OneCB (_,_,_,_,Text _ _ _)) (_,_,_,_,Glue _ _ _ _) _) = True +isFeasibleBreakpoint _ _ = False hunk ./Graphics/PDF/Typesetting/Breaking.hs 466 -type ActiveNodes = Map.Map (Int,Int,Int) BreakNode +type ActiveNodes = Map.Map (Int,Int,Int) BreakNode hunk ./Graphics/PDF/Typesetting/Breaking.hs 481 - -> ActiveNodes -- ^ Actives + -> ActiveNodes-- ^ Actives hunk ./Graphics/PDF/Typesetting/Breaking.hs 501 - if isFeasibleBreakpoint z + if isFeasibleBreakpoint sndPass z hunk ./Graphics/PDF/Typesetting/Breaking.hs 523 -genNodeList :: (Int,Int,Int,BreakNode) -> [(PDFFloat,Int)] -genNodeList (p,_,_,b@(BreakNode _ _ _ _ _ _ _ Nothing)) = [(ratio b,p)] -genNodeList (p,_,_,b@(BreakNode _ _ _ _ _ _ _ (Just _))) = (ratio b,p):genNodeList (fromJust . previous $ b) +genNodeList :: (Int,Int,Int,BreakNode) -> [(PDFFloat,Int,Bool)] +genNodeList (p,_,_,b@(BreakNode _ _ _ _ f _ _ Nothing)) = [(ratio b,p,f)] +genNodeList (p,_,_,b@(BreakNode _ _ _ _ f _ _ (Just _))) = (ratio b,p,f):genNodeList (fromJust . previous $ b) hunk ./Graphics/PDF/Typesetting/Breaking.hs 529 -analyzeBoxes :: Style style => Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList style -> [(PDFFloat,Int)] +analyzeBoxes :: Style style => Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList style -> [(PDFFloat,Int,Bool)] hunk ./Graphics/PDF/Typesetting/Breaking.hs 566 --- Use a list of breakpoint and adjustement ratios to generate a list of lines -cutList :: [B style] -> Int -> [(PDFFloat,Int)] -> [(PDFFloat,[B style])] -cutList t _ [] = [(0.0,t)] -cutList t c ((ra,ba):l) = +-- Use a list of breakpoint and adjustement ratios to generate a list of lines. Bool means if the break was done on a flagged penalty (hyphen) +cutList :: [B style] -> Int -> [(PDFFloat,Int,Bool)] -> [(PDFFloat,Maybe style,[B style])] +cutList t _ [] = [(0.0,Nothing,t)] +cutList t c ((ra,ba,fa):l) = hunk ./Graphics/PDF/Typesetting/Breaking.hs 575 - (ra,theLine) : cutList t' ba l + if null t' + then + [(ra,Nothing,theLine)] + else + case head t' of + FlaggedPenalty _ _ s -> if not fa + then + error "Breakpoint marked as not flagged but detected as flagged ! Send a bug report !" + else + (ra,Just s,theLine) : cutList t' ba l + _ -> if fa + then + error "Breakpoint marked as flagged but detected as not flagged ! Send a bug report !" + else + (ra,Nothing,theLine) : cutList t' ba l hunk ./Graphics/PDF/Typesetting/Breaking.hs 594 -formatList :: Style style => (Int -> PDFFloat) -> [B style] -> [(PDFFloat,[B style])] +formatList :: Style style => (Int -> PDFFloat) -> [B style] -> [(PDFFloat,Maybe style,[B style])] hunk ./Graphics/PDF/Typesetting/Breaking.hs 627 -penalty :: Style style => PDFFloat -- ^ Penalty width - -> Int -- ^ Penalty value +penalty :: Style style => Int -- ^ Penalty value hunk ./Graphics/PDF/Typesetting/Breaking.hs 629 -penalty w p = Penalty w p False +penalty p = Penalty p hunk ./Graphics/PDF/Typesetting/Breaking.hs 640 -asAny (Penalty w p f) = Penalty w p f +asAny (FlaggedPenalty w p s) = FlaggedPenalty w p (AnyStyle s) +asAny (Penalty p) = Penalty p hunk ./Graphics/PDF/Typesetting/Horizontal.hs 19 + , splitText hunk ./Graphics/PDF/Typesetting/Horizontal.hs 28 +import qualified Data.ByteString.Lazy.Char8 as B(pack,unpack) + hunk ./Graphics/PDF/Typesetting/Horizontal.hs 40 -concatHMode r style (t,w) ((Penalty _ _ _):l') = concatHMode r style (t,w) l' +concatHMode r style (t,w) ((FlaggedPenalty _ _ _):l') = concatHMode r style (t,w) l' +concatHMode r style (t,w) ((Penalty _):l') = concatHMode r style (t,w) l' hunk ./Graphics/PDF/Typesetting/Horizontal.hs 60 -simplify ((Penalty _ _ _):l) = simplify l +simplify ((FlaggedPenalty _ _ _):l) = simplify l +simplify ((Penalty _):l) = simplify l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 65 -horizontalPostProcess :: Style style => [(PDFFloat,[B style])] -> [(PDFFloat,[B style])] +horizontalPostProcess :: Style style => [(PDFFloat,Maybe style,[B style])] -> [(PDFFloat,[B style])] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 68 - processHLine (r,l') = (r,simplifyHMode r . simplify $ l') + processHLine (r,Just s,l') = (r,(simplifyHMode r . simplify $ l') ++ [hyphenBox s]) + processHLine (r,Nothing,l') = (r,simplifyHMode r . simplify $ l') + hunk ./Graphics/PDF/Typesetting/Horizontal.hs 103 -endParagraphBoxes = [glue 0 10000.0 0,penalty 0 (-infinity)] +endParagraphBoxes = [glue 0 10000.0 0,penalty (-infinity)] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 105 +-- | Add spaces after . if there is none +punctuation :: B.ByteString -> B.ByteString +punctuation = B.pack . processPunctuation . B.unpack + where + processPunctuation [] = [] + processPunctuation ('.':b:c) | b /= ' ' = '.':' ':processPunctuation (b:c) + | otherwise = '.':b:processPunctuation c + processPunctuation (a:b) = a :processPunctuation b + hunk ./Graphics/PDF/Typesetting/Horizontal.hs 116 -getWords x = B.splitWith B.isSpaceWord8 $ x +getWords x = B.splitWith B.isSpaceWord8 . punctuation $ x + +convertWord :: AnyStyle -> B.ByteString -> [B AnyStyle] +convertWord s = analyzeLetters . B.unpack + where + analyzeLetters [] = [] + analyzeLetters ('/':'-':l) = hyphenPenalty s : analyzeLetters l + analyzeLetters (a:l) = (createTextBox s (PDFString . singleton $ a)) : analyzeLetters l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 129 - | otherwise = wordTransform f [createTextBox f $ (PDFString x)] + | otherwise = wordTransform f (convertWord f x) -- [createTextBox f $ (PDFString x)] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 133 - wordTransform f [createTextBox f $ (PDFString x)] ++ addSpacesToLine f g xs + wordTransform f (convertWord f x) ++ addSpacesToLine f g xs hunk ./Graphics/PDF/Typesetting/Horizontal.hs 135 - wordTransform f [createTextBox f $ (PDFString x)] ++ [g] ++ addSpacesToLine f g xs - + wordTransform f (convertWord f x) ++ [g] ++ addSpacesToLine f g xs hunk ./Graphics/PDF/Typesetting/Horizontal.hs 138 +-- | split a line into boxes +splitText :: AnyStyle -> PDFString -> [B AnyStyle] +splitText f (PDFString t) = addSpacesToLine f (spaceGlue f) . getWords $ t hunk ./Graphics/PDF/Typesetting/Vertical.hs 35 -strokeVBoxes b _ fx y' = recurseStrokeVBoxes 1 b y' +strokeVBoxes b _ fx y'' = recurseStrokeVBoxes 1 b y'' hunk ./Graphics/PDF/Typesetting.hs 35 + , hyphen hunk ./Graphics/PDF/Typesetting.hs 60 +onlyPositive :: (Int -> PDFFloat) -> (Int -> PDFFloat) +onlyPositive f = \l -> let w = f l in + if w <= 0 + then + error $ "One of your line width is negative or null at line " ++ (show l) + else + w hunk ./Graphics/PDF/Typesetting.hs 76 - l = formatList fmaxw boxes + l = formatList (onlyPositive fmaxw) boxes hunk ./Graphics/PDF/Typesetting.hs 81 --- | split a line into boxes -splitText :: PDFString -> TM () -splitText (PDFString t) = do - f <- gets tmStyle - tell $ addSpacesToLine f (spaceGlue f) . getWords $ t + hunk ./Graphics/PDF/Typesetting.hs 110 - splitText (toPDFString t) + f <- gets tmStyle + tell $ splitText f (toPDFString t) hunk ./Graphics/PDF/Typesetting.hs 117 - splitText (toPDFString t) + f <- gets tmStyle + tell $ splitText f (toPDFString t) hunk ./Graphics/PDF/Typesetting.hs 123 + +hyphen :: TM () +hyphen = do + f <- gets tmStyle + tell $ [hyphenPenalty f] hunk ./Test/test.hs 186 +circleArea x y = + let ws = textWidth (PDFFont Times_Roman 10) (toPDFString " ") + h = getHeight (PDFFont Times_Roman 10) + r = 50.0 * ws + angle l = asin $ (r - (fromIntegral l) * h ) / r + xpos l = x - r * cos (angle l) + width l = 2*r*cos (angle l) + in + TextArea xpos y width + hunk ./Test/test.hs 219 - txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " - txt $ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " - txt $ "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " - txt $ "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - endParagraph + txt $ "Lor/-em ip/-sum do/-lor sit am/-et, con/-se/-cte/-tur adi/-pi/-si/-cing el/-it, sed do eius/-mod tem/-por inci/-didunt ut lab/-ore et do/-lo/-re ma/-gna ali/-qua. " + txt $ "Ut en/-im ad mi/-nim ven/-iam, quis no/-strud ex/-er/-ci/-ta/-tion ulla/-mco la/-bo/-ris ni/-si ut ali/-quip ex ea commo/-do con/-se/-quat. Duis au/-te ir/-ure " + txt $ "do/-lor in re/-pre/-hen/-der/-it in vo/-lup/-ta/-te ve/-lit es/-se cil/-lum do/-lo/-re eu fu/-giat nul/-la pa/-ria/-tur. Ex/-cep/-teur sint oc/-cae/-cat cu/-pi/-da/-tat non " + txt $ "pro/-ident, sunt in cul/-pa qui of/-fi/-cia de/-se/-runt mol/-lit anim id est la/-bo/-rum." hunk ./Test/test.hs 232 - mapM_ (const par) [1..10] hunk ./Test/test.hs 241 - displayFormattedText (triangleArea 10 300) Normal debugText + --displayFormattedText (triangleArea 10 300) Normal debugText + displayFormattedText (circleArea 300 300) Normal (mapM_ (const par) [1..3] >> endParagraph) hunk ./Test/test.hs 296 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = True}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = False}) rect $ do hunk ./Graphics/PDF/Typesetting/Breaking.hs 45 - hunk ./Graphics/PDF/Typesetting/Breaking.hs 412 -createBreaknode prev (ZList _ (w,y,z,_,FlaggedPenalty _ p _) _) | p <= (-infinity) = BreakNode w y z 0.0 True 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,Penalty p) _) | p <= (-infinity) = BreakNode w y z 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,FlaggedPenalty _ p _) _) | p <= infinity = BreakNode w y z 0.0 True 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,Penalty p) _) | p <= infinity = BreakNode w y z 0.0 False 0 0.0 prev hunk ./Graphics/PDF/Typesetting/Breaking.hs 448 +isFeasibleBreakpoint _ (ZList _ _ []) = True hunk ./Graphics/PDF/Typesetting/Breaking.hs 517 + nbreaks = Map.filter (\x -> demerit x < dmin + fitness_demerit) breaks' hunk ./Graphics/PDF/Typesetting/Breaking.hs 519 - (Map.filter (\x -> demerit x < dmin + fitness_demerit) breaks', actives') + if Map.null nbreaks + then + (breaks' , actives') + else + (nbreaks , actives') hunk ./Graphics/PDF/Typesetting/Breaking.hs 543 - -- If forced breakpoint of no bearkpoint found + -- If forced breakpoint or no breakpoint found hunk ./Graphics/PDF/Typesetting/Breaking.hs 550 - analyzeBoxes True fmaxw actives z + if not pass + then + analyzeBoxes True fmaxw actives z + else + error "Second pass analysis failed ! Generally due to wrong width in the text area" hunk ./Graphics/PDF/Typesetting/Breaking.hs 565 - let minBreak = getMinBreak breaks' in hunk ./Graphics/PDF/Typesetting/Breaking.hs 569 + let minBreak = getMinBreak breaks' in hunk ./Graphics/PDF/Typesetting/Breaking.hs 591 - error "Breakpoint marked as not flagged but detected as flagged ! Send a bug report !" + error $ "Breakpoint marked as not flagged but detected as flagged ! Send a bug report ! " ++ show (ra,ba,fa) hunk ./Graphics/PDF/Typesetting.hs 74 - let (a, _, boxes) = (runRWS . unTM $ t >>= \x' -> do {endParagraph ; return x'} ) () (TMState (AnyStyle defaultStyle)) + let (a, _, boxes) = (runRWS . unTM $ t >>= \x' -> do {return x'} ) () (TMState (AnyStyle defaultStyle)) hunk ./Test/test.hs 112 +data DebugStyle = DebugStyle deriving(Eq) hunk ./Test/test.hs 128 - +instance Style DebugStyle where + sentenceStyle _ = Nothing + wordStyle _ = Just $ \r m d -> + case m of + DrawWord -> d >> return () + DrawGlue -> d >> stroke r + textStyle _ = TextStyle (PDFFont Times_Roman 10) black black FillText 1.0 1.0 1.0 1.0 + styleCode _ = 5 + updateStyle = id + hunk ./Test/test.hs 200 - angle l = asin $ (r - (fromIntegral l) * h ) / r + pasin x = if x >= 1.0 then pi/2 else if x <= -1.0 then (-pi/2) else asin x + angle l = pasin $ (r - (fromIntegral l) * h ) / r hunk ./Test/test.hs 253 - displayFormattedText (circleArea 300 300) Normal (mapM_ (const par) [1..3] >> endParagraph) + displayFormattedText (circleArea 300 300) Normal (setStyle Normal >> mapM_ (const par) [1..3] >> endParagraph) hunk ./Graphics/PDF/Typesetting/Breaking.hs 448 -isFeasibleBreakpoint _ (ZList _ _ []) = True hunk ./Graphics/PDF/Typesetting/Breaking.hs 553 - error "Second pass analysis failed ! Generally due to wrong width in the text area" + error "Second pass analysis failed ! Generally due to wrong width in the text area or an end of text before end of paragraph detected" hunk ./Graphics/PDF/Typesetting/Breaking.hs 564 - -- If the end it must be a possible breakpoint - -- We should NEVER reach this part. The end should always be a forced breakpoint - if theEnd z - then - let minBreak = getMinBreak breaks' in - getRightOrderNodeList minBreak - else - -- We continue the analysis - analyzeBoxes pass fmaxw newActives (moveRight z) + if Map.null breaks' + then + if theEnd z + then + error "End of text found but no paragraph end detected" + else + analyzeBoxes pass fmaxw actives' (moveRight z) + else + -- If the end it must be a possible breakpoint + -- We should NEVER reach this part. The end should always be a forced breakpoint + if theEnd z + then + let minBreak = getMinBreak breaks' in + getRightOrderNodeList minBreak + else + -- We continue the analysis + analyzeBoxes pass fmaxw newActives (moveRight z) hunk ./Test/test.hs 307 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = False}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = True}) rect $ do hunk ./Graphics/PDF/Typesetting/Breaking.hs 36 -import Data.List(minimumBy) +import Data.List(minimumBy,foldl') hunk ./Graphics/PDF/Typesetting/Breaking.hs 240 - boxWidth l r = foldr (\x y -> y + boxWidth x r) 0.0 l + boxWidth l r = foldl' (\y x -> y + boxWidth x r) 0.0 l hunk ./Graphics/PDF/Typesetting/Breaking.hs 556 - let minBreak = getMinBreak breaks' in + let minBreak = getMinBreak breaks' + someNewBreaks = getRightOrderNodeList minBreak + in hunk ./Graphics/PDF/Typesetting/Breaking.hs 561 - getRightOrderNodeList minBreak + someNewBreaks hunk ./Graphics/PDF/Typesetting/Breaking.hs 563 - getRightOrderNodeList minBreak ++ analyzeBoxes pass fmaxw (Map.insert (getKey minBreak) (getNode minBreak) Map.empty) (moveRight z) + someNewBreaks ++ analyzeBoxes pass fmaxw (Map.insert (getKey minBreak) (getNode minBreak) Map.empty) (moveRight z) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 24 -import Data.ByteString.Lazy.Char8(singleton) +import Data.ByteString.Lazy.Char8(singleton,cons) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 26 -import qualified Data.ByteString.Lazy as B(ByteString,null,splitWith,append) +import qualified Data.ByteString.Lazy as B(ByteString,null,splitWith,cons,head,reverse) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 30 -import Data.Maybe(isJust,fromJust) +import Data.Maybe(isJust,fromJust,isNothing) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 32 --- Concat consecutive words and glue that have the same style to draw the sentence with one PDF command -concatHMode :: Style s => PDFFloat -> s -> (B.ByteString,PDFFloat) -> [B s] -> [B s] -concatHMode r style (t,w) l@((Text s (PDFString t') w'):l') | styleCode style == styleCode s = concatHMode r style (B.append t t', w + w') l' - | otherwise = Text style (PDFString t) w : simplifyHMode r l --- That glue is special. It is just a space and we will processed as a space -concatHMode r style (t,w) l@(a@(Glue _ _ _ (Just s)):l') | styleCode style == styleCode s = concatHMode r style (B.append t (singleton ' '), w + boxWidth a r) l' - | otherwise = Text style (PDFString t) w : simplifyHMode r l --- Penalties are invisible in the final document -concatHMode r style (t,w) ((FlaggedPenalty _ _ _):l') = concatHMode r style (t,w) l' -concatHMode r style (t,w) ((Penalty _):l') = concatHMode r style (t,w) l' -concatHMode r style (t,w) l = Text style (PDFString t) w : simplifyHMode r l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 33 +strict :: a -> a +strict f = seq f f hunk ./Graphics/PDF/Typesetting/Horizontal.hs 36 --- Simplification for improving the generated PDF code. We concatenate words when the word style is not enabled --- and the style is the same -simplifyHMode :: Style s => PDFFloat -> [B s] -> [B s] -simplifyHMode _ [] = [] -simplifyHMode r (a@(Text s (PDFString t) w):l) = - if (isJust . wordStyle $ s) - then - a:simplifyHMode r l - else - concatHMode r s (t,w) l -simplifyHMode r (a:l) = a:simplifyHMode r l +-- WARNING +-- According to splitText, PDFText to concatenate ARE letters so we can optimize the code +-- Sentences are created when no word style is present, otherwise we just create words +createWords :: Style s => PDFFloat -- ^ Adjustement ratio + -> Maybe s -- ^ Hyphen style + -> Maybe (s,B.ByteString, PDFFloat) -- ^ Current word + -> [B s] -- ^ List of letters + -> [B s] -- ^ List of words or sentences hunk ./Graphics/PDF/Typesetting/Horizontal.hs 45 +createWords r Nothing Nothing [] = [] +-- Empty list, current word or sentence is added +createWords r Nothing (Just (s,t,w)) [] = [Text s (PDFString . B.reverse $ t) w] + +createWords r (Just hs) Nothing [] = [hyphenBox hs] +-- Empty list, current word or sentence is added +createWords r (Just hs) (Just (s,t,w)) [] = [Text s (PDFString . B.reverse $ t) w,hyphenBox hs] + +-- Start of a new word +createWords r hs Nothing ((Text s (PDFString t) w):l) = createWords r hs (Just (s,t,w)) l +-- New letter. Same style added to the word. Otherwise we start a new word +createWords r hs (Just (s,t,w)) ((Text s' (PDFString t') w'):l) | styleCode s == styleCode s' = createWords r hs (Just (s,B.cons (B.head t') t,w+w')) l + | otherwise = (Text s (PDFString . B.reverse $ t) w):createWords r hs (Just (s',t',w')) l + +-- Glue. Same style and no word mode, then we add to the sentence. Otherwise we close current word or sentence +createWords r hs (Just (s,t,w)) (a@(Glue _ _ _ (Just s')):l) | (isNothing . wordStyle $ s) && (styleCode s == styleCode s') = + createWords r hs (Just (s,cons ' ' t,w + boxWidth a r)) l + | otherwise = (Text s (PDFString . B.reverse $ t) w):a:createWords r hs Nothing l + +-- Penalties are invisible. The are needed just to compute breaks +createWords r hs c (Penalty _:l) = createWords r hs c l +createWords r hs c (FlaggedPenalty _ _ _:l) = createWords r hs c l + +-- We just add the box +createWords r hs Nothing (a:l) = a:createWords r hs Nothing l + +-- Close current word and add the box +createWords r hs (Just (s,t,w)) (a:l) = (Text s (PDFString . B.reverse $ t) w):a:createWords r hs Nothing l + hunk ./Graphics/PDF/Typesetting/Horizontal.hs 75 -simplify :: [B s] -> [B s] -simplify ((Glue _ _ _ _):l) = simplify l -simplify ((FlaggedPenalty _ _ _):l) = simplify l -simplify ((Penalty _):l) = simplify l -simplify l = l +simplify :: Style s => PDFFloat -- ^ Adjustement ratio + -> Maybe s -- ^ Hyphen style + -> [B s] -- ^ List of letters + -> [B s] -- ^ List of words +simplify r s ((Glue _ _ _ _):l) = simplify r s l +simplify r s ((FlaggedPenalty _ _ _):l) = simplify r s l +simplify r s ((Penalty _):l) = simplify r s l +simplify r s l = createWords r s Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 86 -horizontalPostProcess l = map processHLine l - where - processHLine (r,Just s,l') = (r,(simplifyHMode r . simplify $ l') ++ [hyphenBox s]) - processHLine (r,Nothing,l') = (r,simplifyHMode r . simplify $ l') +horizontalPostProcess [] = [] +horizontalPostProcess ((r,s,l'):l) = (r,simplify r s l'):horizontalPostProcess l -- (r,simplifyHMode r s . simplify $ l'):horizontalPostProcess l + hunk ./Graphics/PDF/Typesetting/Horizontal.hs 137 +-- | PDFStrings are singletons after this code hunk ./Graphics/PDF/Typesetting/Horizontal.hs 157 - +-- WARNING : must generate a list of LETTERS +-- word are created with the analysis of style just above hunk ./Test/test.hs 207 -typesetTest :: PDFReference PDFPage -> PDF () -typesetTest page = do +typesetTest :: Int -> PDFReference PDFPage -> PDF () +typesetTest test page = do hunk ./Test/test.hs 229 + endParagraph hunk ./Test/test.hs 236 - txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " - setStyle Bold - txt $ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " - setStyle Normal - txt $ "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " - txt $ "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - endParagraph hunk ./Test/test.hs 237 + mapM_ (const (par >> endParagraph)) [1..5] hunk ./Test/test.hs 246 - --displayFormattedText (rectangleArea 10 300 maxw) Normal debugText - --displayFormattedText (triangleArea 10 300) Normal debugText - displayFormattedText (circleArea 300 300) Normal (setStyle Normal >> mapM_ (const par) [1..3] >> endParagraph) + case test of + 1 -> displayFormattedText (rectangleArea 10 300 maxw) Normal myText + 2 -> displayFormattedText (rectangleArea 10 300 maxw) Normal debugText + 3 -> displayFormattedText (circleArea 300 300) Normal (setStyle Normal >> mapM_ (const par) [1..3] >> endParagraph) + _ -> displayFormattedText (rectangleArea 10 300 maxw) Normal myText + hunk ./Test/test.hs 257 - typesetTest page - - page <- addPage Nothing - newSection (toPDFString "Shapes") Nothing Nothing $ do - - newSection (toPDFString "Geometry") Nothing Nothing $ do - drawWithPage page $ do - geometryTest - - page <- addPage Nothing - newSection (toPDFString "Line style") Nothing Nothing $ do - drawWithPage page $ do - lineStyle - page <- addPage Nothing - newSection (toPDFString "Object reuse") Nothing Nothing $ do - r <- createPDFXForm 0 0 200 200 lineStyle - drawWithPage page $ do - drawXObject r + newSection (toPDFString "Normal text") Nothing Nothing $ do + typesetTest 1 page + + page <- addPage Nothing + newSection (toPDFString "Debug text") Nothing Nothing $ do + typesetTest 2 page hunk ./Test/test.hs 264 - page <- addPage Nothing - newSectionWithPage (toPDFString "Painting") Nothing Nothing page $ do - newSection (toPDFString "Patterns") Nothing Nothing $ do - patternTest page hunk ./Test/test.hs 265 - newSection (toPDFString "Shading") Nothing Nothing $ do - drawWithPage page $ do - shadingTest - page <- addPage Nothing - newSection (toPDFString "Media") Nothing Nothing $ do - newSection (toPDFString "image") Nothing Nothing $ do - testImage page - - page <- addPage Nothing - newSection (toPDFString "Annotations") Nothing Nothing $ do - drawWithPage page $ do - testAnnotation - page <- addPage Nothing - newSection (toPDFString "Text") Nothing Nothing $ do - drawWithPage page $ do - textTest - newSection (toPDFString "Fun") Nothing Nothing $ do - penrose + newSection (toPDFString "Circle text") Nothing Nothing $ do + typesetTest 3 page + -- + --page <- addPage Nothing + --newSection (toPDFString "Shapes") Nothing Nothing $ do + -- + -- newSection (toPDFString "Geometry") Nothing Nothing $ do + -- drawWithPage page $ do + -- geometryTest + -- + -- page <- addPage Nothing + -- newSection (toPDFString "Line style") Nothing Nothing $ do + -- drawWithPage page $ do + -- lineStyle + -- page <- addPage Nothing + -- newSection (toPDFString "Object reuse") Nothing Nothing $ do + -- r <- createPDFXForm 0 0 200 200 lineStyle + -- drawWithPage page $ do + -- drawXObject r + -- + --page <- addPage Nothing + --newSectionWithPage (toPDFString "Painting") Nothing Nothing page $ do + -- newSection (toPDFString "Patterns") Nothing Nothing $ do + -- patternTest page + -- page <- addPage Nothing + -- newSection (toPDFString "Shading") Nothing Nothing $ do + -- drawWithPage page $ do + -- shadingTest + --page <- addPage Nothing + --newSection (toPDFString "Media") Nothing Nothing $ do + -- newSection (toPDFString "image") Nothing Nothing $ do + -- testImage page + -- + --page <- addPage Nothing + --newSection (toPDFString "Annotations") Nothing Nothing $ do + -- drawWithPage page $ do + -- testAnnotation + --page <- addPage Nothing + --newSection (toPDFString "Text") Nothing Nothing $ do + -- drawWithPage page $ do + -- textTest + --newSection (toPDFString "Fun") Nothing Nothing $ do + -- penrose hunk ./Graphics/PDF/Typesetting/Breaking.hs 36 -import Data.List(minimumBy,foldl') +import Data.List(minimumBy) hunk ./Graphics/PDF/Typesetting/Breaking.hs 232 -instance (Style s) => DisplayableBox [B s] where - strokeBox [] _ _ _ = return () - - strokeBox (a:l) r x y = do - strokeBox a r x y - strokeBox l r (x + boxWidth a r) y +--instance (Style s) => DisplayableBox [B s] where +-- strokeBox [] _ _ _ = return () +-- +-- strokeBox (a:l) r x y = do +-- strokeBox a r x y +-- strokeBox l r (x + boxWidth a r) y hunk ./Graphics/PDF/Typesetting/Breaking.hs 239 -instance Box a => Box [a] where - boxWidth l r = foldl' (\y x -> y + boxWidth x r) 0.0 l - boxHeight l = maximum . map boxHeight $ l - boxDescent l = maximum . map boxDescent $ l +--instance Box a => Box [a] where +-- boxWidth l r = foldl' (\y x -> y + boxWidth x r) 0.0 l +-- boxHeight l = maximum . map boxHeight $ l +-- boxDescent l = maximum . map boxDescent $ l hunk ./Graphics/PDF/Typesetting/Breaking.hs 586 +cutList [] _ _ = [] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 20 + , mkHBox hunk ./Graphics/PDF/Typesetting/Horizontal.hs 27 +import Graphics.PDF.Draw hunk ./Graphics/PDF/Typesetting/Horizontal.hs 31 - hunk ./Graphics/PDF/Typesetting/Horizontal.hs 32 +import Data.List(foldl') hunk ./Graphics/PDF/Typesetting/Horizontal.hs 35 -strict :: a -> a -strict f = seq f f - hunk ./Graphics/PDF/Typesetting/Horizontal.hs 44 -createWords r Nothing Nothing [] = [] +createWords _ Nothing Nothing [] = [] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 46 -createWords r Nothing (Just (s,t,w)) [] = [Text s (PDFString . B.reverse $ t) w] +createWords _ Nothing (Just (s,t,w)) [] = [Text s (PDFString . B.reverse $ t) w] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 48 -createWords r (Just hs) Nothing [] = [hyphenBox hs] +createWords _ (Just hs) Nothing [] = [hyphenBox hs] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 50 -createWords r (Just hs) (Just (s,t,w)) [] = [Text s (PDFString . B.reverse $ t) w,hyphenBox hs] +createWords _ (Just hs) (Just (s,t,w)) [] = [Text s (PDFString . B.reverse $ t) w,hyphenBox hs] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 86 -horizontalPostProcess ((r,s,l'):l) = (r,simplify r s l'):horizontalPostProcess l -- (r,simplifyHMode r s . simplify $ l'):horizontalPostProcess l +horizontalPostProcess ((r,s,l'):l) = (r,simplify r s l'):horizontalPostProcess l + +data HBox a = HBox !PDFFloat ![a] deriving(Show) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 90 - - - -newtype HBox a = HBox [a] +-- | Create an HBox +mkHBox :: Box a => PDFFloat -- ^ Adjustement ratio + -> [a] -- ^ List of boxes + -> HBox a + +mkHBox r l = HBox r l + +getBoxWidthOfList :: Box a => [a] -- ^ List of boxes + -> PDFFloat -- ^ Adjustement ratio + -> PDFFloat -- ^ width +getBoxWidthOfList l r = foldl' (\y x -> y + boxWidth x r) 0.0 l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 103 - boxWidth (HBox a) = boxWidth a - boxHeight (HBox a) = boxHeight a - boxDescent (HBox a) = boxDescent a + boxWidth (HBox r l) _ = getBoxWidthOfList l r + + boxHeight (HBox _ []) = 0 + boxHeight (HBox _ l) = maximum . map boxHeight $ l + + boxDescent (HBox _ []) = 0 + boxDescent (HBox _ l) = maximum . map boxDescent $ l + +-- Stroke a list of box without any special processing +strokeList :: Style s => [B s] -- ^ List of boxes + -> PDFFloat -- ^ Adjust ratio + -> PDFFloat -- ^ x + -> PDFFloat -- ^ y + -> Draw () +strokeList [] _ _ _ = return () + +strokeList (a:l) r x y = do + strokeBox a r x y + strokeList l r (x + boxWidth a r) y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 125 - strokeBox (HBox []) _ _ _ = return () + strokeBox (HBox _ []) _ _ _ = return () hunk ./Graphics/PDF/Typesetting/Horizontal.hs 128 - strokeBox (HBox(l@(a@(Text style _ _):nl))) r x y = do + strokeBox (HBox r (l@(a@(Text style _ _):nl))) _ x y = do hunk ./Graphics/PDF/Typesetting/Horizontal.hs 134 - w = boxWidth l' r - (fromJust . sentenceStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) (strokeBox l' r x y) - strokeBox (HBox l'') r (x+w) y + w = getBoxWidthOfList l' r + (fromJust . sentenceStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) (strokeList l' r x y) + strokeBox (HBox r l'') r (x + w) y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 139 - strokeBox (HBox nl) r (x + boxWidth a r) y + strokeBox (HBox r nl) r (x + boxWidth a r) y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 141 - strokeBox (HBox(a:l)) r x y = do + strokeBox (HBox r (a:l)) _ x y = do hunk ./Graphics/PDF/Typesetting/Horizontal.hs 143 - strokeBox (HBox l) r (x + boxWidth a r) y + strokeBox (HBox r l) r (x + boxWidth a r) y hunk ./Graphics/PDF/Typesetting/Vertical.hs 15 + , TextArea(..) hunk ./Graphics/PDF/Typesetting/Vertical.hs 22 -import Graphics.PDF.Typesetting.Horizontal(HBox(..)) +import Graphics.PDF.Typesetting.Horizontal(mkHBox,horizontalPostProcess) hunk ./Graphics/PDF/Typesetting/Vertical.hs 25 -newtype VBox a = VBox [(PDFFloat,HBox a)] +-- | Pair of functions describing the shape of a text areas : horizontal position of each line, vertical top of the area, width of each line +-- First line is 1 +data TextArea = TextArea (Int -> PDFFloat) PDFFloat (Int -> PDFFloat) hunk ./Graphics/PDF/Typesetting/Vertical.hs 29 +data VBox s = Paragraph [B s] + | VBox (B s) + +-- | Force width of text area to positive value +onlyPositive :: (Int -> PDFFloat) -> (Int -> PDFFloat) +onlyPositive f = \l -> let w = f l in + if w <= 0 + then + error $ "One of your line width is negative or null at line " ++ (show l) + else + w + +-- | Shift origin for the text area +shiftBy :: Int -> (Int -> PDFFloat) -> (Int -> PDFFloat) +shiftBy o f = \x -> f (x + o) + +-- | Convert pure lines to VBoxes +toVBoxes :: Style style => [(PDFFloat,[B style])] -> [VBox style] +toVBoxes = map createVBox + where + createVBox (r,l) = VBox (B $ mkHBox r l) + +-- | Create VBoxes. Paragraphs are analyzd and cut into VBoxes +createVBoxes :: Style s => Int -- ^ Line offset for the text area + -> TextArea -- ^ Text area + -> [VBox s] -- ^ List of VBox with paragraphs + -> [VBox s] -- ^ List of VBox where paragraphs have been line broken +createVBoxes _ _ [] = [] +createVBoxes o t (a@(VBox _):l') = a:createVBoxes (o+1) t l' +createVBoxes o t@(TextArea _ _ fmaxw) ((Paragraph l):l') = + let fl = formatList (onlyPositive . shiftBy o $ fmaxw) l + in + (toVBoxes . horizontalPostProcess $ fl) ++ createVBoxes (o + length fl) t l' hunk ./Graphics/PDF/Typesetting/Vertical.hs 63 -createVBoxes :: Style style => [(PDFFloat,[B style])] -> VBox (B style) -createVBoxes = VBox . map (\(r,l) -> (r, HBox l)) hunk ./Graphics/PDF/Typesetting/Vertical.hs 64 -strokeVBoxes :: Style s => VBox (B s) +-- | Stroke the VBoxes +strokeVBoxes :: Style s => [VBox s] -- ^ List of boxes hunk ./Graphics/PDF/Typesetting/Vertical.hs 72 - recurseStrokeVBoxes _ (VBox []) _ = return () - recurseStrokeVBoxes nb (VBox((ra,theLine):l)) y = do + recurseStrokeVBoxes _ [] _ = return () + recurseStrokeVBoxes _ (Paragraph _:_) _ = return () + recurseStrokeVBoxes nb ((VBox theLine):l) y = do hunk ./Graphics/PDF/Typesetting/Vertical.hs 77 - strokeBox theLine ra (fx nb) y' - recurseStrokeVBoxes (nb+1) (VBox l) (y - h) + strokeBox theLine 1.0 (fx nb) y' -- Adjustement ratio is forced by the HBox so we can pass 1.0 + recurseStrokeVBoxes (nb+1) l (y - h) hunk ./Graphics/PDF/Typesetting.hs 26 - , setStyle - , endParagraph + , Para + , MonadStyle(..) hunk ./Graphics/PDF/Typesetting.hs 30 - , addBox - , currentStyle hunk ./Graphics/PDF/Typesetting.hs 44 --- | Pair of functions describing the shape of a text areas : horizontal position of each line, vertical top of the area, width of each line --- First line is 1 -data TextArea = TextArea (Int -> PDFFloat) PDFFloat (Int -> PDFFloat) + hunk ./Graphics/PDF/Typesetting.hs 56 -onlyPositive :: (Int -> PDFFloat) -> (Int -> PDFFloat) -onlyPositive f = \l -> let w = f l in - if w <= 0 - then - error $ "One of your line width is negative or null at line " ++ (show l) - else - w hunk ./Graphics/PDF/Typesetting.hs 62 -displayFormattedText (TextArea fx y fmaxw) defaultStyle t = do +displayFormattedText area@(TextArea fx y fmaxw) defaultStyle t = do hunk ./Graphics/PDF/Typesetting.hs 65 - l = formatList (onlyPositive fmaxw) boxes + -- l = formatList (onlyPositive fmaxw) boxes hunk ./Graphics/PDF/Typesetting.hs 67 - strokeVBoxes (createVBoxes . horizontalPostProcess $ l) 1.0 fx y + --strokeVBoxes (createVBoxes . horizontalPostProcess $ l) 1.0 fx y + strokeVBoxes (createVBoxes 0 area boxes) 1.0 fx y hunk ./Graphics/PDF/Typesetting.hs 74 -endParagraph :: TM () -endParagraph = TM $ tell endParagraphBoxes +endParagraph :: a -> Para a +endParagraph r = do + tell endParagraphBoxes + return r + hunk ./Graphics/PDF/Typesetting.hs 80 -data TMState = TMState { tmStyle :: !AnyStyle} +data TMState = TMState { tmStyle :: !AnyStyle + } hunk ./Graphics/PDF/Typesetting.hs 83 -newtype TM a = TM { unTM :: RWS () [B AnyStyle] TMState a} +newtype TM a = TM { unTM :: RWS () [VBox AnyStyle] TMState a} hunk ./Graphics/PDF/Typesetting.hs 85 - deriving(Monad,MonadWriter [B AnyStyle], MonadState TMState, Functor) + deriving(Monad,MonadWriter [VBox AnyStyle], MonadState TMState, Functor) hunk ./Graphics/PDF/Typesetting.hs 88 -instance MonadWriter [B AnyStyle] TM +instance MonadWriter [VBox AnyStyle] TM hunk ./Graphics/PDF/Typesetting.hs 93 --- | Set style of text -setStyle :: Style a => a -> TM () -setStyle f = modifyStrict $ \s -> s {tmStyle = AnyStyle f} +newtype Para a = Para { unPara :: RWS () [B AnyStyle] AnyStyle a} +#ifndef __HADDOCK__ + deriving(Monad,MonadWriter [B AnyStyle], MonadState AnyStyle, Functor) +#else +instance Monad Para +instance MonadWriter [B AnyStyle] Para +instance MonadState AnyStyle Para +instance Functor Para +#endif + +class Monad m => MonadStyle m where + setStyle :: Style a => a -> m () + currentStyle :: m AnyStyle + addBox :: (Show a, DisplayableBox a, Box a) => a -> m () + + +instance MonadStyle TM where + -- | Set style of text + setStyle f = modifyStrict $ \s -> s {tmStyle = AnyStyle f} + + -- | Get current text style + currentStyle = gets tmStyle + + -- | Add a box to the stream in vertical mode + addBox a = tell ([VBox (B a)]) + + +instance MonadStyle Para where + -- | Set style of text + setStyle f = put $! AnyStyle f + + -- | Get current text style + currentStyle = get + + -- | Add a box to the stream in horizontal mode + addBox a = tell ([B a]) + +-- | Run a paragraph. Style changes are local to the paragraph +runPara :: Para a -> TM a +runPara m = do + f <- currentStyle + let (a, s', boxes) = (runRWS . unPara $ (m >>= endParagraph) ) () f + tell $ [Paragraph boxes] + return a hunk ./Graphics/PDF/Typesetting.hs 138 --- | Get current text style -currentStyle :: TM AnyStyle -currentStyle = gets tmStyle hunk ./Graphics/PDF/Typesetting.hs 140 -paragraph :: String -> TM () -paragraph t = do - f <- gets tmStyle - tell $ splitText f (toPDFString t) - endParagraph +paragraph :: Para a -> TM a +paragraph = runPara hunk ./Graphics/PDF/Typesetting.hs 144 -txt :: String -> TM () +txt :: String -> Para () hunk ./Graphics/PDF/Typesetting.hs 146 - f <- gets tmStyle + f <- currentStyle hunk ./Graphics/PDF/Typesetting.hs 149 --- | Add a box to the stream -addBox :: (Show a, DisplayableBox a, Box a) => a -> TM () -addBox a = tell ([B a]) - -hyphen :: TM () +hyphen :: Para () hunk ./Graphics/PDF/Typesetting.hs 151 - f <- gets tmStyle + f <- currentStyle hunk ./Test/test.hs 211 - txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor " - setStyle Bold - txt $ "incididunt ut labore et dolore magna aliqua. " - setStyle Normal - txt $ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " - txt $ "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " - endParagraph - txt $ "Excepteur sint occaecat cupidatat non" - txt $ " proident, sunt in culpa qui officia deserunt mollit anim id est laborum." - setStyle superCrazy - txt $ " And now, a super crazy style to test the code. " - setStyle Normal - txt $ "Return to a normal style :-)" - endParagraph - txt $ "More crazy styles ... " - setStyle Crazy - par - setStyle Normal - endParagraph + paragraph $ do + txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor " + setStyle Bold + txt $ "incididunt ut labore et dolore magna aliqua. " + setStyle Normal + txt $ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " + txt $ "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " + paragraph $ do + txt $ "Excepteur sint occaecat cupidatat non" + txt $ " proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + setStyle superCrazy + txt $ " And now, a super crazy style to test the code. " + setStyle Normal + txt $ "Return to a normal style :-)" + paragraph $ do + txt $ "More crazy styles ... " + setStyle Crazy + par + setStyle Normal hunk ./Test/test.hs 237 - mapM_ (const (par >> endParagraph)) [1..5] + mapM_ (const (paragraph par)) [1..4] hunk ./Test/test.hs 249 - 3 -> displayFormattedText (circleArea 300 300) Normal (setStyle Normal >> mapM_ (const par) [1..3] >> endParagraph) + 3 -> displayFormattedText (circleArea 300 300) Normal (setStyle Normal >> paragraph (mapM_ (const par) [1..3]) ) hunk ./Graphics/PDF/Text.hs 40 + , ripText + , charWidth hunk ./Graphics/PDF/Text.hs 49 +import Data.ByteString.Base(w2c,c2w) hunk ./Graphics/PDF/Text.hs 90 - + +charWidth :: PDFFont -> Char -> PDFFloat +charWidth (PDFFont n s) c = let w = cgetAdvance (fromEnum n) (c2w c) in + trueSize s w + +ripText :: PDFFont -- ^ Font + -> PDFString -- ^ String + -> [(PDFFloat,Char)] -- ^ List of chars and char width taking into account kerning +ripText (PDFFont n s) (PDFString t) = getLetters (hasKern (fromEnum n)) . B.unpack $ t + where + getLetters _ [] = [] + getLetters _ [a] = [(trueSize s $ cgetAdvance (fromEnum n) a,w2c a)] + getLetters False (a:b:l) = (trueSize s $ cgetAdvance (fromEnum n) a,w2c a) : getLetters False (b:l) + getLetters True (a:b:l) = (trueSize s $ cgetAdvance (fromEnum n) a + getKern (fromEnum n,a,b),w2c a) : getLetters True (b:l) + hunk ./Graphics/PDF/Typesetting/Breaking.hs 15 - B(..) + Letter(..) hunk ./Graphics/PDF/Typesetting/Breaking.hs 23 + , AnyBox(..) hunk ./Graphics/PDF/Typesetting/Breaking.hs 25 - , createTextBox + , createChar hunk ./Graphics/PDF/Typesetting/Breaking.hs 29 - , nullBox - , asAny - , isSameStyle + , nullLetter hunk ./Graphics/PDF/Typesetting/Breaking.hs 31 - , hyphenBox + , splitText hunk ./Graphics/PDF/Typesetting/Breaking.hs 42 +import Data.Word hunk ./Graphics/PDF/Typesetting/Breaking.hs 77 - -- | A style may add boxes before and after the word - wordTransform :: a -> [B AnyStyle] -> [B AnyStyle] - wordTransform _ x = x - hunk ./Graphics/PDF/Typesetting/Breaking.hs 93 - wordTransform (AnyStyle a) = wordTransform a hunk ./Graphics/PDF/Typesetting/Breaking.hs 102 - -- | Bow height + -- | Box height hunk ./Graphics/PDF/Typesetting/Breaking.hs 107 --- | A box that cna be displayed +-- | A box that can be displayed hunk ./Graphics/PDF/Typesetting/Breaking.hs 116 -data NullBox = NullBox deriving(Show) +data NullChar = NullChar deriving(Show) hunk ./Graphics/PDF/Typesetting/Breaking.hs 119 -nullBox :: B NullBox -nullBox = B NullBox +nullLetter :: Letter +nullLetter = Letter (AnyBox NullChar) hunk ./Graphics/PDF/Typesetting/Breaking.hs 122 -instance Box NullBox where +instance Box NullChar where hunk ./Graphics/PDF/Typesetting/Breaking.hs 127 -instance DisplayableBox NullBox where +instance DisplayableBox NullChar where hunk ./Graphics/PDF/Typesetting/Breaking.hs 130 - --- | A box -data B style = forall a. (Show a,Box a, DisplayableBox a) => B !a - | Glue !PDFFloat !PDFFloat !PDFFloat !(Maybe style) - | FlaggedPenalty !PDFFloat !Int !style +instance Box AnyBox where + boxWidth (AnyBox a) = boxWidth a + boxHeight (AnyBox a) = boxHeight a + boxDescent (AnyBox a) = boxDescent a + +instance DisplayableBox AnyBox where + strokeBox (AnyBox a) = strokeBox a + +instance Show AnyBox where + show (AnyBox a) = show a + +-- | A letter which can be anything +data Letter = Letter !AnyBox + | Glue !PDFFloat !PDFFloat !PDFFloat !(Maybe AnyStyle) + | FlaggedPenalty !PDFFloat !Int !AnyStyle hunk ./Graphics/PDF/Typesetting/Breaking.hs 146 - | Text !style !PDFString !PDFFloat + | AChar !AnyStyle !Char !PDFFloat hunk ./Graphics/PDF/Typesetting/Breaking.hs 148 +data AnyBox = forall a. (Show a,Box a, DisplayableBox a) => AnyBox a hunk ./Graphics/PDF/Typesetting/Breaking.hs 150 - -instance Style style => Box (B style) where - boxWidth (Text _ _ w) _ = w - boxWidth (B a) r = boxWidth a r +instance Box Letter where + boxWidth (AChar _ _ w) _ = w + boxWidth (Letter a) r = boxWidth a r hunk ./Graphics/PDF/Typesetting/Breaking.hs 162 - boxHeight (Text style _ _) = styleHeight style - boxHeight (B a) = boxHeight a + boxHeight (AChar style _ _) = styleHeight style + boxHeight (Letter a) = boxHeight a hunk ./Graphics/PDF/Typesetting/Breaking.hs 168 - boxDescent (Text style _ _) = styleDescent style - boxDescent (B a) = boxDescent a + boxDescent (AChar style _ _) = styleDescent style + boxDescent (Letter a) = boxDescent a hunk ./Graphics/PDF/Typesetting/Breaking.hs 174 --- Draw a text box -drawTheTextBox :: Style style => style - -> PDFFloat - -> PDFFloat - -> PDFFloat - -> PDFString - -> Draw () -drawTheTextBox style r x y t = drawText $ do - setFont (textFont . textStyle $ style) - strokeColor (textStrokeColor . textStyle $ style) - fillColor (textFillColor . textStyle $ style) - renderMode (textMode . textStyle $ style) - --setWidth (penWidth . textStyle $ s) - -- Here we need to dilate the space to take into account r and the font setting - let ws = (textWidth (textFont . textStyle $ style) (toPDFString " ")) - h = scaleSpace . textStyle $ style - sy = scaleDilatation . textStyle $ style - sz = scaleCompression . textStyle $ style - dws = ws * h -- dilated space - gy = sy*dws / 2.0 - gz = sz*dws / 3.0 - delta = if r >= 0 then r*gy else r*gz - -- ws is the true font space. We use dws so we have a user overhead - -- and the overhead of the space dilatation - wordSpace (dws - ws + delta) - -- And we render the text - textStart x y - displayText t hunk ./Graphics/PDF/Typesetting/Breaking.hs 175 -instance Style style => DisplayableBox (B style) where - strokeBox b@(Glue _ _ _ (Just style)) r x y = do - let de = styleDescent style - he = styleHeight style - w = boxWidth b r - -- In word mode we have to apply a special function to the word - -- otherwise we apply a different function to the sentence - if (isJust . wordStyle $ style) - then - (fromJust . wordStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) DrawGlue (return ()) - else - return () - - strokeBox (Text style t w) r x y = do - let de = styleDescent style - he = styleHeight style - -- In word mode we have to apply a special function to the word - -- otherwise we apply a different function to the sentence - if (isJust . wordStyle $ style) - then - (fromJust . wordStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) DrawWord (drawTheTextBox style r x y t) - else - if (isJust . sentenceStyle $ style) - then - (fromJust . sentenceStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) (drawTheTextBox style r x y t) - else - drawTheTextBox style r x y t - - strokeBox (B a) r x y = strokeBox a r x y +instance DisplayableBox Letter where + strokeBox b@(Glue _ _ _ _) _ _ _ = return () + strokeBox (AChar _ _ _) _ _ _ = return () hunk ./Graphics/PDF/Typesetting/Breaking.hs 180 - strokeBox (Glue _ _ _ _) _ _ _ = return () - --- No special display for a simple list of boxes ---instance (Style s) => DisplayableBox [B s] where --- strokeBox [] _ _ _ = return () --- --- strokeBox (a:l) r x y = do --- strokeBox a r x y --- strokeBox l r (x + boxWidth a r) y + strokeBox (Letter a) r x y = strokeBox a r x y hunk ./Graphics/PDF/Typesetting/Breaking.hs 182 ---instance Box a => Box [a] where --- boxWidth l r = foldl' (\y x -> y + boxWidth x r) 0.0 l --- boxHeight l = maximum . map boxHeight $ l --- boxDescent l = maximum . map boxDescent $ l hunk ./Graphics/PDF/Typesetting/Breaking.hs 183 -instance Show (B style) where - show (B a) = "(B " ++ show a ++ ")" +instance Show Letter where + show (Letter a) = "(Letter " ++ show a ++ ")" hunk ./Graphics/PDF/Typesetting/Breaking.hs 188 - show (Text _ t _) = "(Text " ++ show t ++ ")" + show (AChar _ t _) = "(Text " ++ show t ++ ")" hunk ./Graphics/PDF/Typesetting/Breaking.hs 201 -class PointedBox a style | a -> style where +class PointedBox a where hunk ./Graphics/PDF/Typesetting/Breaking.hs 205 - box :: a -> B style + box :: a -> Letter hunk ./Graphics/PDF/Typesetting/Breaking.hs 212 -instance PointedBox (PDFFloat,PDFFloat,PDFFloat,Int,B style) style where +instance PointedBox (PDFFloat,PDFFloat,PDFFloat,Int,Letter) where hunk ./Graphics/PDF/Typesetting/Breaking.hs 231 -instance PointedBox (ZList style) style where +instance PointedBox ZList where hunk ./Graphics/PDF/Typesetting/Breaking.hs 243 -penaltyWidth :: B style -> PDFFloat +penaltyWidth :: Letter -> PDFFloat hunk ./Graphics/PDF/Typesetting/Breaking.hs 260 - -> ZList style + -> ZList hunk ./Graphics/PDF/Typesetting/Breaking.hs 304 - -> ZList style -- ^ Flag for current + -> ZList -- ^ Flag for current hunk ./Graphics/PDF/Typesetting/Breaking.hs 333 -data ZList style = ZList (MaybeCB (B style)) (PDFFloat,PDFFloat,PDFFloat,Int,B style) [B style] deriving(Show) +data ZList = ZList (MaybeCB Letter) (PDFFloat,PDFFloat,PDFFloat,Int,Letter) [Letter] deriving(Show) hunk ./Graphics/PDF/Typesetting/Breaking.hs 336 -createZList :: [B style] -> ZList style +createZList :: [Letter] -> ZList hunk ./Graphics/PDF/Typesetting/Breaking.hs 340 -theEnd :: ZList style -> Bool +theEnd :: ZList -> Bool hunk ./Graphics/PDF/Typesetting/Breaking.hs 346 -createBreaknode :: Style style => Maybe (Int,Int,Int,BreakNode) -> ZList style -> BreakNode +createBreaknode :: Maybe (Int,Int,Int,BreakNode) -> ZList -> BreakNode hunk ./Graphics/PDF/Typesetting/Breaking.hs 353 -createBreaknode prev (ZList _ (w,y,z,_,B _) _) = BreakNode w y z 0.0 False 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,Text _ _ _) _) = BreakNode w y z 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,Letter _) _) = BreakNode w y z 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,AChar _ _ _) _) = BreakNode w y z 0.0 False 0 0.0 prev hunk ./Graphics/PDF/Typesetting/Breaking.hs 357 --- | Create an hyphen box for current style -hyphenBox :: Style s => s -> B s -hyphenBox s = createTextBox s (toPDFString "-") - hunk ./Graphics/PDF/Typesetting/Breaking.hs 358 -hyphenPenalty :: Style s => s -> B s -hyphenPenalty s = FlaggedPenalty (boxWidth (hyphenBox s) 1.0) 0 s +hyphenPenalty :: AnyStyle -> Letter +hyphenPenalty s = FlaggedPenalty (charWidth (textFont . textStyle $ s) '-') 0 s hunk ./Graphics/PDF/Typesetting/Breaking.hs 361 -moveRight :: Style style => ZList style -> ZList style +moveRight :: ZList -> ZList hunk ./Graphics/PDF/Typesetting/Breaking.hs 381 - -> ZList style -- ^ Current analyzed box + -> ZList -- ^ Current analyzed box hunk ./Graphics/PDF/Typesetting/Breaking.hs 387 -isFeasibleBreakpoint _ (ZList (OneCB (_,_,_,_,B _)) (_,_,_,_,Glue _ _ _ _) _) = True -isFeasibleBreakpoint _ (ZList (OneCB (_,_,_,_,Text _ _ _)) (_,_,_,_,Glue _ _ _ _) _) = True +isFeasibleBreakpoint _ (ZList (OneCB (_,_,_,_,Letter _)) (_,_,_,_,Glue _ _ _ _) _) = True +isFeasibleBreakpoint _ (ZList (OneCB (_,_,_,_,AChar _ _ _)) (_,_,_,_,Glue _ _ _ _) _) = True hunk ./Graphics/PDF/Typesetting/Breaking.hs 412 - -> ZList style -- ^ Current + -> ZList -- ^ Current hunk ./Graphics/PDF/Typesetting/Breaking.hs 433 -getNewActiveBreakpoints :: Style style => Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList style -> (PossibleBreak,ActiveNodes) +getNewActiveBreakpoints :: Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList -> (PossibleBreak,ActiveNodes) hunk ./Graphics/PDF/Typesetting/Breaking.hs 468 -analyzeBoxes :: Style style => Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList style -> [(PDFFloat,Int,Bool)] +analyzeBoxes :: Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList -> [(PDFFloat,Int,Bool)] hunk ./Graphics/PDF/Typesetting/Breaking.hs 520 -cutList :: [B style] -> Int -> [(PDFFloat,Int,Bool)] -> [(PDFFloat,Maybe style,[B style])] +cutList :: [Letter] -> Int -> [(PDFFloat,Int,Bool)] -> [(PDFFloat,Maybe AnyStyle,[Letter])] hunk ./Graphics/PDF/Typesetting/Breaking.hs 548 -formatList :: Style style => (Int -> PDFFloat) -> [B style] -> [(PDFFloat,Maybe style,[B style])] +formatList :: (Int -> PDFFloat) -> [Letter] -> [(PDFFloat,Maybe AnyStyle,[Letter])] hunk ./Graphics/PDF/Typesetting/Breaking.hs 563 -glue :: Style style => PDFFloat -- ^ Glue width +glue :: PDFFloat -- ^ Glue width hunk ./Graphics/PDF/Typesetting/Breaking.hs 566 - -> B style + -> Letter hunk ./Graphics/PDF/Typesetting/Breaking.hs 570 -spaceGlue :: Style style => style -- ^ The style - -> B style +spaceGlue :: AnyStyle -- ^ The style + -> Letter hunk ./Graphics/PDF/Typesetting/Breaking.hs 581 -penalty :: Style style => Int -- ^ Penalty value - -> B style +penalty :: Int -- ^ Penalty value + -> Letter hunk ./Graphics/PDF/Typesetting/Breaking.hs 586 -createTextBox :: Style style => style -> PDFString -> B style -createTextBox s t = Text s t (textWidth (textFont . textStyle $ s) t) - --- | Forget the style -asAny :: Style style => B style -> B AnyStyle -asAny (Text s t w) = Text (AnyStyle s) t w -asAny (Glue w y z (Just r)) = Glue w y z (Just (AnyStyle r)) -asAny (Glue w y z Nothing) = Glue w y z Nothing -asAny (FlaggedPenalty w p s) = FlaggedPenalty w p (AnyStyle s) -asAny (Penalty p) = Penalty p -asAny (B a) = B a +createChar :: AnyStyle -- ^ Char style + -> PDFFloat -- ^ Char width + -> Char -- ^ Char code + -> Letter +createChar s w t = AChar s t w hunk ./Graphics/PDF/Typesetting/Breaking.hs 593 - - -- Test is a box has same style -isSameStyle :: Style s => s - -> B s - -> Bool -isSameStyle s (Text style _ _) = styleCode s == styleCode style -isSameStyle s (Glue _ _ _ (Just style)) = styleCode s == styleCode style -isSameStyle _ _ = False +-- | Create boxes for the letters +createLetterBoxes :: AnyStyle -- ^ Letter style + -> [(PDFFloat,Char)] -- ^ Letter and size + -> [Letter] -- ^ Boxes +createLetterBoxes _ [] = [] +createLetterBoxes s (a@(wa,'.'):b@(wb,bc):l') | bc /= ' ' = (createChar s wa '.'): spaceGlue s : createLetterBoxes s l' + | otherwise = (createChar s wa '.') : createLetterBoxes s (b:l') +createLetterBoxes s ((_,'/'):(_,'-'):l) = hyphenPenalty s : createLetterBoxes s l +createLetterBoxes s ((_,' '):l) = (spaceGlue s) : createLetterBoxes s l +createLetterBoxes s ((w,t):l) = (createChar s w t) : createLetterBoxes s l + +-- WARNING : must generate a list of LETTERS +-- word are created with the analysis of style just above +-- | split a line into boxes +splitText :: AnyStyle -> PDFString -> [Letter] +splitText f t = createLetterBoxes f . ripText (textFont . textStyle $ f) $ t hunk ./Graphics/PDF/Typesetting/Horizontal.hs 15 + , HLine(..) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 17 - , endParagraphBoxes - , addSpacesToLine - , getWords - , splitText - , mkHBox hunk ./Graphics/PDF/Typesetting/Horizontal.hs 29 - +import Graphics.PDF.Colors +import Graphics.PDF.Text hunk ./Graphics/PDF/Typesetting/Horizontal.hs 35 -createWords :: Style s => PDFFloat -- ^ Adjustement ratio - -> Maybe s -- ^ Hyphen style - -> Maybe (s,B.ByteString, PDFFloat) -- ^ Current word - -> [B s] -- ^ List of letters - -> [B s] -- ^ List of words or sentences +createWords :: PDFFloat -- ^ Adjustement ratio + -> Maybe AnyStyle -- ^ Hyphen style + -> Maybe (AnyStyle,B.ByteString, PDFFloat) -- ^ Current word + -> [Letter] -- ^ List of letters + -> [HBox] -- ^ List of words or sentences hunk ./Graphics/PDF/Typesetting/Horizontal.hs 43 -createWords _ Nothing (Just (s,t,w)) [] = [Text s (PDFString . B.reverse $ t) w] +createWords r Nothing (Just (s,t,w)) [] = [createText s (PDFString . B.reverse $ t) w] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 47 -createWords _ (Just hs) (Just (s,t,w)) [] = [Text s (PDFString . B.reverse $ t) w,hyphenBox hs] +createWords _ (Just hs) (Just (s,t,w)) [] = [createText s (PDFString . B.reverse $ (cons '-' t)) w] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 50 -createWords r hs Nothing ((Text s (PDFString t) w):l) = createWords r hs (Just (s,t,w)) l +createWords r hs Nothing ((AChar s t w):l) = createWords r hs (Just (s,singleton t,w)) l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 52 -createWords r hs (Just (s,t,w)) ((Text s' (PDFString t') w'):l) | styleCode s == styleCode s' = createWords r hs (Just (s,B.cons (B.head t') t,w+w')) l - | otherwise = (Text s (PDFString . B.reverse $ t) w):createWords r hs (Just (s',t',w')) l +createWords r hs (Just (s,t,w)) ((AChar s' t' w'):l) | styleCode s == styleCode s' = createWords r hs (Just (s,cons t' t,w+w')) l + | otherwise = (createText s (PDFString . B.reverse $ t) w):createWords r hs (Just (s',singleton t',w')) l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 56 -createWords r hs (Just (s,t,w)) (a@(Glue _ _ _ (Just s')):l) | (isNothing . wordStyle $ s) && (styleCode s == styleCode s') = +createWords r hs (Just (s,t,w)) (a@(Glue wg yg zg (Just s')):l)| (isNothing . wordStyle $ s) && (styleCode s == styleCode s') = hunk ./Graphics/PDF/Typesetting/Horizontal.hs 58 - | otherwise = (Text s (PDFString . B.reverse $ t) w):a:createWords r hs Nothing l + | otherwise = (createText s (PDFString . B.reverse $ t) w):(HGlue (boxWidth a r) (Just s')):createWords r hs Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 65 -createWords r hs Nothing (a:l) = a:createWords r hs Nothing l - --- Close current word and add the box -createWords r hs (Just (s,t,w)) (a:l) = (Text s (PDFString . B.reverse $ t) w):a:createWords r hs Nothing l +createWords r hs Nothing (a@(Glue wg yg zg s):l) = (HGlue (boxWidth a r) s):createWords r hs Nothing l +createWords r hs (Just (s,t,w)) (a@(Glue wg yg zg Nothing):l) = (createText s (PDFString . B.reverse $ t) w):(HGlue (boxWidth a r) Nothing):createWords r hs Nothing l + +createWords r hs Nothing ((Letter a):l) = (HBox a):createWords r hs Nothing l +createWords r hs (Just (s,t,w)) ((Letter a):l) = (createText s (PDFString . B.reverse $ t) w):(HBox a):createWords r hs Nothing l + hunk ./Graphics/PDF/Typesetting/Horizontal.hs 73 -simplify :: Style s => PDFFloat -- ^ Adjustement ratio - -> Maybe s -- ^ Hyphen style - -> [B s] -- ^ List of letters - -> [B s] -- ^ List of words +simplify :: PDFFloat -- ^ Adjustement ratio + -> Maybe AnyStyle -- ^ Hyphen style + -> [Letter] -- ^ List of letters + -> [HBox] -- ^ List of words or sentence hunk ./Graphics/PDF/Typesetting/Horizontal.hs 83 -horizontalPostProcess :: Style style => [(PDFFloat,Maybe style,[B style])] -> [(PDFFloat,[B style])] +horizontalPostProcess :: [(PDFFloat,Maybe AnyStyle,[Letter])] -- ^ adjust ratio, hyphen style, list of letters or boxes + -> [HLine] -- ^ List of lines hunk ./Graphics/PDF/Typesetting/Horizontal.hs 86 -horizontalPostProcess ((r,s,l'):l) = (r,simplify r s l'):horizontalPostProcess l +horizontalPostProcess ((r,s,l'):l) = (HLine r $ simplify r s l'):horizontalPostProcess l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 88 -data HBox a = HBox !PDFFloat ![a] deriving(Show) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 89 --- | Create an HBox -mkHBox :: Box a => PDFFloat -- ^ Adjustement ratio - -> [a] -- ^ List of boxes - -> HBox a +-- | An horizontal Hbox (sentence or word) +-- The width of the glue was computed with the adjustement ratio of the HLine containing the glue +-- The width of the text is already taking into account the adjustement ratio of the HLine containing the Text +-- Otherwise, HBox cannot dilate or compress. +data HBox = HBox !AnyBox + | HGlue !PDFFloat !(Maybe AnyStyle) + | Text !AnyStyle !PDFString !PDFFloat hunk ./Graphics/PDF/Typesetting/Horizontal.hs 97 -mkHBox r l = HBox r l +-- | A line of hboxes with an adjustement ratio required to display the text (generate the PDF command to increase space size) +data HLine = HLine !PDFFloat ![HBox] deriving(Show) + +-- | Create an HBox +createText :: Style s => s -- ^ Style + -> PDFString -- ^ String + -> PDFFloat -- ^ Width + -> HBox +createText s t w = Text (AnyStyle s) t w + +-- | Create an hyphen box +hyphenBox :: Style s => s -> HBox +hyphenBox s = createText s (PDFString . singleton $ '-') (charWidth (textFont . textStyle $ s) '-') + +instance Show HBox where + show (HBox a) = "(HBox " ++ show a ++ ")" + show (HGlue a _) = "(HGlue " ++ show a ++ ")" + show (Text _ t _) = "(Text " ++ show t ++ ")" + hunk ./Graphics/PDF/Typesetting/Horizontal.hs 117 -getBoxWidthOfList :: Box a => [a] -- ^ List of boxes +getBoxWidthOfList :: [HBox] -- ^ List of hboxes hunk ./Graphics/PDF/Typesetting/Horizontal.hs 122 -instance Box a => Box (HBox a) where - boxWidth (HBox r l) _ = getBoxWidthOfList l r +instance Box HLine where + boxWidth (HLine r l) _ = getBoxWidthOfList l r hunk ./Graphics/PDF/Typesetting/Horizontal.hs 125 - boxHeight (HBox _ []) = 0 - boxHeight (HBox _ l) = maximum . map boxHeight $ l + boxHeight (HLine _ []) = 0 + boxHeight (HLine _ l) = maximum . map boxHeight $ l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 128 - boxDescent (HBox _ []) = 0 - boxDescent (HBox _ l) = maximum . map boxDescent $ l + boxDescent (HLine _ []) = 0 + boxDescent (HLine _ l) = maximum . map boxDescent $ l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 132 -strokeList :: Style s => [B s] -- ^ List of boxes +strokeList :: [HBox] -- ^ List of boxes hunk ./Graphics/PDF/Typesetting/Horizontal.hs 144 -instance (Style s) => DisplayableBox (HBox (B s)) where - strokeBox (HBox _ []) _ _ _ = return () +instance DisplayableBox HLine where + strokeBox (HLine _ []) _ _ _ = return () hunk ./Graphics/PDF/Typesetting/Horizontal.hs 148 - strokeBox (HBox r (l@(a@(Text style _ _):nl))) _ x y = do + strokeBox (HLine r (l@(a@(Text style _ _):nl))) _ x y = do hunk ./Graphics/PDF/Typesetting/Horizontal.hs 156 - strokeBox (HBox r l'') r (x + w) y + strokeBox (HLine r l'') r (x + w) y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 159 - strokeBox (HBox r nl) r (x + boxWidth a r) y + strokeBox (HLine r nl) r (x + boxWidth a r) y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 161 - strokeBox (HBox r (a:l)) _ x y = do + strokeBox (HLine r (a:l)) _ x y = do hunk ./Graphics/PDF/Typesetting/Horizontal.hs 163 - strokeBox (HBox r l) r (x + boxWidth a r) y + strokeBox (HLine r l) r (x + boxWidth a r) y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 165 -endParagraphBoxes :: Style s => [B s] -endParagraphBoxes = [glue 0 10000.0 0,penalty (-infinity)] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 166 --- | Add spaces after . if there is none -punctuation :: B.ByteString -> B.ByteString -punctuation = B.pack . processPunctuation . B.unpack - where - processPunctuation [] = [] - processPunctuation ('.':b:c) | b /= ' ' = '.':' ':processPunctuation (b:c) - | otherwise = '.':b:processPunctuation c - processPunctuation (a:b) = a :processPunctuation b - --- | Cut into words but keep spaces at beginning and end -getWords :: B.ByteString -> [B.ByteString] -getWords x = B.splitWith B.isSpaceWord8 . punctuation $ x hunk ./Graphics/PDF/Typesetting/Horizontal.hs 167 --- | PDFStrings are singletons after this code -convertWord :: AnyStyle -> B.ByteString -> [B AnyStyle] -convertWord s = analyzeLetters . B.unpack - where - analyzeLetters [] = [] - analyzeLetters ('/':'-':l) = hyphenPenalty s : analyzeLetters l - analyzeLetters (a:l) = (createTextBox s (PDFString . singleton $ a)) : analyzeLetters l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 168 --- | Convert each string to a box and add the glue for the spaces (with beginning and ending space) -addSpacesToLine :: AnyStyle -> B AnyStyle -> [B.ByteString] -> [B AnyStyle] -addSpacesToLine _ _ [] = [] -addSpacesToLine f g [x] | B.null x = [g] - | otherwise = wordTransform f (convertWord f x) -- [createTextBox f $ (PDFString x)] -addSpacesToLine f g (x:xs) | B.null x = g : addSpacesToLine f g xs - | otherwise = if B.null . head $ xs - then - wordTransform f (convertWord f x) ++ addSpacesToLine f g xs - else - wordTransform f (convertWord f x) ++ [g] ++ addSpacesToLine f g xs +instance Box HBox where + boxWidth (Text _ _ w) _ = w + boxWidth (HBox a) r = boxWidth a r + boxWidth (HGlue w _) r = w + + boxHeight (Text style _ _) = styleHeight style + boxHeight (HBox a) = boxHeight a + boxHeight (HGlue _ _) = 0 + + boxDescent (Text style _ _) = styleDescent style + boxDescent (HBox a) = boxDescent a + boxDescent (HGlue _ _) = 0 hunk ./Graphics/PDF/Typesetting/Horizontal.hs 181 --- WARNING : must generate a list of LETTERS --- word are created with the analysis of style just above --- | split a line into boxes -splitText :: AnyStyle -> PDFString -> [B AnyStyle] -splitText f (PDFString t) = addSpacesToLine f (spaceGlue f) . getWords $ t + +-- Draw a text box +drawTheTextBox :: Style style => style + -> PDFFloat + -> PDFFloat + -> PDFFloat + -> PDFString + -> Draw () +drawTheTextBox style r x y t = drawText $ do + setFont (textFont . textStyle $ style) + strokeColor (textStrokeColor . textStyle $ style) + fillColor (textFillColor . textStyle $ style) + renderMode (textMode . textStyle $ style) + --setWidth (penWidth . textStyle $ s) + -- Here we need to dilate the space to take into account r and the font setting + let ws = (textWidth (textFont . textStyle $ style) (toPDFString " ")) + h = scaleSpace . textStyle $ style + sy = scaleDilatation . textStyle $ style + sz = scaleCompression . textStyle $ style + dws = ws * h -- dilated space + gy = sy*dws / 2.0 + gz = sz*dws / 3.0 + delta = if r >= 0 then r*gy else r*gz + -- ws is the true font space. We use dws so we have a user overhead + -- and the overhead of the space dilatation + wordSpace (dws - ws + delta) + -- And we render the text + textStart x y + displayText t + +instance DisplayableBox HBox where + strokeBox b@(HGlue w (Just style)) r x y = do + let de = styleDescent style + he = styleHeight style + -- In word mode we have to apply a special function to the word + -- otherwise we apply a different function to the sentence + if (isJust . wordStyle $ style) + then + (fromJust . wordStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) DrawGlue (return ()) + else + return () + + strokeBox (Text style t w) r x y = do + let de = styleDescent style + he = styleHeight style + -- In word mode we have to apply a special function to the word + -- otherwise we apply a different function to the sentence + if (isJust . wordStyle $ style) + then + (fromJust . wordStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) DrawWord (drawTheTextBox style r x y t) + else + if (isJust . sentenceStyle $ style) + then + (fromJust . sentenceStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) (drawTheTextBox style r x y t) + else + drawTheTextBox style r x y t + + strokeBox (HBox a) r x y = strokeBox a r x y + strokeBox (HGlue _ _) _ _ _ = return () + + -- Test is a box has same style +isSameStyle :: Style s => s + -> HBox + -> Bool +isSameStyle s (Text style _ _) = styleCode s == styleCode style +isSameStyle s (HGlue _ (Just style)) = styleCode s == styleCode style +isSameStyle _ _ = False + hunk ./Graphics/PDF/Typesetting/Vertical.hs 22 -import Graphics.PDF.Typesetting.Horizontal(mkHBox,horizontalPostProcess) +import Graphics.PDF.Typesetting.Horizontal(horizontalPostProcess,HLine) hunk ./Graphics/PDF/Typesetting/Vertical.hs 29 -data VBox s = Paragraph [B s] - | VBox (B s) +data VBox = Paragraph [Letter] + | VBox AnyBox hunk ./Graphics/PDF/Typesetting/Vertical.hs 46 -toVBoxes :: Style style => [(PDFFloat,[B style])] -> [VBox style] +toVBoxes :: [HLine] -- ^ List of lines + -> [VBox] -- ^ List of VBoxes hunk ./Graphics/PDF/Typesetting/Vertical.hs 50 - createVBox (r,l) = VBox (B $ mkHBox r l) + createVBox = VBox . AnyBox hunk ./Graphics/PDF/Typesetting/Vertical.hs 53 -createVBoxes :: Style s => Int -- ^ Line offset for the text area +createVBoxes :: Int -- ^ Line offset for the text area hunk ./Graphics/PDF/Typesetting/Vertical.hs 55 - -> [VBox s] -- ^ List of VBox with paragraphs - -> [VBox s] -- ^ List of VBox where paragraphs have been line broken + -> [VBox] -- ^ List of VBox with paragraphs + -> [VBox] -- ^ List of VBox where paragraphs have been line broken hunk ./Graphics/PDF/Typesetting/Vertical.hs 66 -strokeVBoxes :: Style s => [VBox s] -- ^ List of boxes +strokeVBoxes :: [VBox] -- ^ List of boxes hunk ./Graphics/PDF/Typesetting.hs 21 - , B hunk ./Graphics/PDF/Typesetting.hs 29 - , nullBox + , nullChar hunk ./Graphics/PDF/Typesetting.hs 57 -displayFormattedText :: Style d => TextArea -- ^ Text area - -> d -- ^ Default style +displayFormattedText :: Style s => TextArea -- ^ Text area + -> s -- ^ Default style hunk ./Graphics/PDF/Typesetting.hs 70 - +endParagraphBoxes :: [Letter] +endParagraphBoxes = [glue 0 10000.0 0,penalty (-infinity)] hunk ./Graphics/PDF/Typesetting.hs 83 -newtype TM a = TM { unTM :: RWS () [VBox AnyStyle] TMState a} +newtype TM a = TM { unTM :: RWS () [VBox] TMState a} hunk ./Graphics/PDF/Typesetting.hs 85 - deriving(Monad,MonadWriter [VBox AnyStyle], MonadState TMState, Functor) + deriving(Monad,MonadWriter [VBox], MonadState TMState, Functor) hunk ./Graphics/PDF/Typesetting.hs 88 -instance MonadWriter [VBox AnyStyle] TM +instance MonadWriter [VBox] TM hunk ./Graphics/PDF/Typesetting.hs 93 -newtype Para a = Para { unPara :: RWS () [B AnyStyle] AnyStyle a} +newtype Para a = Para { unPara :: RWS () [Letter] AnyStyle a} hunk ./Graphics/PDF/Typesetting.hs 95 - deriving(Monad,MonadWriter [B AnyStyle], MonadState AnyStyle, Functor) + deriving(Monad,MonadWriter [Letter], MonadState AnyStyle, Functor) hunk ./Graphics/PDF/Typesetting.hs 98 -instance MonadWriter [B AnyStyle] Para +instance MonadWriter [Letter] Para hunk ./Graphics/PDF/Typesetting.hs 117 - addBox a = tell ([VBox (B a)]) + addBox a = tell ([VBox (AnyBox a)]) hunk ./Graphics/PDF/Typesetting.hs 128 - addBox a = tell ([B a]) + addBox a = tell ([Letter (AnyBox a)]) hunk ./Graphics/PDF/Typesetting.hs 142 + +-- | Add a null char +nullChar :: Para () +nullChar = tell $ [nullLetter] hunk ./Graphics/PDF/Text.hs 100 + slash = c2w '/' + hyphen = c2w '-' hunk ./Graphics/PDF/Text.hs 104 - getLetters False (a:b:l) = (trueSize s $ cgetAdvance (fromEnum n) a,w2c a) : getLetters False (b:l) + getLetters False (a:l) = (trueSize s $ cgetAdvance (fromEnum n) a,w2c a) : getLetters False l + getLetters True (a:b:c:d:l) | b == slash && c == hyphen = + let k = getKern (fromEnum n,a,d) + hw = cgetAdvance (fromEnum n) hyphen + in + (trueSize s $ cgetAdvance (fromEnum n) a + k,w2c a):(0,'/'):(trueSize s $ hw-k,'-'):getLetters True (d:l) + | otherwise = (trueSize s $ cgetAdvance (fromEnum n) a + getKern (fromEnum n,a,b),w2c a) : getLetters True (b:c:d:l) hunk ./Graphics/PDF/Typesetting.hs 32 - , hyphen hunk ./Graphics/PDF/Typesetting.hs 39 -import Graphics.PDF.Typesetting.Horizontal hunk ./Graphics/PDF/Typesetting.hs 40 - - +import Graphics.PDF.Typesetting.Box hunk ./Graphics/PDF/Typesetting.hs 58 -displayFormattedText area@(TextArea fx y fmaxw) defaultStyle t = do +displayFormattedText area@(TextArea fx y _) defaultStyle t = do hunk ./Graphics/PDF/Typesetting.hs 114 - addBox a = tell ([VBox (AnyBox a)]) + addBox a = TM . tell $ ([VBox (AnyBox a)]) hunk ./Graphics/PDF/Typesetting.hs 132 + put $! TMState s' hunk ./Graphics/PDF/Typesetting.hs 143 -nullChar = tell $ [nullLetter] +nullChar = Para . tell $ [nullLetter] hunk ./Graphics/PDF/Typesetting.hs 151 -hyphen :: Para () -hyphen = do - f <- currentStyle - tell $ [hyphenPenalty f] addfile ./Graphics/PDF/Typesetting/Box.hs hunk ./Graphics/PDF/Typesetting/Box.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2006 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Box +--------------------------------------------------------- +-- #hide +module Graphics.PDF.Typesetting.Box ( + Box(..) + , DisplayableBox(..) + , AnyBox(..) + , NullChar(..) + ) where + +import Graphics.PDF.LowLevel.Types +import Graphics.PDF.Draw + +-- | A box with dimensions +class Box a where + -- | Box width + boxWidth :: a -- ^ Box + -> PDFFloat -- ^ Width with adjustement + -- | Box height + boxHeight :: a -> PDFFloat + -- | Distance between bow bottom and point where the base of the text line is + boxDescent :: a -> PDFFloat + +-- | A box that can be displayed +class DisplayableBox a where + -- | Draw a bow + strokeBox :: a -- ^ The box + -> PDFFloat -- ^ Adjustement ratio (used to dilate space when displaying a text with PDF raw commands) + -> PDFFloat -- ^ Horizontal position + -> PDFFloat -- ^ Vertical position + -> Draw () + +data NullChar = NullChar deriving(Show) + +instance Box NullChar where + boxWidth _ = 0 + boxHeight _ = 0 + boxDescent _ = 0 + +instance DisplayableBox NullChar where + strokeBox _ _ _ _ = return () + +instance Box AnyBox where + boxWidth (AnyBox a) = boxWidth a + boxHeight (AnyBox a) = boxHeight a + boxDescent (AnyBox a) = boxDescent a + +instance DisplayableBox AnyBox where + strokeBox (AnyBox a) = strokeBox a + +instance Show AnyBox where + show (AnyBox a) = show a + +data AnyBox = forall a. (Show a,Box a, DisplayableBox a) => AnyBox a hunk ./Graphics/PDF/Typesetting/Breaking.hs 17 - , Box(..) - , DisplayableBox(..) hunk ./Graphics/PDF/Typesetting/Breaking.hs 21 - , AnyBox(..) hunk ./Graphics/PDF/Typesetting/Breaking.hs 29 + , letterWidth hunk ./Graphics/PDF/Typesetting/Breaking.hs 38 -import Data.Maybe(isJust,fromJust) hunk ./Graphics/PDF/Typesetting/Breaking.hs 39 -import Data.Word - +import Graphics.PDF.Typesetting.Box(AnyBox(..),NullChar(..),Box(..)) +import Data.Maybe(fromJust) hunk ./Graphics/PDF/Typesetting/Breaking.hs 93 --- | A box with dimensions -class Box a where - -- | Box width - boxWidth :: a -- ^ Box - -> PDFFloat -- ^ Box adjustement ratio - -> PDFFloat -- ^ Width with adjustement - -- | Box height - boxHeight :: a -> PDFFloat - -- | Distance between bow bottom and point where the base of the text line is - boxDescent :: a -> PDFFloat - --- | A box that can be displayed -class DisplayableBox a where - -- | Draw a bow - strokeBox :: a -- ^ The box - -> PDFFloat -- ^ Adjustement ratio - -> PDFFloat -- ^ Horizontal position - -> PDFFloat -- ^ Vertical position - -> Draw () - -data NullChar = NullChar deriving(Show) + hunk ./Graphics/PDF/Typesetting/Breaking.hs 99 -instance Box NullChar where - boxWidth _ _ = 0 - boxHeight _ = 0 - boxDescent _ = 0 - -instance DisplayableBox NullChar where - strokeBox _ _ _ _ = return () - -instance Box AnyBox where - boxWidth (AnyBox a) = boxWidth a - boxHeight (AnyBox a) = boxHeight a - boxDescent (AnyBox a) = boxDescent a hunk ./Graphics/PDF/Typesetting/Breaking.hs 100 -instance DisplayableBox AnyBox where - strokeBox (AnyBox a) = strokeBox a - -instance Show AnyBox where - show (AnyBox a) = show a - hunk ./Graphics/PDF/Typesetting/Breaking.hs 107 -data AnyBox = forall a. (Show a,Box a, DisplayableBox a) => AnyBox a - -instance Box Letter where - boxWidth (AChar _ _ w) _ = w - boxWidth (Letter a) r = boxWidth a r - boxWidth (Glue w yi zi _) r = - if r >= 0 - then - r*yi + w - else - r*zi + w - boxWidth (FlaggedPenalty _ _ _) _ = 0 - boxWidth (Penalty _) _ = 0 - - boxHeight (AChar style _ _) = styleHeight style - boxHeight (Letter a) = boxHeight a - boxHeight (Glue _ _ _ _) = 0 - boxHeight (FlaggedPenalty _ _ _) = 0 - boxHeight (Penalty _) = 0 - - boxDescent (AChar style _ _) = styleDescent style - boxDescent (Letter a) = boxDescent a - boxDescent (Glue _ _ _ _) = 0 - boxDescent (FlaggedPenalty _ _ _) = 0 - boxDescent (Penalty _) = 0 - - -instance DisplayableBox Letter where - strokeBox b@(Glue _ _ _ _) _ _ _ = return () - strokeBox (AChar _ _ _) _ _ _ = return () - strokeBox (FlaggedPenalty _ _ _) _ _ _ = return () - strokeBox (Penalty _) _ _ _ = return () - strokeBox (Letter a) r x y = strokeBox a r x y - - +letterWidth :: Letter -- ^ letter + -> PDFFloat -- ^ Adjustement ratio + -> PDFFloat -- ^ Width +letterWidth (AChar _ _ w) _ = w +letterWidth (Letter a) _ = boxWidth a +letterWidth (Glue w yi zi _) r = + if r >= 0 + then + r*yi + w + else + r*zi + w +letterWidth (FlaggedPenalty _ _ _) _ = 0 +letterWidth (Penalty _) _ = 0 + hunk ./Graphics/PDF/Typesetting/Breaking.hs 131 -instance DisplayableBox a => DisplayableBox (CB a) where - strokeBox (_,_,_,_,a) = strokeBox a - -instance Box a => Box (CB a) where - boxWidth (_,_,_,_,a) = boxWidth a - boxHeight (_,_,_,_,a) = boxHeight a - boxDescent (_,_,_,_,a) = boxDescent a hunk ./Graphics/PDF/Typesetting/Breaking.hs 136 - box :: a -> Letter + letter :: a -> Letter hunk ./Graphics/PDF/Typesetting/Breaking.hs 152 - box (_,_,_,_,a) = a + letter (_,_,_,_,a) = a hunk ./Graphics/PDF/Typesetting/Breaking.hs 165 - box (ZList _ b _) = box b + letter (ZList _ b _) = letter b hunk ./Graphics/PDF/Typesetting/Breaking.hs 195 - let w = cumulatedW l - totalWidth a + penaltyWidth (box l) + let w = cumulatedW l - totalWidth a + penaltyWidth (letter l) hunk ./Graphics/PDF/Typesetting/Breaking.hs 281 -createBreaknode prev (ZList _ (w,y,z,_,a) []) = BreakNode (w + boxWidth a 0.0) (y) (z) 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,a) []) = BreakNode (w + letterWidth a 0.0) (y) (z) 0.0 False 0 0.0 prev hunk ./Graphics/PDF/Typesetting/Breaking.hs 289 -hyphenPenalty :: AnyStyle -> Letter -hyphenPenalty s = FlaggedPenalty (charWidth (textFont . textStyle $ s) '-') 0 s +hyphenPenalty :: AnyStyle -- ^ Style of future hyphen + -> PDFFloat -- ^ Size of hyphen taking into account the kerning that was perturbed by the hyphen introduction. The char before the hyphen is now bigger + -> Letter +hyphenPenalty s w = FlaggedPenalty w 0 s hunk ./Graphics/PDF/Typesetting/Breaking.hs 302 - let w' = boxWidth a 0.0 + let w' = letterWidth a 0.0 hunk ./Graphics/PDF/Typesetting/Breaking.hs 307 ---moveLeft :: ZList -> ZList ---moveLeft (ZList l c r) = ZList (tail l) (head l) ((box c):r) - ---fromZlist :: ZList -> [B] ---fromZlist (ZList l c r) = (reverse . map box $ l) ++ [box c] ++ r - hunk ./Graphics/PDF/Typesetting/Breaking.hs 525 -createLetterBoxes s (a@(wa,'.'):b@(wb,bc):l') | bc /= ' ' = (createChar s wa '.'): spaceGlue s : createLetterBoxes s l' +createLetterBoxes s ((wa,'.'):b@(_,bc):l') | bc /= ' ' = (createChar s wa '.'): spaceGlue s : createLetterBoxes s l' hunk ./Graphics/PDF/Typesetting/Breaking.hs 527 -createLetterBoxes s ((_,'/'):(_,'-'):l) = hyphenPenalty s : createLetterBoxes s l +createLetterBoxes s ((_,'/'):(w,'-'):l) = hyphenPenalty s w : createLetterBoxes s l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 24 -import qualified Data.ByteString.Lazy as B(ByteString,null,splitWith,cons,head,reverse) -import qualified Data.ByteString.Base as B(isSpaceWord8) -import qualified Data.ByteString.Lazy.Char8 as B(pack,unpack) +import qualified Data.ByteString.Lazy as B(ByteString,reverse) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 29 +import Graphics.PDF.Typesetting.Box hunk ./Graphics/PDF/Typesetting/Horizontal.hs 42 -createWords r Nothing (Just (s,t,w)) [] = [createText s (PDFString . B.reverse $ t) w] +createWords _ Nothing (Just (s,t,w)) [] = [createText s (PDFString . B.reverse $ t) w] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 46 -createWords _ (Just hs) (Just (s,t,w)) [] = [createText s (PDFString . B.reverse $ (cons '-' t)) w] +createWords _ (Just _) (Just (s,t,w)) [] = [createText s (PDFString . B.reverse $ (cons '-' t)) w] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 55 -createWords r hs (Just (s,t,w)) (a@(Glue wg yg zg (Just s')):l)| (isNothing . wordStyle $ s) && (styleCode s == styleCode s') = - createWords r hs (Just (s,cons ' ' t,w + boxWidth a r)) l - | otherwise = (createText s (PDFString . B.reverse $ t) w):(HGlue (boxWidth a r) (Just s')):createWords r hs Nothing l +createWords r hs (Just (s,t,w)) (a@(Glue _ _ _ (Just s')):l)| (isNothing . wordStyle $ s) && (styleCode s == styleCode s') = + createWords r hs (Just (s,cons ' ' t,w + letterWidth a r)) l + | otherwise = (createText s (PDFString . B.reverse $ t) w):(HGlue (letterWidth a r) (Just s')):createWords r hs Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 64 -createWords r hs Nothing (a@(Glue wg yg zg s):l) = (HGlue (boxWidth a r) s):createWords r hs Nothing l -createWords r hs (Just (s,t,w)) (a@(Glue wg yg zg Nothing):l) = (createText s (PDFString . B.reverse $ t) w):(HGlue (boxWidth a r) Nothing):createWords r hs Nothing l +createWords r hs Nothing (a@(Glue _ _ _ s):l) = (HGlue (letterWidth a r) s):createWords r hs Nothing l +createWords r hs (Just (s,t,w)) (a@(Glue _ _ _ Nothing):l) = (createText s (PDFString . B.reverse $ t) w):(HGlue (letterWidth a r) Nothing):createWords r hs Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 117 - -> PDFFloat -- ^ Adjustement ratio hunk ./Graphics/PDF/Typesetting/Horizontal.hs 118 -getBoxWidthOfList l r = foldl' (\y x -> y + boxWidth x r) 0.0 l +getBoxWidthOfList l = foldl' (\y x -> y + boxWidth x) 0.0 l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 121 - boxWidth (HLine r l) _ = getBoxWidthOfList l r + boxWidth (HLine _ l) = getBoxWidthOfList l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 139 - strokeList l r (x + boxWidth a r) y + strokeList l r (x + boxWidth a) y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 152 - w = getBoxWidthOfList l' r + w = getBoxWidthOfList l' hunk ./Graphics/PDF/Typesetting/Horizontal.hs 157 - strokeBox (HLine r nl) r (x + boxWidth a r) y + strokeBox (HLine r nl) r (x + boxWidth a) y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 161 - strokeBox (HLine r l) r (x + boxWidth a r) y + strokeBox (HLine r l) r (x + boxWidth a) y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 167 - boxWidth (Text _ _ w) _ = w - boxWidth (HBox a) r = boxWidth a r - boxWidth (HGlue w _) r = w + boxWidth (Text _ _ w) = w + boxWidth (HBox a) = boxWidth a + boxWidth (HGlue w _) = w hunk ./Graphics/PDF/Typesetting/Horizontal.hs 210 - strokeBox b@(HGlue w (Just style)) r x y = do + strokeBox (HGlue w (Just style)) _ x y = do hunk ./Graphics/PDF/Typesetting/Vertical.hs 24 +import Graphics.PDF.Typesetting.Box hunk ./HPDF.cabal 56 + Graphics.PDF.Typesetting.Box hunk ./Test/test.hs 113 +data RedRectStyle = RedRectStyle deriving(Eq) hunk ./Test/test.hs 129 +instance Style RedRectStyle where + sentenceStyle _ = Just $ \r d -> do + strokeColor red + stroke r + d + return() + wordStyle _ = Nothing + textStyle _ = TextStyle (PDFFont Times_Roman 10) black black FillText 1.0 1.0 1.0 1.0 + styleCode _ = 5 + updateStyle = id + hunk ./Test/test.hs 229 + setStyle RedRectStyle hunk ./Test/test.hs 327 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = True}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = False}) rect $ do hunk ./Graphics/PDF/Typesetting/Breaking.hs 229 -secondPassTolerance = 2.0 +secondPassTolerance = 1.5 hunk ./Graphics/PDF/Typesetting/Horizontal.hs 30 +import qualified Data.ByteString.Base as Base +import qualified Data.ByteString as Strict + +forceStrict :: Base.LazyByteString -> Base.LazyByteString +forceStrict (Base.LPS l) = Base.LPS [Strict.concat l] + +-- | Current word (created from letter) is converted to a PDFString +saveCurrentword :: B.ByteString -> PDFString +saveCurrentword = PDFString . forceStrict . B.reverse hunk ./Graphics/PDF/Typesetting/Horizontal.hs 51 -createWords _ Nothing (Just (s,t,w)) [] = [createText s (PDFString . B.reverse $ t) w] +createWords _ Nothing (Just (s,t,w)) [] = [createText s (saveCurrentword t) w] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 55 -createWords _ (Just _) (Just (s,t,w)) [] = [createText s (PDFString . B.reverse $ (cons '-' t)) w] +createWords _ (Just _) (Just (s,t,w)) [] = [createText s (saveCurrentword $ (cons '-' t)) w] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 61 - | otherwise = (createText s (PDFString . B.reverse $ t) w):createWords r hs (Just (s',singleton t',w')) l + | otherwise = (createText s (saveCurrentword $ t) w):createWords r hs (Just (s',singleton t',w')) l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 66 - | otherwise = (createText s (PDFString . B.reverse $ t) w):(HGlue (letterWidth a r) (Just s')):createWords r hs Nothing l + | otherwise = (createText s (saveCurrentword $ t) w):(HGlue (letterWidth a r) (Just s')):createWords r hs Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 74 -createWords r hs (Just (s,t,w)) (a@(Glue _ _ _ Nothing):l) = (createText s (PDFString . B.reverse $ t) w):(HGlue (letterWidth a r) Nothing):createWords r hs Nothing l +createWords r hs (Just (s,t,w)) (a@(Glue _ _ _ Nothing):l) = (createText s (saveCurrentword $ t) w):(HGlue (letterWidth a r) Nothing):createWords r hs Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 77 -createWords r hs (Just (s,t,w)) ((Letter a):l) = (createText s (PDFString . B.reverse $ t) w):(HBox a):createWords r hs Nothing l +createWords r hs (Just (s,t,w)) ((Letter a):l) = (createText s (saveCurrentword $ t) w):(HBox a):createWords r hs Nothing l hunk ./Test/test.hs 231 + setStyle Normal hunk ./Test/test.hs 245 - txt $ "Lor/-em ip/-sum do/-lor sit am/-et, con/-se/-cte/-tur adi/-pi/-si/-cing el/-it, sed do eius/-mod tem/-por inci/-didunt ut lab/-ore et do/-lo/-re ma/-gna ali/-qua. " - txt $ "Ut en/-im ad mi/-nim ven/-iam, quis no/-strud ex/-er/-ci/-ta/-tion ulla/-mco la/-bo/-ris ni/-si ut ali/-quip ex ea commo/-do con/-se/-quat. Duis au/-te ir/-ure " + txt $ "Lor/-em ip/-sum do/-lor sit am/-et, con/-se/-cte/-tur adi/-pi/-si/-cing el/-it, sed do eius/-mod tem/-por inci/-di/-dunt ut lab/-ore et do/-lo/-re ma/-gna ali/-qua. " + txt $ "Ut en/-im ad mi/-nim ven/-iam, quis no/-strud ex/-er/-ci/-ta/-tion ul/-lam/-co labo/-ris ni/-si ut ali/-quip ex ea com/-mo/-do con/-se/-quat. Duis au/-te ir/-ure " hunk ./Test/test.hs 248 - txt $ "pro/-ident, sunt in cul/-pa qui of/-fi/-cia de/-se/-runt mol/-lit anim id est la/-bo/-rum." + txt $ "pro/-id/-ent, sunt in cul/-pa qui of/-fi/-cia de/-se/-runt mol/-lit anim id est la/-bo/-rum." hunk ./Test/test.hs 250 - -- Duplicate paragraph four times + -- Duplicate paragraph several times hunk ./Test/test.hs 328 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = False}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = True}) rect $ do hunk ./Graphics/PDF/Text.hs 107 + kh = getKern (fromEnum n,a,hyphen) hunk ./Graphics/PDF/Text.hs 110 - (trueSize s $ cgetAdvance (fromEnum n) a + k,w2c a):(0,'/'):(trueSize s $ hw-k,'-'):getLetters True (d:l) + -- We record the hyphen size + an adaptation due to the different kerning with an hyphen + (trueSize s $ cgetAdvance (fromEnum n) a + k,w2c a):(0,'/'):(trueSize s $ hw-k+kh,'-'):getLetters True (d:l) hunk ./Graphics/PDF/Typesetting/Box.hs 18 + , Overfull(..) + , Style(..) + , TextStyle(..) + , StyleFunction(..) + , AnyStyle(..) hunk ./Graphics/PDF/Typesetting/Box.hs 27 +import Graphics.PDF.Text +import Graphics.PDF.Shapes + + +-- | Text style used by PDF operators +data TextStyle = TextStyle { textFont :: !PDFFont + , textStrokeColor :: !Color + , textFillColor :: !Color + , textMode :: !TextMode + , penWidth :: !PDFFloat + , scaleSpace :: !PDFFloat -- ^ Scaling factor for normal space size (scale also the dilation and compression factors) + , scaleDilatation :: !PDFFloat -- ^ Scale the dilation factor of glues + , scaleCompression :: !PDFFloat -- ^ Scale the compression factor of glues + } + deriving(Eq) + +-- | What kind of style drawing function is required for a word +-- when word styling is enabled +data StyleFunction = DrawWord -- ^ Must style a word + | DrawGlue -- ^ Must style a glue + deriving(Eq) + +-- | Style of text +class Style a where + -- ^ Modify the look of a sentence (sequence of words using the same style on a line) + sentenceStyle :: a -- ^ The style + -> Maybe (Rectangle -> Draw b -> Draw ()) -- ^ Function receiving the bounding rectangle and the commands drawing the sentence + -- ^ Modify the look of a word + wordStyle :: a -- ^ The style + -> Maybe (Rectangle -> StyleFunction -> Draw b -> Draw ()) -- ^ Word styling function + textStyle :: a -> TextStyle + -- | All styles used in a document must have different style codes + styleCode :: a -> Int + -- | A style may contain data changed from word to word + updateStyle :: a -> a + + -- | A style may change the height of words + styleHeight :: a -> PDFFloat + + -- | A style may change the descent of lines + styleDescent :: a -> PDFFloat + styleHeight = getHeight . textFont . textStyle + styleDescent = getDescent . textFont . textStyle + +data AnyStyle = forall a. (Style a) => AnyStyle a + +instance Style AnyStyle where + sentenceStyle (AnyStyle a) = sentenceStyle a + wordStyle (AnyStyle a) = wordStyle a + textStyle (AnyStyle a) = textStyle a + styleCode (AnyStyle a) = styleCode a + updateStyle (AnyStyle a) = AnyStyle $ updateStyle a + styleHeight (AnyStyle a) = styleHeight a + styleDescent (AnyStyle a) = styleDescent a + + hunk ./Graphics/PDF/Typesetting/Box.hs 104 +data Overfull = Overfull AnyStyle hunk ./Graphics/PDF/Typesetting/Box.hs 114 +instance Box Overfull where + boxWidth _ = 0 + boxHeight (Overfull s) = getHeight (textFont . textStyle $ s) + boxDescent (Overfull s) = getDescent (textFont . textStyle $ s) + +instance DisplayableBox Overfull where + strokeBox a _ x y = do + stroke $ Line (x+2) (y - boxDescent a) (x+2) (y - boxDescent a + boxHeight a) + hunk ./Graphics/PDF/Typesetting/Breaking.hs 17 - , Style(..) - , TextStyle(..) - , StyleFunction(..) - , AnyStyle(..) hunk ./Graphics/PDF/Typesetting/Breaking.hs 26 + , defaultBreakingSettings + , BRState(..) hunk ./Graphics/PDF/Typesetting/Breaking.hs 34 -import Graphics.PDF.Draw -import Graphics.PDF.Shapes -import Graphics.PDF.Colors -import Graphics.PDF.Typesetting.Box(AnyBox(..),NullChar(..),Box(..)) +import Graphics.PDF.Typesetting.Box hunk ./Graphics/PDF/Typesetting/Breaking.hs 37 --- | Text style used by PDF operators -data TextStyle = TextStyle { textFont :: !PDFFont - , textStrokeColor :: !Color - , textFillColor :: !Color - , textMode :: !TextMode - , penWidth :: !PDFFloat - , scaleSpace :: !PDFFloat -- ^ Scaling factor for normal space size (scale also the dilation and compression factors) - , scaleDilatation :: !PDFFloat -- ^ Scale the dilation factor of glues - , scaleCompression :: !PDFFloat -- ^ Scale the compression factor of glues - } - deriving(Eq) - --- | What kind of style drawing function is required for a word --- when word styling is enabled -data StyleFunction = DrawWord -- ^ Must style a word - | DrawGlue -- ^ Must style a glue - deriving(Eq) - --- | Style of text -class Style a where - -- ^ Modify the look of a sentence (sequence of words using the same style on a line) - sentenceStyle :: a -- ^ The style - -> Maybe (Rectangle -> Draw b -> Draw ()) -- ^ Function receiving the bounding rectangle and the commands drawing the sentence - -- ^ Modify the look of a word - wordStyle :: a -- ^ The style - -> Maybe (Rectangle -> StyleFunction -> Draw b -> Draw ()) -- ^ Word styling function - textStyle :: a -> TextStyle - -- | All styles used in a document must have different style codes - styleCode :: a -> Int - -- | A style may contain data changed from word to word - updateStyle :: a -> a - - -- | A style may change the height of words - styleHeight :: a -> PDFFloat - - -- | A style may change the descent of lines - styleDescent :: a -> PDFFloat - styleHeight = getHeight . textFont . textStyle - styleDescent = getDescent . textFont . textStyle - -data AnyStyle = forall a. (Style a) => AnyStyle a - -instance Style AnyStyle where - sentenceStyle (AnyStyle a) = sentenceStyle a - wordStyle (AnyStyle a) = wordStyle a - textStyle (AnyStyle a) = textStyle a - styleCode (AnyStyle a) = styleCode a - updateStyle (AnyStyle a) = AnyStyle $ updateStyle a - styleHeight (AnyStyle a) = styleHeight a - styleDescent (AnyStyle a) = styleDescent a - hunk ./Graphics/PDF/Typesetting/Breaking.hs 168 + +-- | Breaking algorithm settings +data BRState = BRState { firstPassTolerance :: !PDFFloat + , secondPassTolerance :: !PDFFloat + , hyphenPenaltyValue :: !Int + , fitness_demerit :: !PDFFloat + , flagged_demerit :: !PDFFloat + } + +defaultBreakingSettings :: BRState +defaultBreakingSettings = BRState 2.0 1.5 50 100 100 hunk ./Graphics/PDF/Typesetting/Breaking.hs 180 -firstPassTolerance :: PDFFloat -firstPassTolerance = 2.0 hunk ./Graphics/PDF/Typesetting/Breaking.hs 181 -secondPassTolerance :: PDFFloat -secondPassTolerance = 1.5 hunk ./Graphics/PDF/Typesetting/Breaking.hs 182 - -computeDemerit :: Bool +computeDemerit :: BRState + -> Bool hunk ./Graphics/PDF/Typesetting/Breaking.hs 188 -computeDemerit sndPass r a z = +computeDemerit settings sndPass r a z = hunk ./Graphics/PDF/Typesetting/Breaking.hs 192 - tolerance = if sndPass then secondPassTolerance else firstPassTolerance + tolerance = if sndPass then (secondPassTolerance settings) else (firstPassTolerance settings) hunk ./Graphics/PDF/Typesetting/Breaking.hs 194 - if (-1 <= r) && (r <= tolerance) + if ((-1 <= r) && (r <= tolerance)) || sndPass hunk ./Graphics/PDF/Typesetting/Breaking.hs 196 - let fld = if isFlagged z && (flagged a) then flagged_demerit else 0.0 - fid = if fitness' /= (fitnessValue a) then fitness_demerit else 0.0 - dem = if p >= 0 + let fld = if isFlagged z && (flagged a) then (flagged_demerit settings) else 0.0 + fid = if fitness' /= (fitnessValue a) then (fitness_demerit settings) else 0.0 + dem = max 1000.0 $ if p >= 0 hunk ./Graphics/PDF/Typesetting/Breaking.hs 240 -hyphenPenalty :: AnyStyle -- ^ Style of future hyphen +hyphenPenalty :: BRState + -> AnyStyle -- ^ Style of future hyphen hunk ./Graphics/PDF/Typesetting/Breaking.hs 244 -hyphenPenalty s w = FlaggedPenalty w 0 s +hyphenPenalty settings s w = FlaggedPenalty w (hyphenPenaltyValue settings) s hunk ./Graphics/PDF/Typesetting/Breaking.hs 271 -fitness_demerit :: PDFFloat -fitness_demerit = 100 hunk ./Graphics/PDF/Typesetting/Breaking.hs 272 -flagged_demerit :: PDFFloat -flagged_demerit = 100 hunk ./Graphics/PDF/Typesetting/Breaking.hs 308 -getNewActiveBreakpoints :: Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList -> (PossibleBreak,ActiveNodes) -getNewActiveBreakpoints sndPass fmaxw actives z = +getNewActiveBreakpoints :: BRState -> Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList -> (PossibleBreak,ActiveNodes) +getNewActiveBreakpoints settings sndPass fmaxw actives z = hunk ./Graphics/PDF/Typesetting/Breaking.hs 316 - \r newmap -> let dem' = computeDemerit sndPass r b z in + \r newmap -> let dem' = computeDemerit settings sndPass r b z in hunk ./Graphics/PDF/Typesetting/Breaking.hs 326 - nbreaks = Map.filter (\x -> demerit x < dmin + fitness_demerit) breaks' + nbreaks = Map.filter (\x -> demerit x < dmin + (fitness_demerit settings)) breaks' hunk ./Graphics/PDF/Typesetting/Breaking.hs 343 -analyzeBoxes :: Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList -> [(PDFFloat,Int,Bool)] -analyzeBoxes pass fmaxw actives z = +analyzeBoxes :: BRState -> Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList -> [(PDFFloat,Int,Bool)] +analyzeBoxes settings pass fmaxw actives z = hunk ./Graphics/PDF/Typesetting/Breaking.hs 346 - (breaks',actives') = getNewActiveBreakpoints pass fmaxw actives z + (breaks',actives') = getNewActiveBreakpoints settings pass fmaxw actives z hunk ./Graphics/PDF/Typesetting/Breaking.hs 361 - analyzeBoxes True fmaxw actives z + analyzeBoxes settings True fmaxw actives z hunk ./Graphics/PDF/Typesetting/Breaking.hs 373 - someNewBreaks ++ analyzeBoxes pass fmaxw (Map.insert (getKey minBreak) (getNode minBreak) Map.empty) (moveRight z) + someNewBreaks ++ analyzeBoxes settings pass fmaxw (Map.insert (getKey minBreak) (getNode minBreak) Map.empty) (moveRight z) hunk ./Graphics/PDF/Typesetting/Breaking.hs 382 - analyzeBoxes pass fmaxw actives' (moveRight z) + analyzeBoxes settings pass fmaxw actives' (moveRight z) hunk ./Graphics/PDF/Typesetting/Breaking.hs 392 - analyzeBoxes pass fmaxw newActives (moveRight z) + analyzeBoxes settings pass fmaxw newActives (moveRight z) + +-- | Create an hyphen box +hyphenBox :: AnyStyle -> Letter +hyphenBox s = AChar s '-' (charWidth (textFont . textStyle $ s) '-') hunk ./Graphics/PDF/Typesetting/Breaking.hs 399 -cutList :: [Letter] -> Int -> [(PDFFloat,Int,Bool)] -> [(PDFFloat,Maybe AnyStyle,[Letter])] +cutList :: [Letter] -> Int -> [(PDFFloat,Int,Bool)] -> [(PDFFloat,[Letter])] hunk ./Graphics/PDF/Typesetting/Breaking.hs 401 -cutList t _ [] = [(0.0,Nothing,t)] +cutList t _ [] = [(0.0,t)] hunk ./Graphics/PDF/Typesetting/Breaking.hs 403 - let (theLine,t') = splitAt (ba-c) t in + let (theLine,t') = splitAt (ba-c) t + in hunk ./Graphics/PDF/Typesetting/Breaking.hs 411 - [(ra,Nothing,theLine)] + [(ra,theLine)] hunk ./Graphics/PDF/Typesetting/Breaking.hs 418 - (ra,Just s,theLine) : cutList t' ba l + (ra,theLine ++ [hyphenBox s]) : cutList t' ba l hunk ./Graphics/PDF/Typesetting/Breaking.hs 423 - (ra,Nothing,theLine) : cutList t' ba l + (ra,theLine) : cutList t' ba l hunk ./Graphics/PDF/Typesetting/Breaking.hs 428 -formatList :: (Int -> PDFFloat) -> [Letter] -> [(PDFFloat,Maybe AnyStyle,[Letter])] -formatList fmaxw boxes = +formatList :: BRState -> (Int -> PDFFloat) -> [Letter] -> [(PDFFloat,[Letter])] +formatList settings fmaxw boxes = hunk ./Graphics/PDF/Typesetting/Breaking.hs 431 - theBreaks = analyzeBoxes False fmaxw active (createZList boxes) + theBreaks = analyzeBoxes settings False fmaxw active (createZList boxes) hunk ./Graphics/PDF/Typesetting/Breaking.hs 474 -createLetterBoxes :: AnyStyle -- ^ Letter style +createLetterBoxes :: BRState + -> AnyStyle -- ^ Letter style hunk ./Graphics/PDF/Typesetting/Breaking.hs 478 -createLetterBoxes _ [] = [] -createLetterBoxes s ((wa,'.'):b@(_,bc):l') | bc /= ' ' = (createChar s wa '.'): spaceGlue s : createLetterBoxes s l' - | otherwise = (createChar s wa '.') : createLetterBoxes s (b:l') -createLetterBoxes s ((_,'/'):(w,'-'):l) = hyphenPenalty s w : createLetterBoxes s l -createLetterBoxes s ((_,' '):l) = (spaceGlue s) : createLetterBoxes s l -createLetterBoxes s ((w,t):l) = (createChar s w t) : createLetterBoxes s l +createLetterBoxes _ _ [] = [] +createLetterBoxes settings s ((wa,'.'):b@(_,bc):l') | bc /= ' ' = (createChar s wa '.'): spaceGlue s : createLetterBoxes settings s (b:l') + | otherwise = (createChar s wa '.') : spaceGlue s : createLetterBoxes settings s l' +createLetterBoxes settings s ((_,'/'):(w,'-'):l) = hyphenPenalty settings s w : createLetterBoxes settings s l +createLetterBoxes settings s ((_,' '):l) = (spaceGlue s) : createLetterBoxes settings s l +createLetterBoxes settings s ((w,t):l) = (createChar s w t) : createLetterBoxes settings s l hunk ./Graphics/PDF/Typesetting/Breaking.hs 488 -splitText :: AnyStyle -> PDFString -> [Letter] -splitText f t = createLetterBoxes f . ripText (textFont . textStyle $ f) $ t +splitText :: BRState -> AnyStyle -> PDFString -> [Letter] +splitText settings f t = createLetterBoxes settings f . ripText (textFont . textStyle $ f) $ t hunk ./Graphics/PDF/Typesetting/Horizontal.hs 44 - -> Maybe AnyStyle -- ^ Hyphen style hunk ./Graphics/PDF/Typesetting/Horizontal.hs 48 -createWords _ Nothing Nothing [] = [] +createWords _ Nothing [] = [] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 50 -createWords _ Nothing (Just (s,t,w)) [] = [createText s (saveCurrentword t) w] - -createWords _ (Just hs) Nothing [] = [hyphenBox hs] --- Empty list, current word or sentence is added -createWords _ (Just _) (Just (s,t,w)) [] = [createText s (saveCurrentword $ (cons '-' t)) w] +createWords _ (Just (s,t,w)) [] = [createText s (saveCurrentword t) w] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 53 -createWords r hs Nothing ((AChar s t w):l) = createWords r hs (Just (s,singleton t,w)) l +createWords r Nothing ((AChar s t w):l) = createWords r (Just (s,singleton t,w)) l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 55 -createWords r hs (Just (s,t,w)) ((AChar s' t' w'):l) | styleCode s == styleCode s' = createWords r hs (Just (s,cons t' t,w+w')) l - | otherwise = (createText s (saveCurrentword $ t) w):createWords r hs (Just (s',singleton t',w')) l +createWords r (Just (s,t,w)) ((AChar s' t' w'):l) | styleCode s == styleCode s' = createWords r (Just (s,cons t' t,w+w')) l + | otherwise = (createText s (saveCurrentword $ t) w):createWords r (Just (s',singleton t',w')) l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 59 -createWords r hs (Just (s,t,w)) (a@(Glue _ _ _ (Just s')):l)| (isNothing . wordStyle $ s) && (styleCode s == styleCode s') = - createWords r hs (Just (s,cons ' ' t,w + letterWidth a r)) l - | otherwise = (createText s (saveCurrentword $ t) w):(HGlue (letterWidth a r) (Just s')):createWords r hs Nothing l +createWords r (Just (s,t,w)) (a@(Glue _ _ _ (Just s')):l) | (isNothing . wordStyle $ s) && (styleCode s == styleCode s') = + createWords r (Just (s,cons ' ' t,w + letterWidth a r)) l + | otherwise = (createText s (saveCurrentword $ t) w):(HGlue (letterWidth a r) (Just s')):createWords r Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 64 -createWords r hs c (Penalty _:l) = createWords r hs c l -createWords r hs c (FlaggedPenalty _ _ _:l) = createWords r hs c l +createWords r c (Penalty _:l) = createWords r c l +createWords r c (FlaggedPenalty _ _ _:l) = createWords r c l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 68 -createWords r hs Nothing (a@(Glue _ _ _ s):l) = (HGlue (letterWidth a r) s):createWords r hs Nothing l -createWords r hs (Just (s,t,w)) (a@(Glue _ _ _ Nothing):l) = (createText s (saveCurrentword $ t) w):(HGlue (letterWidth a r) Nothing):createWords r hs Nothing l +createWords r Nothing (a@(Glue _ _ _ s):l) = (HGlue (letterWidth a r) s):createWords r Nothing l +createWords r (Just (s,t,w)) (a@(Glue _ _ _ Nothing):l) = (createText s (saveCurrentword $ t) w):(HGlue (letterWidth a r) Nothing):createWords r Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 71 -createWords r hs Nothing ((Letter a):l) = (HBox a):createWords r hs Nothing l -createWords r hs (Just (s,t,w)) ((Letter a):l) = (createText s (saveCurrentword $ t) w):(HBox a):createWords r hs Nothing l +createWords r Nothing ((Letter a):l) = (HBox a):createWords r Nothing l +createWords r (Just (s,t,w)) ((Letter a):l) = (createText s (saveCurrentword $ t) w):(HBox a):createWords r Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 77 - -> Maybe AnyStyle -- ^ Hyphen style hunk ./Graphics/PDF/Typesetting/Horizontal.hs 79 -simplify r s ((Glue _ _ _ _):l) = simplify r s l -simplify r s ((FlaggedPenalty _ _ _):l) = simplify r s l -simplify r s ((Penalty _):l) = simplify r s l -simplify r s l = createWords r s Nothing l +simplify r ((Glue _ _ _ _):l) = simplify r l +simplify r ((FlaggedPenalty _ _ _):l) = simplify r l +simplify r ((Penalty _):l) = simplify r l +simplify r l = createWords r Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 85 -horizontalPostProcess :: [(PDFFloat,Maybe AnyStyle,[Letter])] -- ^ adjust ratio, hyphen style, list of letters or boxes +horizontalPostProcess :: [(PDFFloat,[Letter])] -- ^ adjust ratio, hyphen style, list of letters or boxes hunk ./Graphics/PDF/Typesetting/Horizontal.hs 88 -horizontalPostProcess ((r,s,l'):l) = (HLine r $ simplify r s l'):horizontalPostProcess l +horizontalPostProcess ((r,l'):l) = (HLine r $ simplify r l'):horizontalPostProcess l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 109 --- | Create an hyphen box -hyphenBox :: Style s => s -> HBox -hyphenBox s = createText s (PDFString . singleton $ '-') (charWidth (textFont . textStyle $ s) '-') hunk ./Graphics/PDF/Typesetting/Vertical.hs 54 -createVBoxes :: Int -- ^ Line offset for the text area +createVBoxes :: BRState + -> Int -- ^ Line offset for the text area hunk ./Graphics/PDF/Typesetting/Vertical.hs 59 -createVBoxes _ _ [] = [] -createVBoxes o t (a@(VBox _):l') = a:createVBoxes (o+1) t l' -createVBoxes o t@(TextArea _ _ fmaxw) ((Paragraph l):l') = - let fl = formatList (onlyPositive . shiftBy o $ fmaxw) l +createVBoxes _ _ _ [] = [] +createVBoxes settings o t (a@(VBox _):l') = a:createVBoxes settings (o+1) t l' +createVBoxes settings o t@(TextArea _ _ fmaxw) ((Paragraph l):l') = + let fl = formatList settings (onlyPositive . shiftBy o $ fmaxw) l hunk ./Graphics/PDF/Typesetting/Vertical.hs 64 - (toVBoxes . horizontalPostProcess $ fl) ++ createVBoxes (o + length fl) t l' + (toVBoxes . horizontalPostProcess $ fl) ++ createVBoxes settings (o + length fl) t l' hunk ./Graphics/PDF/Typesetting.hs 17 + , DisplayableBox(..) hunk ./Graphics/PDF/Typesetting.hs 33 + , setFirstPassTolerance + , setSecondPassTolerance + , setHyphenPenaltyValue + , setFitnessDemerit + , setHyphenDemerit hunk ./Graphics/PDF/Typesetting.hs 65 - let (a, _, boxes) = (runRWS . unTM $ t >>= \x' -> do {return x'} ) () (TMState (AnyStyle defaultStyle)) - -- Cut the text into lines and get a list of lines - -- l = formatList (onlyPositive fmaxw) boxes - -- Apply the gorizontal postprocessing and package everything as a list of VBox. Each line being a list of HBox - --strokeVBoxes (createVBoxes . horizontalPostProcess $ l) 1.0 fx y - strokeVBoxes (createVBoxes 0 area boxes) 1.0 fx y + let (a, s', boxes) = (runRWS . unTM $ t >>= \x' -> do {return x'} ) () (TMState (AnyStyle defaultStyle) defaultBreakingSettings) + strokeVBoxes (createVBoxes (breakSettings s') 0 area boxes) 1.0 fx y hunk ./Graphics/PDF/Typesetting.hs 80 + , breakSettings :: !BRState hunk ./Graphics/PDF/Typesetting.hs 93 -newtype Para a = Para { unPara :: RWS () [Letter] AnyStyle a} +newtype Para a = Para { unPara :: RWS BRState [Letter] AnyStyle a} hunk ./Graphics/PDF/Typesetting.hs 95 - deriving(Monad,MonadWriter [Letter], MonadState AnyStyle, Functor) + deriving(Monad,MonadWriter [Letter], MonadReader BRState, MonadState AnyStyle, Functor) hunk ./Graphics/PDF/Typesetting.hs 101 +instance MonadReader BRState Para hunk ./Graphics/PDF/Typesetting.hs 134 - f <- currentStyle - let (a, s', boxes) = (runRWS . unPara $ (m >>= endParagraph) ) () f - put $! TMState s' + TMState f settings <- get + let (a, s', boxes) = (runRWS . unPara $ (m >>= endParagraph) ) settings f + put $! TMState s' settings hunk ./Graphics/PDF/Typesetting.hs 153 - tell $ splitText f (toPDFString t) + settings <- ask + tell $ splitText settings f (toPDFString t) + +setFirstPassTolerance :: PDFFloat -> TM () +setFirstPassTolerance x = modifyStrict $ \s -> s {breakSettings = (breakSettings s){firstPassTolerance = x}} + +setSecondPassTolerance :: PDFFloat -> TM () +setSecondPassTolerance x = modifyStrict $ \s -> s {breakSettings = (breakSettings s){secondPassTolerance = x}} + +setHyphenPenaltyValue :: Int -> TM () +setHyphenPenaltyValue x = modifyStrict $ \s -> s {breakSettings = (breakSettings s){hyphenPenaltyValue = x}} + +setFitnessDemerit :: PDFFloat -> TM () +setFitnessDemerit x = modifyStrict $ \s -> s {breakSettings = (breakSettings s){fitness_demerit = x}} hunk ./Graphics/PDF/Typesetting.hs 168 +setHyphenDemerit :: PDFFloat -> TM () +setHyphenDemerit x = modifyStrict $ \s -> s {breakSettings = (breakSettings s){flagged_demerit = x}} + hunk ./Test/test.hs 211 - r = 50.0 * ws + r = 60.0 * ws hunk ./Test/test.hs 249 + normalPar = do + txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + txt $ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor " + txt $ "in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, " + txt $ "sunt in culpa qui officia deserunt mollit anim id est laborum." hunk ./Test/test.hs 268 - 3 -> displayFormattedText (circleArea 300 300) Normal (setStyle Normal >> paragraph (mapM_ (const par) [1..3]) ) + 3 -> displayFormattedText (circleArea 300 350) Normal $ do + setStyle Normal + setFirstPassTolerance 10.0 + setSecondPassTolerance 10.0 + setFitnessDemerit 50.0 + paragraph $ do + mapM_ (const normalPar) [1..4] + txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + txt $ "Ut enim ad minim" hunk ./Graphics/PDF/Typesetting/Box.hs 98 - -> PDFFloat -- ^ Adjustement ratio (used to dilate space when displaying a text with PDF raw commands) hunk ./Graphics/PDF/Typesetting/Box.hs 111 - strokeBox _ _ _ _ = return () + strokeBox _ _ _ = return () hunk ./Graphics/PDF/Typesetting/Box.hs 119 - strokeBox a _ x y = do + strokeBox a x y = do hunk ./Graphics/PDF/Typesetting/Breaking.hs 25 - , letterWidth + , MaybeGlue(..) hunk ./Graphics/PDF/Typesetting/Breaking.hs 28 + , glueWidth hunk ./Graphics/PDF/Typesetting/Breaking.hs 52 +class MaybeGlue a where + boxWidthWithRatio :: a -> PDFFloat -> PDFFloat + +instance MaybeGlue Letter where + boxWidthWithRatio = letterWidth + +-- | Compute glue width with dilation +glueWidth :: PDFFloat -> PDFFloat -> PDFFloat -> PDFFloat -> PDFFloat +glueWidth w y z r = + if r >= 0 + then + r*y + w + else + r*z + w + hunk ./Graphics/PDF/Typesetting/Breaking.hs 72 -letterWidth (Glue w yi zi _) r = - if r >= 0 - then - r*yi + w - else - r*zi + w +letterWidth (Glue w yi zi _) r = glueWidth w yi zi r hunk ./Graphics/PDF/Typesetting/Breaking.hs 243 -createBreaknode prev (ZList _ (w,y,z,_,a) []) = BreakNode (w + letterWidth a 0.0) (y) (z) 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,a) []) = BreakNode (w + boxWidthWithRatio a 0.0) (y) (z) 0.0 False 0 0.0 prev hunk ./Graphics/PDF/Typesetting/Breaking.hs 265 - let w' = letterWidth a 0.0 + let w' = boxWidthWithRatio a 0.0 hunk ./Graphics/PDF/Typesetting/Breaking.hs 471 +-- | Add a glue to the stream +punctuationGlue :: AnyStyle -- ^ The style + -> Letter +punctuationGlue s = + let ws = (textWidth (textFont . textStyle $ s) (toPDFString " ") ) + h = scaleSpace . textStyle $ s + sy = scaleDilatation . textStyle $ s + sz = scaleCompression . textStyle $ s + in + Glue (ws*h) (h*sy*ws) (h*sz*ws/3.0) (Just s) + hunk ./Graphics/PDF/Typesetting/Breaking.hs 501 -createLetterBoxes settings s ((wa,'.'):b@(_,bc):l') | bc /= ' ' = (createChar s wa '.'): spaceGlue s : createLetterBoxes settings s (b:l') - | otherwise = (createChar s wa '.') : spaceGlue s : createLetterBoxes settings s l' +createLetterBoxes settings s ((wa,'.'):b@(_,bc):l') | bc /= ' ' = (createChar s wa '.'): punctuationGlue s : createLetterBoxes settings s (b:l') + | otherwise = (createChar s wa '.') : punctuationGlue s : createLetterBoxes settings s l' hunk ./Graphics/PDF/Typesetting/Horizontal.hs 15 - , HLine(..) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 20 -import Data.ByteString.Lazy.Char8(singleton,cons) +import Data.ByteString.Lazy.Char8(singleton,cons,pack) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 23 -import qualified Data.ByteString.Lazy as B(ByteString,reverse) -import Data.Maybe(isJust,fromJust,isNothing) +import qualified Data.ByteString.Lazy as B(ByteString,reverse,concat) +import Data.Maybe(isJust,fromJust) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 31 +import Control.Monad.Writer(tell) +import Control.Monad(when) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 59 --- Glue. Same style and no word mode, then we add to the sentence. Otherwise we close current word or sentence -createWords r (Just (s,t,w)) (a@(Glue _ _ _ (Just s')):l) | (isNothing . wordStyle $ s) && (styleCode s == styleCode s') = - createWords r (Just (s,cons ' ' t,w + letterWidth a r)) l - | otherwise = (createText s (saveCurrentword $ t) w):(HGlue (letterWidth a r) (Just s')):createWords r Nothing l +-- Glue close the word and start a new one because we want glues of different widths in the PDF +createWords r (Just (s,t,w)) ((Glue w' y z (Just s')):l) = (createText s (saveCurrentword $ t) w):(HGlue w' (Just(y,z)) (Just s')):createWords r Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 67 -createWords r Nothing (a@(Glue _ _ _ s):l) = (HGlue (letterWidth a r) s):createWords r Nothing l -createWords r (Just (s,t,w)) (a@(Glue _ _ _ Nothing):l) = (createText s (saveCurrentword $ t) w):(HGlue (letterWidth a r) Nothing):createWords r Nothing l +createWords r Nothing ((Glue w' y z s):l) = (HGlue w' (Just(y,z)) s):createWords r Nothing l +createWords r (Just (s,t,w)) ((Glue w' y z Nothing):l) = (createText s (saveCurrentword $ t) w):(HGlue w' (Just(y,z)) Nothing):createWords r Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 70 -createWords r Nothing ((Letter a):l) = (HBox a):createWords r Nothing l -createWords r (Just (s,t,w)) ((Letter a):l) = (createText s (saveCurrentword $ t) w):(HBox a):createWords r Nothing l +createWords r Nothing ((Letter a):l) = (SomeBox a):createWords r Nothing l +createWords r (Just (s,t,w)) ((Letter a):l) = (createText s (saveCurrentword $ t) w):(SomeBox a):createWords r Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 85 - -> [HLine] -- ^ List of lines + -> [HBox] -- ^ List of lines hunk ./Graphics/PDF/Typesetting/Horizontal.hs 87 -horizontalPostProcess ((r,l'):l) = (HLine r $ simplify r l'):horizontalPostProcess l +horizontalPostProcess ((r,l'):l) = (mkHboxWithRatio r $ simplify r l'):horizontalPostProcess l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 94 -data HBox = HBox !AnyBox - | HGlue !PDFFloat !(Maybe AnyStyle) +data HBox = HBox !PDFFloat !PDFFloat !PDFFloat ![HBox] + | HGlue !PDFFloat !(Maybe (PDFFloat,PDFFloat)) !(Maybe AnyStyle) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 97 + | SomeBox !AnyBox hunk ./Graphics/PDF/Typesetting/Horizontal.hs 100 -data HLine = HLine !PDFFloat ![HBox] deriving(Show) +--data HLine = HLine !PDFFloat ![HBox] deriving(Show) + +mkHboxWithRatio :: PDFFloat -- ^ Adjustement ratio + -> [HBox] + -> HBox +mkHboxWithRatio _ [] = SomeBox (AnyBox NullChar) +mkHboxWithRatio r l = + let w = foldl' (\x y -> x + boxWidthWithRatio y r) 0.0 l + h = maximum . map boxHeight $ l + d = maximum . map boxDescent $ l + addBox (HGlue gw (Just(y,z)) s) (HBox w' h' d' l') = HBox w' h' d' (HGlue (glueWidth gw y z r) Nothing s:l') + addBox a (HBox w' h' d' l') = HBox w' h' d' (a:l') + addBox _ _ = error "We can add boxes only to an horizontal list" + in + -- Add boxes and dilate glues when needing fixing their dimensions after dilatation + foldr addBox (HBox w h d []) l + +instance MaybeGlue HBox where + boxWidthWithRatio (HGlue w (Just(y,z)) _) r = glueWidth w y z r + boxWidthWithRatio a _ = boxWidth a + hunk ./Graphics/PDF/Typesetting/Horizontal.hs 131 - show (HBox a) = "(HBox " ++ show a ++ ")" - show (HGlue a _) = "(HGlue " ++ show a ++ ")" + show (HBox _ _ _ a) = "(HBox " ++ show a ++ ")" + show (HGlue a _ _) = "(HGlue " ++ show a ++ ")" hunk ./Graphics/PDF/Typesetting/Horizontal.hs 134 + show (SomeBox t) = "(SomeBox " ++ show t ++ ")" hunk ./Graphics/PDF/Typesetting/Horizontal.hs 136 - -getBoxWidthOfList :: [HBox] -- ^ List of hboxes - -> PDFFloat -- ^ width -getBoxWidthOfList l = foldl' (\y x -> y + boxWidth x) 0.0 l - -instance Box HLine where - boxWidth (HLine _ l) = getBoxWidthOfList l +-- | Draw a line of words and glue using the word style +drawTextLine :: AnyStyle -> [HBox] -> PDFFloat -> PDFFloat -> Draw () +drawTextLine _ [] _ _ = return () +drawTextLine style l@(a:l') x y | (isJust . wordStyle $ style) = do + strokeBox a x y + drawTextLine style l' (x + boxWidth a) y + | otherwise = drawText $ drawWords True style l x y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 144 - boxHeight (HLine _ []) = 0 - boxHeight (HLine _ l) = maximum . map boxHeight $ l +-- | Draw a line of words glue without word style +drawWords :: Bool -> AnyStyle -> [HBox] -> PDFFloat -> PDFFloat -> PDFText() +drawWords False s [] x y = drawTheTextBox StopText s x y (toPDFString "") +drawWords True _ [] _ _ = return () + +drawWords True s ((Text _ t w):l) x y = do + drawTheTextBox StartText s x y t + drawWords False s l (x + w) y + +drawWords False s ((Text _ t w):l) x y = do + drawTheTextBox ContinueText s x y t + drawWords False s l (x + w) y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 157 - boxDescent (HLine _ []) = 0 - boxDescent (HLine _ l) = maximum . map boxDescent $ l +drawWords False s ((HGlue w _ _):l) x y = do + drawTextGlue s w + drawWords False s l (x + w) y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 161 --- Stroke a list of box without any special processing -strokeList :: [HBox] -- ^ List of boxes - -> PDFFloat -- ^ Adjust ratio - -> PDFFloat -- ^ x - -> PDFFloat -- ^ y - -> Draw () -strokeList [] _ _ _ = return () - -strokeList (a:l) r x y = do - strokeBox a r x y - strokeList l r (x + boxWidth a) y - --- HBox processing must be special since we need to take into account the sentence style -instance DisplayableBox HLine where - strokeBox (HLine _ []) _ _ _ = return () +drawWords True _ _ _ _ = return () +drawWords False _ _ _ _ = return () + hunk ./Graphics/PDF/Typesetting/Horizontal.hs 165 - -- A normal box is drawn and we move to the next one - strokeBox (HLine r (l@(a@(Text style _ _):nl))) _ x y = do - if (isJust . sentenceStyle $ style) +drawLineOfHboxes :: [HBox] -> PDFFloat -> PDFFloat -> Draw () +drawLineOfHboxes [] _ _ = return () +-- | Start a new text +drawLineOfHboxes l@((Text style _ _):_) x y = do + let de = styleDescent style + he = styleHeight style + (l',l'') = span (isSameStyle style) l + w' = foldl' (\x' y' -> x' + boxWidth y') 0.0 l' + if (isJust . sentenceStyle $ style) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 175 - let de = styleDescent style - he = styleHeight style - (l',l'') = span (isSameStyle style) l - w = getBoxWidthOfList l' - (fromJust . sentenceStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) (strokeList l' r x y) - strokeBox (HLine r l'') r (x + w) y - else do - strokeBox a r x y - strokeBox (HLine r nl) r (x + boxWidth a) y - - strokeBox (HLine r (a:l)) _ x y = do - strokeBox a r x y - strokeBox (HLine r l) r (x + boxWidth a) y - - - + (fromJust . sentenceStyle $ style) (Rectangle x (y - de) (x+w') (y - de + he)) (drawTextLine style l' x y) + else do + drawTextLine style l' x y + drawLineOfHboxes l'' (x + w') y + +drawLineOfHboxes (a:l) x y = do + strokeBox a x y + drawLineOfHboxes l (x + boxWidth a) y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 186 - boxWidth (HBox a) = boxWidth a - boxWidth (HGlue w _) = w + boxWidth (HBox w _ _ _) = w + boxWidth (SomeBox a) = boxWidth a + boxWidth (HGlue w _ _) = w hunk ./Graphics/PDF/Typesetting/Horizontal.hs 191 - boxHeight (HBox a) = boxHeight a - boxHeight (HGlue _ _) = 0 + boxHeight (HBox _ h _ _) = h + boxHeight (SomeBox a) = boxHeight a + boxHeight (HGlue _ _ _) = 0 hunk ./Graphics/PDF/Typesetting/Horizontal.hs 196 - boxDescent (HBox a) = boxDescent a - boxDescent (HGlue _ _) = 0 + boxDescent (HBox _ _ d _) = d + boxDescent (SomeBox a) = boxDescent a + boxDescent (HGlue _ _ _) = 0 hunk ./Graphics/PDF/Typesetting/Horizontal.hs 202 -drawTheTextBox :: Style style => style - -> PDFFloat +drawTheTextBox :: Style style => TextDrawingState + -> style hunk ./Graphics/PDF/Typesetting/Horizontal.hs 207 - -> Draw () -drawTheTextBox style r x y t = drawText $ do - setFont (textFont . textStyle $ style) - strokeColor (textStrokeColor . textStyle $ style) - fillColor (textFillColor . textStyle $ style) - renderMode (textMode . textStyle $ style) - --setWidth (penWidth . textStyle $ s) + -> PDFText () +drawTheTextBox state style x y t = do + when (state == StartText || state == OneBlock) $ (do + setFont (textFont . textStyle $ style) + strokeColor (textStrokeColor . textStyle $ style) + fillColor (textFillColor . textStyle $ style) + renderMode (textMode . textStyle $ style) + textStart x y + tell $ B.concat [newline,lbracket]) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 217 - let ws = (textWidth (textFont . textStyle $ style) (toPDFString " ")) - h = scaleSpace . textStyle $ style - sy = scaleDilatation . textStyle $ style - sz = scaleCompression . textStyle $ style - dws = ws * h -- dilated space - gy = sy*dws / 2.0 - gz = sz*dws / 3.0 - delta = if r >= 0 then r*gy else r*gz - -- ws is the true font space. We use dws so we have a user overhead - -- and the overhead of the space dilatation - wordSpace (dws - ws + delta) - -- And we render the text - textStart x y - displayText t + when (state == StartText || state == OneBlock || state == ContinueText) $ (do + tell $ toPDF t) + when (state == StopText || state == OneBlock) $ (do + tell rbracket + tell $ pack " TJ") + +-- | Draw the additional displacement required for a space in a text due to the dilaton of the glue +drawTextGlue :: Style style => style + -> PDFFloat + -> PDFText () +drawTextGlue style w = do + let ws = (textWidth (textFont . textStyle $ style) (toPDFString " ")) + PDFFont _ size = textFont . textStyle $ style + delta = w - ws + return () + tell . B.concat $ [ lparen, bspace,rparen,bspace,toPDF ((-delta) * 1000.0 / (fromIntegral size) ), bspace] + + +data TextDrawingState = StartText -- ^ Send PDF commands needed to start a text + | ContinueText -- ^ Continue adding text + | StopText -- ^ Stop the text + | OneBlock -- ^ One block of text + deriving(Eq) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 242 - strokeBox (HGlue w (Just style)) _ x y = do + strokeBox (HBox _ _ _ l) x y = drawLineOfHboxes l x y + + strokeBox (HGlue w _ (Just style)) x y = do hunk ./Graphics/PDF/Typesetting/Horizontal.hs 255 - strokeBox (Text style t w) r x y = do + strokeBox (Text style t w) x y = do hunk ./Graphics/PDF/Typesetting/Horizontal.hs 262 - (fromJust . wordStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) DrawWord (drawTheTextBox style r x y t) + (fromJust . wordStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) DrawWord (drawText $ drawTheTextBox OneBlock style x y t) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 264 - if (isJust . sentenceStyle $ style) - then - (fromJust . sentenceStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) (drawTheTextBox style r x y t) - else - drawTheTextBox style r x y t + --if (isJust . sentenceStyle $ style) + -- then + -- (fromJust . sentenceStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) (drawText $ drawTheTextBox OneBlock style x y t) + -- else + drawText $ drawTheTextBox OneBlock style x y t hunk ./Graphics/PDF/Typesetting/Horizontal.hs 270 - strokeBox (HBox a) r x y = strokeBox a r x y - strokeBox (HGlue _ _) _ _ _ = return () + strokeBox (SomeBox a) x y = strokeBox a x y + strokeBox (HGlue _ _ _) _ _ = return () hunk ./Graphics/PDF/Typesetting/Horizontal.hs 278 -isSameStyle s (HGlue _ (Just style)) = styleCode s == styleCode style +isSameStyle s (HGlue _ _ (Just style)) = styleCode s == styleCode style hunk ./Graphics/PDF/Typesetting/Vertical.hs 22 -import Graphics.PDF.Typesetting.Horizontal(horizontalPostProcess,HLine) +import Graphics.PDF.Typesetting.Horizontal(horizontalPostProcess,HBox) hunk ./Graphics/PDF/Typesetting/Vertical.hs 47 -toVBoxes :: [HLine] -- ^ List of lines +toVBoxes :: [HBox] -- ^ List of lines hunk ./Graphics/PDF/Typesetting/Vertical.hs 80 - strokeBox theLine 1.0 (fx nb) y' -- Adjustement ratio is forced by the HBox so we can pass 1.0 + strokeBox theLine (fx nb) y' -- Adjustement ratio is forced by the HBox so we can pass 1.0 hunk ./Test/test.hs 270 - setFirstPassTolerance 10.0 - setSecondPassTolerance 10.0 - setFitnessDemerit 50.0 + setFirstPassTolerance 5.0 + setSecondPassTolerance 5.0 + --setFitnessDemerit 50.0 hunk ./Test/test.hs 341 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = True}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = False}) rect $ do hunk ./Graphics/PDF/Typesetting/Breaking.hs 186 + , line_penalty :: !PDFFloat hunk ./Graphics/PDF/Typesetting/Breaking.hs 190 -defaultBreakingSettings = BRState 2.0 1.5 50 100 100 +defaultBreakingSettings = BRState 100 200 50 10000 10000 10 hunk ./Graphics/PDF/Typesetting/Breaking.hs 206 - if ((-1 <= r) && (r <= tolerance)) || sndPass + if (b <= tolerance) || sndPass hunk ./Graphics/PDF/Typesetting/Breaking.hs 212 - fid + fld + (1.0 + b + (fromIntegral p)) ** 2.0 + fid + fld + ((line_penalty settings) + b) ** 2.0 + (fromIntegral p) ** 2.0 hunk ./Graphics/PDF/Typesetting/Breaking.hs 215 - fid + fld + (1.0 + b) ** 2.0 - (fromIntegral p)**2.0 + fid + fld + ((line_penalty settings) + b) ** 2.0 - (fromIntegral p)**2.0 hunk ./Graphics/PDF/Typesetting/Breaking.hs 217 - fid + fld + (1.0 + b) ** 2.0 + fid + fld + ((line_penalty settings) + b) ** 2.0 hunk ./Graphics/PDF/Typesetting.hs 38 + , setLinePenalty hunk ./Graphics/PDF/Typesetting.hs 171 - + +setLinePenalty :: PDFFloat -> TM () +setLinePenalty x = modifyStrict $ \s -> s {breakSettings = (breakSettings s){line_penalty = x}} + hunk ./Test/test.hs 270 - setFirstPassTolerance 5.0 - setSecondPassTolerance 5.0 - --setFitnessDemerit 50.0 + setFirstPassTolerance 5000 + setSecondPassTolerance 5000 hunk ./Test/test.hs 340 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = False}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = True}) rect $ do hunk ./Graphics/PDF/Draw.hs 344 -newtype PDF a = PDF {unPDF :: StateT PdfState IO a} +newtype PDF a = PDF {unPDF :: State PdfState a} hunk ./Graphics/PDF/Draw.hs 346 - deriving (Functor, Monad, MonadState PdfState, MonadIO) + deriving (Functor, Monad, MonadState PdfState) hunk ./Graphics/PDF/Draw.hs 351 -instance MonadIO PDF hunk ./Graphics/PDF/Image.hs 17 + , JpegFile hunk ./Graphics/PDF/Image.hs 20 + , readJpegFile hunk ./Graphics/PDF/Image.hs 148 -newtype FA a = FA {unFA :: ErrorT String PDF a} +newtype FA a = FA {unFA :: ErrorT String IO a} hunk ./Graphics/PDF/Image.hs 158 -runFA :: FA a -> PDF (Either String a) +runFA :: FA a -> IO (Either String a) hunk ./Graphics/PDF/Image.hs 244 -createPDFJpeg :: FilePath - -> PDF (Either String (PDFReference PDFJpeg)) -createPDFJpeg f = do +readJpegFile :: FilePath + -> IO (Either String JpegFile) +readJpegFile f = do hunk ./Graphics/PDF/Image.hs 251 - Right settings@(_,height,width,_) -> do + Right (bits_per_component,height,width,color_space) -> do hunk ./Graphics/PDF/Image.hs 253 - PDFReference s <- createContent (a' img settings) Nothing - recordBound s width height - return (Right $ PDFReference s) + return (Right $ JpegFile bits_per_component width height color_space img) hunk ./Graphics/PDF/Image.hs 255 - where - color c = case c of - 1 -> [(PDFName "ColorSpace",AnyPdfObject $ PDFName "DeviceGray")] - 3 -> [(PDFName "ColorSpace",AnyPdfObject $ PDFName "DeviceRGB")] - 4 -> [(PDFName "ColorSpace",AnyPdfObject $ PDFName "DeviceCMYK") - ,(PDFName "Decode",AnyPdfObject . map (AnyPdfObject . PDFInteger) $ [1,0,1,0,1,0,1,0]) - ] - _ -> error "Jpeg color space not supported" - a' img (bits_per_component,height,width,color_space) = - do modifyStrict $ \s -> s {otherRsrcs = PDFDictionary. M.fromList $ - [ (PDFName "Type",AnyPdfObject . PDFName $ "XObject") - , (PDFName "Subtype",AnyPdfObject . PDFName $ "Image") - , (PDFName "Width",AnyPdfObject . PDFInteger $ round width) - , (PDFName "Height",AnyPdfObject . PDFInteger $ round height) - , (PDFName "BitsPerComponent",AnyPdfObject . PDFInteger $ bits_per_component) - , (PDFName "Interpolate", AnyPdfObject True) - , (PDFName "Filter",AnyPdfObject . PDFName $ "DCTDecode") - ] ++ color color_space - } - tell img - + + +createPDFJpeg :: JpegFile + -> PDF (PDFReference PDFJpeg) +createPDFJpeg (JpegFile bits_per_component width height color_space img) = do + PDFReference s <- createContent a' Nothing + recordBound s width height + return (PDFReference s) + where + color c = case c of + 1 -> [(PDFName "ColorSpace",AnyPdfObject $ PDFName "DeviceGray")] + 3 -> [(PDFName "ColorSpace",AnyPdfObject $ PDFName "DeviceRGB")] + 4 -> [(PDFName "ColorSpace",AnyPdfObject $ PDFName "DeviceCMYK") + ,(PDFName "Decode",AnyPdfObject . map (AnyPdfObject . PDFInteger) $ [1,0,1,0,1,0,1,0]) + ] + _ -> error "Jpeg color space not supported" + a' = + do modifyStrict $ \s -> s {otherRsrcs = PDFDictionary. M.fromList $ + [ (PDFName "Type",AnyPdfObject . PDFName $ "XObject") + , (PDFName "Subtype",AnyPdfObject . PDFName $ "Image") + , (PDFName "Width",AnyPdfObject . PDFInteger $ round width) + , (PDFName "Height",AnyPdfObject . PDFInteger $ round height) + , (PDFName "BitsPerComponent",AnyPdfObject . PDFInteger $ bits_per_component) + , (PDFName "Interpolate", AnyPdfObject True) + , (PDFName "Filter",AnyPdfObject . PDFName $ "DCTDecode") + ] ++ color color_space + } + tell img + +-- | A Jpeg file +data JpegFile = JpegFile !Int !PDFFloat !PDFFloat !Int !B.ByteString hunk ./Graphics/PDF/Image.hs 287 +-- | A Jpeg PDF object hunk ./Graphics/PDF.hs 76 +import Data.List(foldl') hunk ./Graphics/PDF.hs 156 - --- | Write PDF objects in the TOC -writeObjectsAndCreateToc :: Handle -- ^ File handle - -> [B.ByteString] -- ^ List of objects each object being already converted to a bytestring - -> IO (Int,Int64,[B.ByteString]) -writeObjectsAndCreateToc h l = foldM writeObject (0,0::Int64,[]) l where - writeObject (nb,len,toc) obj = do - -- Write the object to the file - B.hPut h obj - -- Remember the position - return (nb+1,len + B.length obj,(toByteString (printf "%010d 00000 n \n" ((fromIntegral len)::Integer))) : toc) hunk ./Graphics/PDF.hs 180 - + + +-- | Write PDF objects in the TOC +writeObjectsAndCreateToc :: [B.ByteString] -- ^ List of objects each object being already converted to a bytestring + -> (Int,Int64,[B.ByteString]) +writeObjectsAndCreateToc l = foldr writeObject (0,0::Int64,[]) l where + writeObject obj (nb,len,toc) = (nb+1,len + B.length obj,(toByteString (printf "%010d 00000 n \n" ((fromIntegral len)::Integer))) : toc) + +defaultPdfSettings :: PdfState +defaultPdfSettings = + PdfState { + supplySrc = 1 + , objects = IM.empty + , pages = noPages + , streams = IM.empty + , catalog = PDFReference 0 + , defaultRect = PDFRect 0 0 600 400 + , docInfo = standardDocInfo { author=toPDFString "Unknown", compressed = True} + , outline = Nothing + , currentPage = Nothing + , xobjectBound = IM.empty + , firstOutline = [True] + } + +createObjectByteStrings :: PdfState -> PDF a -> (PDFReference PDFCatalog,Int,Int64,B.ByteString,B.ByteString) +createObjectByteStrings pdfState m = + let header = toByteString "%PDF-1.5\n" + objectEncoding (x,a) = toPDF . PDFReferencedObject (fromIntegral x) $ a + (root,s) = flip runState pdfState . unPDF $ createPDF >> m >> saveObjects + objs = objects s + objectContents = header : (map objectEncoding . IM.toAscList $ objs) + (nb,len,toc) = writeObjectsAndCreateToc objectContents + in + (root,nb,len,B.concat objectContents,B.concat . tail . reverse $ toc) + hunk ./Graphics/PDF.hs 222 - (root,s) <- flip runStateT vars . unPDF $ createPDF >> m >> saveObjects - let header = toByteString "%PDF-1.5\n" - objs = objects s + let (root,nb,len,content,toc) = createObjectByteStrings (defaultPdfSettings {defaultRect = rect, docInfo = infos} ) m hunk ./Graphics/PDF.hs 224 - (nb,len,toc) <- writeObjectsAndCreateToc h $ header : (map (toPDF . pointer) . IM.toAscList $ objs) + B.hPut h content hunk ./Graphics/PDF.hs 228 - B.hPut h . B.concat . tail . reverse $ toc + B.hPut h toc hunk ./Graphics/PDF.hs 234 - where - pointer (x,a) = PDFReferencedObject (fromIntegral x) a - vars = PdfState { - supplySrc = 1 - , objects = IM.empty - , pages = noPages - , streams = IM.empty - , catalog = PDFReference 0 - , defaultRect = rect - , docInfo = infos - , outline = Nothing - , currentPage = Nothing - , xobjectBound = IM.empty - , firstOutline = [True] - } + hunk ./Test/test.hs 95 -testImage :: PDFReference PDFPage -> PDF () -testImage page = do - Right jpg <- createPDFJpeg "logo.jpg" +testImage :: JpegFile -> PDFReference PDFPage -> PDF () +testImage jpgf page = do + jpg <- createPDFJpeg jpgf hunk ./Test/test.hs 279 -testAll :: PDF () -testAll = do +testAll :: JpegFile -> PDF () +testAll jpg = do hunk ./Test/test.hs 293 - -- - --page <- addPage Nothing - --newSection (toPDFString "Shapes") Nothing Nothing $ do - -- - -- newSection (toPDFString "Geometry") Nothing Nothing $ do - -- drawWithPage page $ do - -- geometryTest - -- - -- page <- addPage Nothing - -- newSection (toPDFString "Line style") Nothing Nothing $ do - -- drawWithPage page $ do - -- lineStyle - -- page <- addPage Nothing - -- newSection (toPDFString "Object reuse") Nothing Nothing $ do - -- r <- createPDFXForm 0 0 200 200 lineStyle - -- drawWithPage page $ do - -- drawXObject r - -- - --page <- addPage Nothing - --newSectionWithPage (toPDFString "Painting") Nothing Nothing page $ do - -- newSection (toPDFString "Patterns") Nothing Nothing $ do - -- patternTest page - -- page <- addPage Nothing - -- newSection (toPDFString "Shading") Nothing Nothing $ do - -- drawWithPage page $ do - -- shadingTest - --page <- addPage Nothing - --newSection (toPDFString "Media") Nothing Nothing $ do - -- newSection (toPDFString "image") Nothing Nothing $ do - -- testImage page - -- - --page <- addPage Nothing - --newSection (toPDFString "Annotations") Nothing Nothing $ do - -- drawWithPage page $ do - -- testAnnotation - --page <- addPage Nothing - --newSection (toPDFString "Text") Nothing Nothing $ do - -- drawWithPage page $ do - -- textTest - --newSection (toPDFString "Fun") Nothing Nothing $ do - -- penrose + + page <- addPage Nothing + newSection (toPDFString "Shapes") Nothing Nothing $ do + + newSection (toPDFString "Geometry") Nothing Nothing $ do + drawWithPage page $ do + geometryTest + + page <- addPage Nothing + newSection (toPDFString "Line style") Nothing Nothing $ do + drawWithPage page $ do + lineStyle + page <- addPage Nothing + newSection (toPDFString "Object reuse") Nothing Nothing $ do + r <- createPDFXForm 0 0 200 200 lineStyle + drawWithPage page $ do + drawXObject r + + page <- addPage Nothing + newSectionWithPage (toPDFString "Painting") Nothing Nothing page $ do + newSection (toPDFString "Patterns") Nothing Nothing $ do + patternTest page + page <- addPage Nothing + newSection (toPDFString "Shading") Nothing Nothing $ do + drawWithPage page $ do + shadingTest + page <- addPage Nothing + newSection (toPDFString "Media") Nothing Nothing $ do + newSection (toPDFString "image") Nothing Nothing $ do + testImage jpg page + + page <- addPage Nothing + newSection (toPDFString "Annotations") Nothing Nothing $ do + drawWithPage page $ do + testAnnotation + page <- addPage Nothing + newSection (toPDFString "Text") Nothing Nothing $ do + drawWithPage page $ do + textTest + newSection (toPDFString "Fun") Nothing Nothing $ do + penrose hunk ./Test/test.hs 340 + Right jpg <- readJpegFile "logo.jpg" hunk ./Test/test.hs 342 - testAll + testAll jpg hunk ./Graphics/PDF.hs 61 -import Control.Exception(bracket) hunk ./Graphics/PDF.hs 75 -import Data.List(foldl') +import Data.Binary.Builder(Builder,fromLazyByteString, toLazyByteString) +import Graphics.PDF.LowLevel.Serializer +import Data.Monoid hunk ./Graphics/PDF.hs 135 - let w'' = compress w' + let w''' = compress . toLazyByteString $ w' + w'' = fromLazyByteString w''' hunk ./Graphics/PDF.hs 138 - updateObject ref (PDFLength (B.length w'')) + updateObject ref (PDFLength (B.length w''')) hunk ./Graphics/PDF.hs 141 - updateObject ref (PDFLength (B.length w')) + updateObject ref (PDFLength (B.length . toLazyByteString $ w')) hunk ./Graphics/PDF.hs 159 -withFile :: FilePath -> (Handle -> IO c) -> IO c -withFile name = bracket (openBinaryFile name WriteMode) hClose - hunk ./Graphics/PDF.hs 182 -writeObjectsAndCreateToc :: [B.ByteString] -- ^ List of objects each object being already converted to a bytestring - -> (Int,Int64,[B.ByteString]) -writeObjectsAndCreateToc l = foldr writeObject (0,0::Int64,[]) l where - writeObject obj (nb,len,toc) = (nb+1,len + B.length obj,(toByteString (printf "%010d 00000 n \n" ((fromIntegral len)::Integer))) : toc) +writeObjectsAndCreateToc :: [Builder] -- ^ List of objects each object being already converted to a bytestring + -> (Int,Int64,[Builder]) +writeObjectsAndCreateToc l = + let lengths = tail . scanl (\len obj -> len + (B.length . toLazyByteString $ obj)) 0 $ l + createEntry x = serialize $ (printf "%010d 00000 n \n" ((fromIntegral x)::Integer) :: String) + entries = map createEntry lengths + in + (length l,sum lengths,entries) +-- foldr writeObject (0,0::Int64,[]) l where +-- writeObject obj (nb,len,toc) = (nb+1,len + (B.length . toLazyByteString $ obj),(serialize $ (printf "%010d 00000 n \n" ((fromIntegral len)::Integer))) : toc) hunk ./Graphics/PDF.hs 209 -createObjectByteStrings :: PdfState -> PDF a -> (PDFReference PDFCatalog,Int,Int64,B.ByteString,B.ByteString) +createObjectByteStrings :: PdfState -> PDF a -> Builder hunk ./Graphics/PDF.hs 211 - let header = toByteString "%PDF-1.5\n" + let header = serialize "%PDF-1.5\n" hunk ./Graphics/PDF.hs 218 - (root,nb,len,B.concat objectContents,B.concat . tail . reverse $ toc) + mconcat$ objectContents ++ + [ serialize "xref\n" + , serialize $ "0 " ++ show nb ++ "\n" + , serialize "0000000000 65535 f \n" + ] + ++ + (tail . reverse $ toc) + ++ + [ serialize "\ntrailer\n" + , toPDF $ PDFTrailer nb root (docInfo pdfState) + , serialize "\nstartxref\n" + , serialize (show len) + , serialize "\n%%EOF" + ] hunk ./Graphics/PDF.hs 240 - let (root,nb,len,content,toc) = createObjectByteStrings (defaultPdfSettings {defaultRect = rect, docInfo = infos} ) m - withFile filename $ \h -> do - B.hPut h content - B.hPut h . toByteString $ "xref\n" - B.hPut h . toByteString $ "0 " ++ show nb ++ "\n" - B.hPut h . toByteString $ "0000000000 65535 f \n" - B.hPut h toc - B.hPut h . toByteString $ "\ntrailer\n" - B.hPut h . toPDF $ PDFTrailer nb root infos - B.hPut h . toByteString $ "\nstartxref\n" - B.hPut h . toByteString $ (show len) - B.hPut h . toByteString $ "\n%%EOF" + let content = createObjectByteStrings (defaultPdfSettings {defaultRect = rect, docInfo = infos} ) m + B.writeFile filename (toLazyByteString content) hunk ./Graphics/PDF/Colors.hs 35 -import Data.ByteString.Lazy.Char8(singleton,pack) hunk ./Graphics/PDF/Colors.hs 36 -import qualified Data.ByteString.Lazy as B(concat) - +import Graphics.PDF.LowLevel.Serializer +import Data.Monoid hunk ./Graphics/PDF/Colors.hs 62 - tell . B.concat$[ pack "\n/" - , toByteString newName - , pack " gs" + tell . mconcat $[ serialize "\n/" + , serialize newName + , serialize " gs" hunk ./Graphics/PDF/Colors.hs 73 - tell . B.concat$[ pack "\n/" - , toByteString newName - , pack " gs" + tell . mconcat $[ serialize "\n/" + , serialize newName + , serialize " gs" hunk ./Graphics/PDF/Colors.hs 80 -setRGBColorSpace = tell . pack $ "\n/DeviceRGB CS\n/DeviceRGB cs\n" +setRGBColorSpace = tell . serialize $ "\n/DeviceRGB CS\n/DeviceRGB cs\n" hunk ./Graphics/PDF/Colors.hs 88 - tell . B.concat$[ pack "\n" + tell . mconcat $[ serialize "\n" hunk ./Graphics/PDF/Colors.hs 90 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Colors.hs 92 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Colors.hs 94 - , pack " rg" + , serialize " rg" hunk ./Graphics/PDF/Colors.hs 99 - tell . B.concat$[ pack "\n" + tell . mconcat $[ serialize "\n" hunk ./Graphics/PDF/Colors.hs 101 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Colors.hs 103 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Colors.hs 105 - , pack " rg" + , serialize " rg" hunk ./Graphics/PDF/Colors.hs 112 - tell . B.concat$[ pack "\n" + tell . mconcat $[ serialize "\n" hunk ./Graphics/PDF/Colors.hs 114 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Colors.hs 116 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Colors.hs 118 - , pack " RG" + , serialize " RG" hunk ./Graphics/PDF/Colors.hs 122 - tell . B.concat$[ pack "\n" + tell . mconcat $[ serialize "\n" hunk ./Graphics/PDF/Colors.hs 124 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Colors.hs 126 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Colors.hs 128 - , pack " RG" + , serialize " RG" hunk ./Graphics/PDF/Coordinates.hs 27 -import Data.ByteString.Lazy.Char8(singleton,pack) hunk ./Graphics/PDF/Coordinates.hs 28 -import qualified Data.ByteString.Lazy as B(concat) + +import Graphics.PDF.LowLevel.Serializer +import Data.Monoid + hunk ./Graphics/PDF/Coordinates.hs 71 - tell . B.concat$[ singleton '\n' + tell . mconcat $[ serialize '\n' hunk ./Graphics/PDF/Coordinates.hs 73 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Coordinates.hs 75 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Coordinates.hs 77 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Coordinates.hs 79 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Coordinates.hs 81 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Coordinates.hs 83 - , pack " cm" + , serialize " cm" hunk ./Graphics/PDF/Document.hs 50 -import qualified Data.ByteString.Lazy as B(append) - +import Data.Monoid hunk ./Graphics/PDF/Document.hs 135 - modifyStrict $ \s -> s {streams = IM.insert streamRef (Just page,(state',B.append oldW w')) lStreams} + modifyStrict $ \s -> s {streams = IM.insert streamRef (Just page,(state',mappend oldW w')) lStreams} hunk ./Graphics/PDF/Draw.hs 69 -import qualified Data.ByteString.Lazy as B hunk ./Graphics/PDF/Draw.hs 78 -import Data.ByteString.Lazy.Char8(pack) +import qualified Data.Binary.Builder as BU +import Graphics.PDF.LowLevel.Serializer +import Data.Monoid hunk ./Graphics/PDF/Draw.hs 133 -newtype Draw a = Draw {unDraw :: RWS DrawEnvironment B.ByteString DrawState a} +newtype Draw a = Draw {unDraw :: RWS DrawEnvironment BU.Builder DrawState a} hunk ./Graphics/PDF/Draw.hs 135 - deriving(Monad,MonadWriter B.ByteString, MonadReader DrawEnvironment, MonadState DrawState, Functor) + deriving(Monad,MonadWriter BU.Builder, MonadReader DrawEnvironment, MonadState DrawState, Functor) hunk ./Graphics/PDF/Draw.hs 138 -instance MonadWriter B.ByteString Draw +instance MonadWriter BU.Builder Draw hunk ./Graphics/PDF/Draw.hs 147 -data PDFStream = PDFStream !B.ByteString !Bool !(PDFReference PDFLength) !PDFDictionary +data PDFStream = PDFStream !BU.Builder !Bool !(PDFReference PDFLength) !PDFDictionary hunk ./Graphics/PDF/Draw.hs 151 - B.concat $ [ toPDF dict - , toByteString "\nstream" + mconcat $ [ toPDF dict + , serialize "\nstream" hunk ./Graphics/PDF/Draw.hs 156 - , toByteString "endstream"] + , serialize "endstream"] hunk ./Graphics/PDF/Draw.hs 170 - --- | Write a command to the drawing ---writeCmd :: (MonadWriter B.ByteString m) => String -> m () ---writeCmd = tell . toByteString hunk ./Graphics/PDF/Draw.hs 184 -runDrawing :: Draw a -> DrawEnvironment -> DrawState -> (a,DrawState,B.ByteString) +runDrawing :: Draw a -> DrawEnvironment -> DrawState -> (a,DrawState,BU.Builder) hunk ./Graphics/PDF/Draw.hs 192 - tell . pack $ "\nq" + tell . serialize $ "\nq" hunk ./Graphics/PDF/Draw.hs 194 - tell . pack $ "\nQ" + tell . serialize $ "\nQ" hunk ./Graphics/PDF/Draw.hs 220 - tell . B.concat $ [ pack "\n/" - , toByteString newName - , pack " Do" + tell . mconcat $ [ serialize "\n/" + , serialize newName + , serialize " Do" hunk ./Graphics/PDF/Draw.hs 271 - , streams :: !(IM.IntMap ((Maybe (PDFReference PDFPage)),(DrawState,B.ByteString))) -- ^ Draw commands + , streams :: !(IM.IntMap ((Maybe (PDFReference PDFPage)),(DrawState,BU.Builder))) -- ^ Draw commands hunk ./Graphics/PDF/Image.hs 36 +import Data.Binary.Builder(Builder,fromLazyByteString) hunk ./Graphics/PDF/Image.hs 254 - return (Right $ JpegFile bits_per_component width height color_space img) + return (Right $ JpegFile bits_per_component width height color_space (fromLazyByteString img)) hunk ./Graphics/PDF/Image.hs 286 -data JpegFile = JpegFile !Int !PDFFloat !PDFFloat !Int !B.ByteString +data JpegFile = JpegFile !Int !PDFFloat !PDFFloat !Int !Builder addfile ./Graphics/PDF/LowLevel/Serializer.hs hunk ./Graphics/PDF/LowLevel/Serializer.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2006 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Serializer +--------------------------------------------------------- +-- #hide +module Graphics.PDF.LowLevel.Serializer( + SerializeValue(..) + ) where + +import Data.Word +import qualified Data.ByteString.Lazy as B +import qualified Data.Binary.Builder as BU +import qualified Data.ByteString.Lazy.Char8 as C +import Data.Encoding +import Data.Encoding.UTF8 +import Foreign.Ptr(Ptr) +import Data.Monoid +import Data.ByteString.Base + +foreign import ccall "conversion.h c_floatToString" cfloatToString :: Double -> Ptr Word8 -> IO Int +foreign import ccall "conversion.h c_shortToString" cshortToString :: Int -> Ptr Word8 -> IO Int + + + +class (Monoid s) => SerializeValue s a where + serialize :: a -> s + cons :: a -> s -> s + cons a b = (serialize a) `mappend` b + +instance SerializeValue B.ByteString Word8 where + serialize = B.singleton + cons = B.cons + +instance SerializeValue B.ByteString Char where + serialize = C.singleton + cons = C.cons + +instance SerializeValue B.ByteString [Char] where + serialize = encodeLazy UTF8 + +instance SerializeValue B.ByteString B.ByteString where + serialize = id + +instance SerializeValue B.ByteString Int where + serialize a = LPS [inlinePerformIO (createAndTrim 12 (cshortToString a))] + +instance SerializeValue B.ByteString Double where + serialize a = LPS [inlinePerformIO (createAndTrim 12 (cfloatToString a))] + + +instance SerializeValue BU.Builder Word8 where + serialize = BU.singleton + +instance SerializeValue BU.Builder Char where + serialize = BU.singleton . c2w + +instance SerializeValue BU.Builder [Char] where + serialize = BU.fromLazyByteString . serialize + +instance SerializeValue BU.Builder B.ByteString where + serialize = BU.fromLazyByteString + +instance SerializeValue BU.Builder Int where + serialize = BU.fromLazyByteString . serialize + +instance SerializeValue BU.Builder Double where + serialize = BU.fromLazyByteString . serialize + + hunk ./Graphics/PDF/LowLevel/Types.hs 15 -import qualified Data.ByteString.Lazy as B -import Data.ByteString.Base(c2w) hunk ./Graphics/PDF/LowLevel/Types.hs 23 -import Data.Encoding.UTF8 hunk ./Graphics/PDF/LowLevel/Types.hs 25 -import Foreign.Ptr(Ptr) -import Data.Word(Word8) -import Data.ByteString.Base(createAndTrim,inlinePerformIO,LazyByteString(..)) hunk ./Graphics/PDF/LowLevel/Types.hs 26 +import Data.Binary.Builder(Builder,fromByteString) +import Graphics.PDF.LowLevel.Serializer +import Data.Monoid +import qualified Data.ByteString.Lazy as B +import qualified Data.ByteString as S +import Data.ByteString.Base(LazyByteString(..)) hunk ./Graphics/PDF/LowLevel/Types.hs 35 - toPDF :: a -> B.ByteString + toPDF :: a -> Builder hunk ./Graphics/PDF/LowLevel/Types.hs 64 - toPDF (PDFInteger a) = LPS [inlinePerformIO (createAndTrim 12 (cshortToString a))] + toPDF (PDFInteger a) = serialize a hunk ./Graphics/PDF/LowLevel/Types.hs 67 - toPDF a = LPS [inlinePerformIO (createAndTrim 12 (cshortToString a))] + toPDF a = serialize a hunk ./Graphics/PDF/LowLevel/Types.hs 70 - toPDF (PDFLength a) = toByteString (show a) + toPDF (PDFLength a) = serialize (show a) hunk ./Graphics/PDF/LowLevel/Types.hs 72 -foreign import ccall "conversion.h c_floatToString" cfloatToString :: Double -> Ptr Word8 -> IO Int -foreign import ccall "conversion.h c_shortToString" cshortToString :: Int -> Ptr Word8 -> IO Int - hunk ./Graphics/PDF/LowLevel/Types.hs 73 - toPDF (PDFFloat a) = LPS [inlinePerformIO (createAndTrim 12 (cfloatToString a))] + toPDF (PDFFloat a) = serialize a hunk ./Graphics/PDF/LowLevel/Types.hs 76 - toPDF a = LPS [inlinePerformIO (createAndTrim 12 (cfloatToString a))] + toPDF a = serialize a hunk ./Graphics/PDF/LowLevel/Types.hs 79 - toPDF (True) = toByteString "true" - toPDF (False) = toByteString "false" + toPDF (True) = serialize "true" + toPDF (False) = serialize "false" hunk ./Graphics/PDF/LowLevel/Types.hs 82 --- | A PDFString -newtype PDFString = PDFString B.ByteString deriving(Eq,Ord,Show) +-- | A PDFString containing a strict bytestring +newtype PDFString = PDFString S.ByteString deriving(Eq,Ord,Show) hunk ./Graphics/PDF/LowLevel/Types.hs 87 -toPDFString = PDFString . encodeLazy ISO88591 . escapeString +toPDFString = PDFString . encode ISO88591 . escapeString hunk ./Graphics/PDF/LowLevel/Types.hs 89 --- | Convert an Haskell string to an UTF8 encoded bytestring -toByteString :: String -> B.ByteString ---toByteString = B.pack . encode -toByteString = encodeLazy UTF8 +instance SerializeValue B.ByteString PDFString where + serialize (PDFString t) = LPS [t] + +instance SerializeValue Builder PDFString where + serialize (PDFString t) = fromByteString t hunk ./Graphics/PDF/LowLevel/Types.hs 105 -lparen :: B.ByteString -lparen = B.singleton . c2w $ '(' - -rparen :: B.ByteString -rparen = B.singleton . c2w $ ')' +lparen :: SerializeValue s Char => s +lparen = serialize '(' hunk ./Graphics/PDF/LowLevel/Types.hs 108 -lbracket :: B.ByteString -lbracket = B.singleton . c2w $ '[' +rparen :: SerializeValue s Char => s +rparen = serialize ')' hunk ./Graphics/PDF/LowLevel/Types.hs 111 -rbracket :: B.ByteString -rbracket = B.singleton . c2w $ ']' +lbracket :: SerializeValue s Char => s +lbracket = serialize '[' hunk ./Graphics/PDF/LowLevel/Types.hs 114 -bspace :: B.ByteString -bspace = B.singleton . c2w $ ' ' +rbracket :: SerializeValue s Char => s +rbracket = serialize ']' hunk ./Graphics/PDF/LowLevel/Types.hs 117 -blt :: B.ByteString -blt = B.singleton . c2w $ '<' +bspace :: SerializeValue s Char => s +bspace = serialize ' ' hunk ./Graphics/PDF/LowLevel/Types.hs 120 -bgt :: B.ByteString -bgt = B.singleton . c2w $ '>' +blt :: SerializeValue s Char => s +blt = serialize '<' hunk ./Graphics/PDF/LowLevel/Types.hs 123 -newline :: B.ByteString -newline = B.singleton . c2w $ '\n' +bgt :: SerializeValue s Char => s +bgt = serialize '>' hunk ./Graphics/PDF/LowLevel/Types.hs 126 -noPdfObject :: B.ByteString -noPdfObject = B.empty +newline :: SerializeValue s Char => s +newline = serialize '\n' hunk ./Graphics/PDF/LowLevel/Types.hs 129 +noPdfObject :: Monoid s => s +noPdfObject = mempty + hunk ./Graphics/PDF/LowLevel/Types.hs 133 - toPDF (PDFString a) = B.concat [ lparen - , a - , rparen - ] + toPDF a = mconcat [ lparen + , serialize a + , rparen + ] hunk ./Graphics/PDF/LowLevel/Types.hs 142 - toPDF (PDFName a) = toByteString ("/" ++ a) + toPDF (PDFName a) = serialize ("/" ++ a) hunk ./Graphics/PDF/LowLevel/Types.hs 148 - toPDF l = B.concat $ (lbracket:intersperse bspace (map toPDF l)) ++ [bspace] ++ [rbracket] + toPDF l = mconcat $ (lbracket:intersperse bspace (map toPDF l)) ++ [bspace] ++ [rbracket] hunk ./Graphics/PDF/LowLevel/Types.hs 155 - toPDF (PDFDictionary a) = B.concat $ [blt,blt,newline] + toPDF (PDFDictionary a) = mconcat $ [blt,blt,newline] hunk ./Graphics/PDF/LowLevel/Types.hs 159 - convertLevel _ = let convertItem key value current = B.concat $ [ toPDF key - , bspace - , toPDF value - , newline - , current - ] + convertLevel _ = let convertItem key value current = mconcat $ [ toPDF key + , bspace + , toPDF value + , newline + , current + ] hunk ./Graphics/PDF/LowLevel/Types.hs 167 - M.foldWithKey convertItem B.empty a + M.foldWithKey convertItem mempty a hunk ./Graphics/PDF/LowLevel/Types.hs 195 - B.concat $ [ toByteString . show $ referenceId - , toByteString " 0 obj" + mconcat $ [ serialize . show $ referenceId + , serialize " 0 obj" hunk ./Graphics/PDF/LowLevel/Types.hs 200 - , toByteString "endobj" + , serialize "endobj" hunk ./Graphics/PDF/LowLevel/Types.hs 220 - toPDF (PDFReference i) = B.concat $ [ toByteString . show $ i - , toByteString " 0 R"] + toPDF (PDFReference i) = mconcat $ [ serialize . show $ i + , serialize " 0 R"] hunk ./Graphics/PDF/LowLevel/Types.hs 235 -class MonadWriter B.ByteString m => MonadPath m +class MonadWriter Builder m => MonadPath m hunk ./Graphics/PDF/Pattern.hs 32 -import Data.ByteString.Lazy.Char8(singleton,pack) hunk ./Graphics/PDF/Pattern.hs 33 -import qualified Data.ByteString.Lazy as B(concat) +import Graphics.PDF.LowLevel.Serializer +import Data.Monoid hunk ./Graphics/PDF/Pattern.hs 106 - tell . pack $ ("\n/Pattern cs") - tell . B.concat$[ pack "\n/" - , toByteString newName - , pack " scn" + tell . serialize $ ("\n/Pattern cs") + tell . mconcat $[ serialize "\n/" + , serialize newName + , serialize " scn" hunk ./Graphics/PDF/Pattern.hs 118 - tell . pack $ ("\n/Pattern CS") - tell . B.concat$[ pack "\n/" - , toByteString newName - , pack " SCN" + tell . serialize $ ("\n/Pattern CS") + tell . mconcat $[ serialize "\n/" + , serialize newName + , serialize " SCN" hunk ./Graphics/PDF/Pattern.hs 135 - tell . B.concat$[ pack "\n/" - , toByteString newColorName - , pack " cs" + tell . mconcat $[ serialize "\n/" + , serialize newColorName + , serialize " cs" hunk ./Graphics/PDF/Pattern.hs 139 - tell . B.concat$[ singleton '\n' + tell . mconcat $[ serialize '\n' hunk ./Graphics/PDF/Pattern.hs 141 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Pattern.hs 143 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Pattern.hs 145 - , singleton ' ' - , pack " /" - , toByteString newName - , pack " scn" + , serialize ' ' + , serialize " /" + , serialize newName + , serialize " scn" hunk ./Graphics/PDF/Pattern.hs 160 - tell . B.concat$[ pack "\n/" - , toByteString newColorName - , pack " CS" + tell . mconcat $[ serialize "\n/" + , serialize newColorName + , serialize " CS" hunk ./Graphics/PDF/Pattern.hs 164 - tell . B.concat$[ singleton '\n' + tell . mconcat $ [ serialize '\n' hunk ./Graphics/PDF/Pattern.hs 166 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Pattern.hs 168 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Pattern.hs 170 - , singleton ' ' - , pack " /" - , toByteString newName - , pack " SCN" + , serialize ' ' + , serialize " /" + , serialize newName + , serialize " SCN" hunk ./Graphics/PDF/Shading.hs 23 -import Data.ByteString.Lazy.Char8(pack) hunk ./Graphics/PDF/Shading.hs 24 -import qualified Data.ByteString.Lazy as B(concat) +import Graphics.PDF.LowLevel.Serializer +import Data.Monoid hunk ./Graphics/PDF/Shading.hs 33 - tell . B.concat$[ pack "\n/" - , toByteString newName - , pack " sh" + tell . mconcat $[ serialize "\n/" + , serialize newName + , serialize " sh" hunk ./Graphics/PDF/Shapes.hs 56 -import Data.ByteString.Lazy.Char8(singleton,pack) hunk ./Graphics/PDF/Shapes.hs 57 -import qualified Data.ByteString.Lazy as B(concat) +import Graphics.PDF.LowLevel.Serializer +import Data.Monoid hunk ./Graphics/PDF/Shapes.hs 153 -setWidth w = tell . B.concat$[ pack "\n" +setWidth w = tell . mconcat $[ serialize "\n" hunk ./Graphics/PDF/Shapes.hs 155 - , pack " w" + , serialize " w" hunk ./Graphics/PDF/Shapes.hs 160 -setMiterLimit w = tell . B.concat$[ pack "\n" +setMiterLimit w = tell . mconcat $[ serialize "\n" hunk ./Graphics/PDF/Shapes.hs 162 - , pack " M" + , serialize " M" hunk ./Graphics/PDF/Shapes.hs 179 -setLineCap w = tell . B.concat$[ pack "\n " +setLineCap w = tell . mconcat $[ serialize "\n " hunk ./Graphics/PDF/Shapes.hs 181 - , pack " J" + , serialize " J" hunk ./Graphics/PDF/Shapes.hs 186 -setLineJoin w = tell . B.concat$[ pack "\n " +setLineJoin w = tell . mconcat $[ serialize "\n " hunk ./Graphics/PDF/Shapes.hs 188 - , pack " j" + , serialize " j" hunk ./Graphics/PDF/Shapes.hs 196 - tell . B.concat$[ pack "\n " + tell . mconcat$ [ serialize "\n " hunk ./Graphics/PDF/Shapes.hs 198 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Shapes.hs 200 - , pack " d" + , serialize " d" hunk ./Graphics/PDF/Shapes.hs 215 -closePath = tell . pack $ "\nh" +closePath = tell . serialize $ "\nh" hunk ./Graphics/PDF/Shapes.hs 229 - tell . B.concat$[ pack "\n" + tell . mconcat $[ serialize "\n" hunk ./Graphics/PDF/Shapes.hs 231 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Shapes.hs 233 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Shapes.hs 235 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Shapes.hs 237 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Shapes.hs 239 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Shapes.hs 241 - , pack " c" + , serialize " c" hunk ./Graphics/PDF/Shapes.hs 249 - tell . B.concat$[ pack "\n" + tell . mconcat $[ serialize "\n" hunk ./Graphics/PDF/Shapes.hs 251 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Shapes.hs 253 - , pack " m" + , serialize " m" hunk ./Graphics/PDF/Shapes.hs 261 - tell . B.concat$[ pack "\n" + tell . mconcat $[ serialize "\n" hunk ./Graphics/PDF/Shapes.hs 263 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Shapes.hs 265 - , pack " l s" + , serialize " l s" hunk ./Graphics/PDF/Shapes.hs 273 - tell . B.concat$[ pack "\n" + tell . mconcat $[ serialize "\n" hunk ./Graphics/PDF/Shapes.hs 275 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Shapes.hs 277 - , pack " l" + , serialize " l" hunk ./Graphics/PDF/Shapes.hs 293 -strokePath = tell . pack $ "\nS" +strokePath = tell . serialize $ "\nS" hunk ./Graphics/PDF/Shapes.hs 297 -fillPath = tell . pack $ "\nf" +fillPath = tell . serialize $ "\nf" hunk ./Graphics/PDF/Shapes.hs 301 -fillAndStrokePath = tell . pack $ "\nB" +fillAndStrokePath = tell . serialize $ "\nB" hunk ./Graphics/PDF/Shapes.hs 305 -setAsClipPathEO = tell . pack $ "\nW* n" +setAsClipPathEO = tell . serialize $ "\nW* n" hunk ./Graphics/PDF/Shapes.hs 309 -setAsClipPath = tell . pack $ "\nW n" +setAsClipPath = tell . serialize $ "\nW n" hunk ./Graphics/PDF/Shapes.hs 313 -fillPathEO = tell . pack $ "\nf*" +fillPathEO = tell . serialize $ "\nf*" hunk ./Graphics/PDF/Shapes.hs 317 -fillAndStrokePathEO = tell . pack $ "\nB*" +fillAndStrokePathEO = tell . serialize $ "\nB*" hunk ./Graphics/PDF/Text.hs 39 - , textBox hunk ./Graphics/PDF/Text.hs 47 -import qualified Data.ByteString.Lazy as B -import Data.ByteString.Base(w2c,c2w) hunk ./Graphics/PDF/Text.hs 54 -import Graphics.PDF.Shapes -import qualified Data.ByteString.Lazy.Char8 as B(words,unwords) -import Data.ByteString.Lazy.Char8(singleton,pack) hunk ./Graphics/PDF/Text.hs 55 +import Data.Binary.Builder(Builder) +import Graphics.PDF.LowLevel.Serializer +import Data.Monoid +import qualified Data.ByteString as S +import Data.ByteString.Base(w2c,c2w) hunk ./Graphics/PDF/Text.hs 62 -foreign import ccall "ctext.h c_getAdvance" cgetAdvance :: Int -> Word8 -> Int +foreign import ccall "ctext.h c_getAdvance" cgetAdvance :: Int -> Int -> Int hunk ./Graphics/PDF/Text.hs 83 -textWidth (PDFFont n s) (PDFString t) = let w = foldl' (\a b -> a + cgetAdvance (fromEnum n) b) 0 . B.unpack $ t in +textWidth (PDFFont n s) (PDFString t) = + let w = foldl' (\a b -> a + cgetAdvance (fromEnum n) (fromIntegral b)) 0 . S.unpack $ t + in hunk ./Graphics/PDF/Text.hs 88 - trueSize s (w + (foldl' (\a b -> a + getKern b) 0 $ [(fromEnum n,ca,cb) | (ca,cb) <- B.zip t (B.tail t)])) + trueSize s (w + (foldl' (\a b -> a + getKern b) 0 $ [(fromEnum n,ca,cb) | (ca,cb) <- S.zip t (S.tail t)])) hunk ./Graphics/PDF/Text.hs 93 -charWidth (PDFFont n s) c = let w = cgetAdvance (fromEnum n) (c2w c) in +charWidth (PDFFont n s) c = let w = cgetAdvance (fromEnum n) (fromEnum c) in hunk ./Graphics/PDF/Text.hs 95 + +c2i :: Char -> Int +c2i = fromEnum hunk ./Graphics/PDF/Text.hs 102 -ripText (PDFFont n s) (PDFString t) = getLetters (hasKern (fromEnum n)) . B.unpack $ t +ripText (PDFFont n s) (PDFString t) = getLetters (hasKern (fromEnum n)) . S.unpack $ t hunk ./Graphics/PDF/Text.hs 104 - slash = c2w '/' - hyphen = c2w '-' hunk ./Graphics/PDF/Text.hs 105 - getLetters _ [a] = [(trueSize s $ cgetAdvance (fromEnum n) a,w2c a)] - getLetters False (a:l) = (trueSize s $ cgetAdvance (fromEnum n) a,w2c a) : getLetters False l - getLetters True (a:b:c:d:l) | b == slash && c == hyphen = + getLetters _ [a] = [(trueSize s $ cgetAdvance (fromEnum n) (fromEnum a),w2c a)] + getLetters False (a:l) = (trueSize s $ cgetAdvance (fromEnum n) (fromEnum a),w2c a) : getLetters False l + getLetters True (a:b:c:d:l) | b == (c2w '/') && c == (c2w '-') = hunk ./Graphics/PDF/Text.hs 109 - kh = getKern (fromEnum n,a,hyphen) - hw = cgetAdvance (fromEnum n) hyphen + kh = getKern (fromEnum n,a,c2w '-') + hw = cgetAdvance (fromEnum n) (c2i '-') hunk ./Graphics/PDF/Text.hs 113 - (trueSize s $ cgetAdvance (fromEnum n) a + k,w2c a):(0,'/'):(trueSize s $ hw-k+kh,'-'):getLetters True (d:l) - | otherwise = (trueSize s $ cgetAdvance (fromEnum n) a + getKern (fromEnum n,a,b),w2c a) : getLetters True (b:c:d:l) - getLetters True (a:b:l) = (trueSize s $ cgetAdvance (fromEnum n) a + getKern (fromEnum n,a,b),w2c a) : getLetters True (b:l) + (trueSize s $ cgetAdvance (fromEnum n) (fromEnum a) + k,w2c a):(0,'/'):(trueSize s $ hw-k+kh,'-'):getLetters True (d:l) + | otherwise = (trueSize s $ cgetAdvance (fromEnum n) (fromEnum a) + getKern (fromEnum n,a,b),w2c a) : getLetters True (b:c:d:l) + getLetters True (a:b:l) = (trueSize s $ cgetAdvance (fromEnum n) (fromEnum a) + getKern (fromEnum n,a,b),w2c a) : getLetters True (b:l) hunk ./Graphics/PDF/Text.hs 129 --- | Tolerance value when text is too long. We accept to overflow a little -tolerance :: PDFFloat -tolerance = 0.2 - --- | Format a text string inside a rectangle. Experimental and will be replaced by a better typesetting --- system in a next version -textBox :: PDFFont -- ^ Font to use - -> PDFString -- ^ Text to draw - -> Rectangle -- ^ Where to draw - -> Draw () -textBox f@(PDFFont _ size) (PDFString s) (Rectangle xa _ xb yb) = do - let width = xb -xa - ws = textWidth f (toPDFString " ") - getLines _ l [] = [B.unwords . reverse $ l] - getLines c l (h:t) = let c' = c + ws + textWidth f (PDFString h) in - if c' > width + tolerance * (fromIntegral size) - then - (B.unwords . reverse $ l):getLines 0 [] (h:t) - else - getLines c' (h:l) t - drawText $ do - setFont f - leading $ getHeight f - textStart xa (yb + getDescent f) - startNewLine - mapM_ (\x -> displayText x >> startNewLine) (map PDFString . getLines 0 [] $ (B.words s)) - - hunk ./Graphics/PDF/Text.hs 131 -newtype PDFText a = PDFText {unText :: WriterT B.ByteString (State TextParameter) a} +newtype PDFText a = PDFText {unText :: WriterT Builder (State TextParameter) a} hunk ./Graphics/PDF/Text.hs 133 - deriving(Monad,Functor,MonadWriter B.ByteString) + deriving(Monad,Functor,MonadWriter Builder) hunk ./Graphics/PDF/Text.hs 137 -instance MonadWriter B.ByteString PDFText +instance MonadWriter Builder PDFText hunk ./Graphics/PDF/Text.hs 160 - tell . B.concat$[ pack "\n/" - , toByteString (show n) - , singleton ' ' + tell . mconcat$ [ serialize "\n/" + , serialize (show n) + , serialize ' ' hunk ./Graphics/PDF/Text.hs 164 - , pack " Tf" + , serialize " Tf" hunk ./Graphics/PDF/Text.hs 174 - tell . pack $ "\nBT" + tell . serialize $ "\nBT" hunk ./Graphics/PDF/Text.hs 176 - tell . pack $ "\nET" + tell . serialize $ "\nET" hunk ./Graphics/PDF/Text.hs 185 -textStart x y = tell . B.concat $ [ singleton '\n' +textStart x y = tell . mconcat $ [ serialize '\n' hunk ./Graphics/PDF/Text.hs 187 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Text.hs 189 - , pack " Td" + , serialize " Td" hunk ./Graphics/PDF/Text.hs 198 - tell . pack $ " Tj" + tell . serialize $ " Tj" hunk ./Graphics/PDF/Text.hs 203 -startNewLine = tell . pack $ "\nT*" +startNewLine = tell . serialize $ "\nT*" hunk ./Graphics/PDF/Text.hs 209 - tell . B.concat $ [ singleton '\n' + tell . mconcat $ [ serialize '\n' hunk ./Graphics/PDF/Text.hs 211 - , pack " TL" + , serialize " TL" hunk ./Graphics/PDF/Text.hs 218 - tell . B.concat $ [ singleton '\n' + tell . mconcat $ [ serialize '\n' hunk ./Graphics/PDF/Text.hs 220 - , pack " Tc" + , serialize " Tc" hunk ./Graphics/PDF/Text.hs 227 - tell . B.concat $ [ singleton '\n' + tell . mconcat $ [ serialize '\n' hunk ./Graphics/PDF/Text.hs 229 - , pack " Tw" + , serialize " Tw" hunk ./Graphics/PDF/Text.hs 236 - tell . B.concat $ [ singleton '\n' + tell . mconcat $ [ serialize '\n' hunk ./Graphics/PDF/Text.hs 238 - , pack " Tz" + , serialize " Tz" hunk ./Graphics/PDF/Text.hs 244 - tell . B.concat $ [ singleton '\n' + tell . mconcat $ [ serialize '\n' hunk ./Graphics/PDF/Text.hs 246 - , pack " Tr" + , serialize " Tr" hunk ./Graphics/PDF/Text.hs 253 - tell . B.concat $ [ singleton '\n' + tell . mconcat $ [ serialize '\n' hunk ./Graphics/PDF/Text.hs 255 - , pack " Ts" + , serialize " Ts" hunk ./Graphics/PDF/Text.hs 261 - tell . B.concat$[ singleton '\n' + tell . mconcat $[ serialize '\n' hunk ./Graphics/PDF/Text.hs 263 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Text.hs 265 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Text.hs 267 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Text.hs 269 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Text.hs 271 - , singleton ' ' + , serialize ' ' hunk ./Graphics/PDF/Text.hs 273 - , pack " Tm" + , serialize " Tm" hunk ./Graphics/PDF/Typesetting/Horizontal.hs 20 -import Data.ByteString.Lazy.Char8(singleton,cons,pack) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 22 -import qualified Data.ByteString.Lazy as B(ByteString,reverse,concat) +import qualified Data.ByteString.Char8 as S(pack) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 28 -import qualified Data.ByteString.Base as Base -import qualified Data.ByteString as Strict hunk ./Graphics/PDF/Typesetting/Horizontal.hs 30 - -forceStrict :: Base.LazyByteString -> Base.LazyByteString -forceStrict (Base.LPS l) = Base.LPS [Strict.concat l] +import Graphics.PDF.LowLevel.Serializer +import Data.Monoid hunk ./Graphics/PDF/Typesetting/Horizontal.hs 34 -saveCurrentword :: B.ByteString -> PDFString -saveCurrentword = PDFString . forceStrict . B.reverse +saveCurrentword :: String -> PDFString +saveCurrentword = PDFString . S.pack . reverse hunk ./Graphics/PDF/Typesetting/Horizontal.hs 41 - -> Maybe (AnyStyle,B.ByteString, PDFFloat) -- ^ Current word + -> Maybe (AnyStyle,String, PDFFloat) -- ^ Current word hunk ./Graphics/PDF/Typesetting/Horizontal.hs 50 -createWords r Nothing ((AChar s t w):l) = createWords r (Just (s,singleton t,w)) l +createWords r Nothing ((AChar s t w):l) = createWords r (Just (s,[t],w)) l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 52 -createWords r (Just (s,t,w)) ((AChar s' t' w'):l) | styleCode s == styleCode s' = createWords r (Just (s,cons t' t,w+w')) l - | otherwise = (createText s (saveCurrentword $ t) w):createWords r (Just (s',singleton t',w')) l +createWords r (Just (s,t,w)) ((AChar s' t' w'):l) | styleCode s == styleCode s' = createWords r (Just (s,t':t,w+w')) l + | otherwise = (createText s (saveCurrentword $ t) w):createWords r (Just (s',[t'],w')) l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 211 - tell $ B.concat [newline,lbracket]) + tell $ mconcat [newline,lbracket]) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 217 - tell $ pack " TJ") + tell $ serialize " TJ") hunk ./Graphics/PDF/Typesetting/Horizontal.hs 228 - tell . B.concat $ [ lparen, bspace,rparen,bspace,toPDF ((-delta) * 1000.0 / (fromIntegral size) ), bspace] + tell . mconcat $ [ lparen, bspace,rparen,bspace,toPDF ((-delta) * 1000.0 / (fromIntegral size) ), bspace] hunk ./HPDF.cabal 10 -build-depends: base, haskell98,mtl,encoding >= 0.1 ,zlib >= 0.3 +build-depends: base, haskell98,mtl,encoding >= 0.1 ,zlib >= 0.3, binary >= 0.3 hunk ./HPDF.cabal 57 - + Graphics.PDF.LowLevel.Serializer hunk ./Test/test.hs 71 - myDrawing = do - stroke (Line 0 0 100 100) - fill (Rectangle 100 100 200 200) hunk ./Test/test.hs 89 - fontDebug (PDFFont Times_Roman 48) (toPDFString "This is a test !") + fontDebug (PDFFont Times_Roman 48) (toPDFString "This is a test (éèçàù)!") hunk ./Test/test.hs 155 -crazyWord (Rectangle xa ya xb yb) DrawGlue d = do +crazyWord (Rectangle xa ya xb yb) DrawGlue _ = do hunk ./Test/test.hs 181 - wordStyle (SuperCrazy (l,angl)) = Just ws + wordStyle (SuperCrazy (l,_)) = Just ws hunk ./Test/test.hs 183 - ws r DrawGlue _ = return () + ws _ DrawGlue _ = return () hunk ./Test/test.hs 186 - angle = head angl + --angle = head angl hunk ./Test/test.hs 201 - + +triangleArea :: PDFFloat -> PDFFloat -> TextArea hunk ./Test/test.hs 205 - + +circleArea :: PDFFloat -> PDFFloat -> TextArea hunk ./Test/test.hs 211 - pasin x = if x >= 1.0 then pi/2 else if x <= -1.0 then (-pi/2) else asin x + pasin x' = if x' >= 1.0 then pi/2 else if x' <= -1.0 then (-pi/2) else asin x' hunk ./Test/test.hs 220 - let f = PDFFont Times_Roman 10 - debugText = do + let debugText = do hunk ./Test/test.hs 254 - mapM_ (const (paragraph par)) [1..4] - textStart = 300 - getHeight f + getDescent f + mapM_ (const (paragraph par)) ([1..4]::[Int]) + --textStart = 300 - getHeight f + getDescent f hunk ./Test/test.hs 271 - mapM_ (const normalPar) [1..4] + mapM_ (const normalPar) ([1..4]::[Int]) hunk ./Test/test.hs 279 - page <- addPage Nothing + page1 <- addPage Nothing hunk ./Test/test.hs 282 - typesetTest 1 page + typesetTest 1 page1 hunk ./Test/test.hs 284 - page <- addPage Nothing + page2 <- addPage Nothing hunk ./Test/test.hs 286 - typesetTest 2 page + typesetTest 2 page2 hunk ./Test/test.hs 288 - page <- addPage Nothing + page3 <- addPage Nothing hunk ./Test/test.hs 290 - typesetTest 3 page + typesetTest 3 page3 hunk ./Test/test.hs 292 - page <- addPage Nothing + page4 <- addPage Nothing hunk ./Test/test.hs 296 - drawWithPage page $ do + drawWithPage page4 $ do hunk ./Test/test.hs 299 - page <- addPage Nothing + page5 <- addPage Nothing hunk ./Test/test.hs 301 - drawWithPage page $ do + drawWithPage page5 $ do hunk ./Test/test.hs 303 - page <- addPage Nothing + + page6 <- addPage Nothing hunk ./Test/test.hs 307 - drawWithPage page $ do + drawWithPage page6 $ do hunk ./Test/test.hs 310 - page <- addPage Nothing - newSectionWithPage (toPDFString "Painting") Nothing Nothing page $ do + page7 <- addPage Nothing + newSectionWithPage (toPDFString "Painting") Nothing Nothing page7 $ do hunk ./Test/test.hs 313 - patternTest page - page <- addPage Nothing + patternTest page7 + + page8 <- addPage Nothing hunk ./Test/test.hs 317 - drawWithPage page $ do + drawWithPage page8 $ do hunk ./Test/test.hs 319 - page <- addPage Nothing + + page9 <- addPage Nothing hunk ./Test/test.hs 323 - testImage jpg page + testImage jpg page9 hunk ./Test/test.hs 325 - page <- addPage Nothing + page10 <- addPage Nothing hunk ./Test/test.hs 327 - drawWithPage page $ do + drawWithPage page10 $ do hunk ./Test/test.hs 329 - page <- addPage Nothing - newSection (toPDFString "Text") Nothing Nothing $ do - drawWithPage page $ do + + page11 <- addPage Nothing + newSection (toPDFString "Text encoding") Nothing Nothing $ do + drawWithPage page11 $ do hunk ./c/ctext.h 3 -extern short c_getAdvance(unsigned short,unsigned char); +extern short c_getAdvance(unsigned short,short); hunk ./c/metrics.c 8 -short c_getAdvance(unsigned short font,unsigned char c) +short c_getAdvance(unsigned short font,short c) hunk ./c/metrics.c 12 + if (c-32 >= GFONTSIZE) + return(0); hunk ./Graphics/PDF.hs 185 - let lengths = tail . scanl (\len obj -> len + (B.length . toLazyByteString $ obj)) 0 $ l + let lengths = tail . scanl (\len obj -> len + (B.length . toLazyByteString $ obj)) 0 $ l hunk ./Graphics/PDF.hs 189 - (length l,sum lengths,entries) + (length l,last lengths,init entries) hunk ./Graphics/PDF.hs 224 - (tail . reverse $ toc) + toc hunk ./Graphics/PDF.hs 179 - hunk ./Graphics/PDF.hs 186 - entries = map createEntry lengths + entries = map createEntry (init lengths) hunk ./Graphics/PDF.hs 188 - (length l,last lengths,init entries) + (length l,last lengths,entries) hunk ./Graphics/PDF/Typesetting/Breaking.hs 19 - , glue + , kernBox + , glueBox hunk ./Graphics/PDF/Typesetting/Breaking.hs 22 - , spaceGlue + , spaceGlueBox hunk ./Graphics/PDF/Typesetting/Breaking.hs 47 -data Letter = Letter !AnyBox - | Glue !PDFFloat !PDFFloat !PDFFloat !(Maybe AnyStyle) - | FlaggedPenalty !PDFFloat !Int !AnyStyle - | Penalty !Int - | AChar !AnyStyle !Char !PDFFloat +data Letter = Letter !AnyBox -- ^ Any box as a letter + | Glue !PDFFloat !PDFFloat !PDFFloat !(Maybe AnyStyle) -- ^ A glue with style to know if it is part of the same sentence + | FlaggedPenalty !PDFFloat !Int !AnyStyle -- ^ Hyphen point + | Penalty !Int -- ^ Penalty + | AChar !AnyStyle !Char !PDFFloat -- ^ A char + | Kern !PDFFloat !(Maybe AnyStyle) -- ^ A kern : non dilatable and non breakable glue hunk ./Graphics/PDF/Typesetting/Breaking.hs 77 +letterWidth (Kern w _) _ = w hunk ./Graphics/PDF/Typesetting/Breaking.hs 85 - + show (Kern _ _) = "(Kern)" hunk ./Graphics/PDF/Typesetting/Breaking.hs 252 +createBreaknode prev (ZList _ (w,y,z,_,Kern _ _) _) = BreakNode w y z 0.0 False 0 0.0 prev hunk ./Graphics/PDF/Typesetting/Breaking.hs 459 -glue :: PDFFloat -- ^ Glue width - -> PDFFloat -- ^ Glue dilatation - -> PDFFloat -- ^ Glue compression - -> Letter -glue w y z = Glue w y z Nothing +glueBox :: Maybe AnyStyle + -> PDFFloat -- ^ Glue width + -> PDFFloat -- ^ Glue dilatation + -> PDFFloat -- ^ Glue compression + -> Letter +glueBox s w y z = Glue w y z s hunk ./Graphics/PDF/Typesetting/Breaking.hs 467 -spaceGlue :: AnyStyle -- ^ The style - -> Letter -spaceGlue s = +spaceGlueBox :: AnyStyle -- ^ The style + -> Letter +spaceGlueBox s = hunk ./Graphics/PDF/Typesetting/Breaking.hs 510 -createLetterBoxes settings s ((_,' '):l) = (spaceGlue s) : createLetterBoxes settings s l +createLetterBoxes settings s ((_,' '):l) = (spaceGlueBox s) : createLetterBoxes settings s l hunk ./Graphics/PDF/Typesetting/Breaking.hs 518 + +kernBox :: AnyStyle -> PDFFloat -> Letter +kernBox s w = Kern w (Just s) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 15 + , mkHboxWithRatio hunk ./Graphics/PDF/Typesetting/Horizontal.hs 67 -createWords r Nothing ((Letter a):l) = (SomeBox a):createWords r Nothing l -createWords r (Just (s,t,w)) ((Letter a):l) = (createText s (saveCurrentword $ t) w):(SomeBox a):createWords r Nothing l +createWords r Nothing ((Kern w' s):l) = (HGlue w' Nothing s):createWords r Nothing l +createWords r (Just (s,t,w)) ((Kern w' s'):l) = (createText s (saveCurrentword $ t) w):(HGlue w' Nothing s'):createWords r Nothing l + +createWords r Nothing ((Letter a):l) = (SomeHBox a):createWords r Nothing l +createWords r (Just (s,t,w)) ((Letter a):l) = (createText s (saveCurrentword $ t) w):(SomeHBox a):createWords r Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 87 -horizontalPostProcess ((r,l'):l) = (mkHboxWithRatio r $ simplify r l'):horizontalPostProcess l +horizontalPostProcess ((r,l'):l) = let l'' = simplify r l' in + if null l'' + then + horizontalPostProcess l + else + (mkHboxWithRatio r l''):horizontalPostProcess l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 102 - | SomeBox !AnyBox - + | SomeHBox !AnyBox + + hunk ./Graphics/PDF/Typesetting/Horizontal.hs 111 -mkHboxWithRatio _ [] = SomeBox (AnyBox NullChar) +mkHboxWithRatio _ [] = SomeHBox (AnyBox NullChar) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 140 - show (SomeBox t) = "(SomeBox " ++ show t ++ ")" + show (SomeHBox t) = "(SomeHBox " ++ show t ++ ")" hunk ./Graphics/PDF/Typesetting/Horizontal.hs 193 - boxWidth (SomeBox a) = boxWidth a + boxWidth (SomeHBox a) = boxWidth a hunk ./Graphics/PDF/Typesetting/Horizontal.hs 198 - boxHeight (SomeBox a) = boxHeight a + boxHeight (SomeHBox a) = boxHeight a hunk ./Graphics/PDF/Typesetting/Horizontal.hs 203 - boxDescent (SomeBox a) = boxDescent a + boxDescent (SomeHBox a) = boxDescent a hunk ./Graphics/PDF/Typesetting/Horizontal.hs 276 - strokeBox (SomeBox a) x y = strokeBox a x y + strokeBox (SomeHBox a) x y = strokeBox a x y hunk ./Graphics/PDF/Typesetting/Vertical.hs 16 - , createVBoxes + , VerState(..) + , verticalPostProcess + , mkVboxWithRatio hunk ./Graphics/PDF/Typesetting/Vertical.hs 20 + , vglue + , defaultVerState hunk ./Graphics/PDF/Typesetting/Vertical.hs 29 +import Data.List(foldl') + +data VerState = VerState { baselineskipW :: !PDFFloat + , baselineskipY :: !PDFFloat + , baselineskipZ :: !PDFFloat + , lineskip :: !VBox + , lineskiplimit :: !PDFFloat} + +defaultVerState :: VerState +defaultVerState = VerState { baselineskipW = 12 + , baselineskipY = 0.17 + , baselineskipZ = 0.0 + , lineskip = vglue 3.0 0.33 0.0 + , lineskiplimit = 2 + } hunk ./Graphics/PDF/Typesetting/Vertical.hs 50 - | VBox AnyBox + | VBox !PDFFloat !PDFFloat !PDFFloat ![VBox] + | VGlue !PDFFloat !(Maybe (PDFFloat,PDFFloat)) !(Maybe AnyStyle) + | SomeVBox !AnyBox + +vglue :: PDFFloat + -> PDFFloat + -> PDFFloat + -> VBox +vglue w y z = VGlue w (Just(y,z)) Nothing + +instance Show VBox where + show (VBox _ _ _ a) = "(HBox " ++ show a ++ ")" + show (VGlue a _ _) = "(HGlue " ++ show a ++ ")" + show (Paragraph _) = "(Paragraph)" + show (SomeVBox t) = "(SomeHBox " ++ show t ++ ")" + +-- | A line of hboxes with an adjustement ratio required to display the text (generate the PDF command to increase space size) +--data HLine = HLine !PDFFloat ![HBox] deriving(Show) + +mkVboxWithRatio :: PDFFloat -- ^ Adjustement ratio + -> [VBox] + -> VBox +mkVboxWithRatio _ [] = SomeVBox (AnyBox NullChar) +mkVboxWithRatio r l = + let w = foldl' (\x y -> x + boxWidthWithRatio y r) 0.0 l + h = maximum . map boxHeight $ l + d = maximum . map boxDescent $ l + addBox (VGlue gw (Just(y,z)) s) (VBox w' h' d' l') = VBox w' h' d' (VGlue (glueWidth gw y z r) Nothing s:l') + addBox a (VBox w' h' d' l') = VBox w' h' d' (a:l') + addBox _ _ = error "We can add boxes only to an horizontal list" + in + -- Add boxes and dilate glues when needing fixing their dimensions after dilatation + foldr addBox (VBox w h d []) l + +instance MaybeGlue VBox where + boxWidthWithRatio (VGlue w (Just(y,z)) _) r = glueWidth w y z r + boxWidthWithRatio a _ = boxWidth a hunk ./Graphics/PDF/Typesetting/Vertical.hs 100 + hunk ./Graphics/PDF/Typesetting/Vertical.hs 107 - createVBox = VBox . AnyBox + createVBox = SomeVBox . AnyBox hunk ./Graphics/PDF/Typesetting/Vertical.hs 116 -createVBoxes settings o t (a@(VBox _):l') = a:createVBoxes settings (o+1) t l' -createVBoxes settings o t@(TextArea _ _ fmaxw) ((Paragraph l):l') = - let fl = formatList settings (onlyPositive . shiftBy o $ fmaxw) l +createVBoxes paraSettings o t@(TextArea _ _ fmaxw) ((Paragraph l):l') = + let fl = formatList paraSettings (onlyPositive . shiftBy o $ fmaxw) l hunk ./Graphics/PDF/Typesetting/Vertical.hs 119 - (toVBoxes . horizontalPostProcess $ fl) ++ createVBoxes settings (o + length fl) t l' + (toVBoxes . horizontalPostProcess $ fl) ++ createVBoxes paraSettings (o + length fl) t l' +createVBoxes paraSettings o t (a:l') = a:createVBoxes paraSettings (o+1) t l' + +verticalPostProcess :: (VerState,BRState) + -> Int -- ^ Line offset for the text area + -> TextArea -- ^ Text area + -> [VBox] -- ^ List of VBox with paragraphs + -> [VBox] -- ^ List of VBox where paragraphs have been line broken +verticalPostProcess (pageSettings,paraSettings) i t l = addInterlineGlue pageSettings . createVBoxes paraSettings i t $ l hunk ./Graphics/PDF/Typesetting/Vertical.hs 130 +notGlue :: VBox -> Bool +notGlue (VGlue _ _ _) = False +notGlue (Paragraph _) = False +notGlue _ = True + +addInterlineGlue :: VerState -> [VBox] -> [VBox] +addInterlineGlue _ [] = [] +addInterlineGlue _ [a] = [a] +addInterlineGlue settings (a:b:l) | notGlue a && notGlue b = + let p = boxDescent a + h = boxHeight b - boxDescent b + ba = baselineskipW settings + li = lineskiplimit settings + in + if p <= -1000 + then + a:addInterlineGlue settings (b:l) + else + if ba - p - h >= li + then + a:(vglue (ba-p-h) (baselineskipY settings) (baselineskipZ settings)):addInterlineGlue settings (b:l) + else + a:(lineskip settings):addInterlineGlue settings (b:l) + | otherwise = a:addInterlineGlue settings (b:l) + +instance Box VBox where + boxWidth (Paragraph _) = 0 + boxWidth (VBox _ _ _ _) = 0 + boxWidth (SomeVBox _) = 0 + boxWidth (VGlue _ _ _) = 0 + + boxHeight (Paragraph _) = 0 + boxHeight (VBox _ h _ _) = h + boxHeight (SomeVBox a) = boxHeight a + boxHeight (VGlue w _ _) = w + + boxDescent (Paragraph _) = 0 + boxDescent (VBox _ _ d _) = d + boxDescent (SomeVBox a) = boxDescent a + boxDescent (VGlue _ _ _) = 0 + +instance DisplayableBox VBox where + strokeBox (Paragraph _) _ _ = return () + strokeBox (VBox _ _ _ l) x y = strokeVBoxes l (const x) y + strokeBox (VGlue _ _ _) _ _ = return () + + strokeBox (SomeVBox a) x y = do + let h = boxHeight a + y' = y + boxDescent a - h + strokeBox a x y' + + hunk ./Graphics/PDF/Typesetting/Vertical.hs 184 - -> PDFFloat -- ^ Adjustement ratio hunk ./Graphics/PDF/Typesetting/Vertical.hs 187 -strokeVBoxes b _ fx y'' = recurseStrokeVBoxes 1 b y'' +strokeVBoxes b fx y'' = recurseStrokeVBoxes 1 b y'' hunk ./Graphics/PDF/Typesetting/Vertical.hs 191 - recurseStrokeVBoxes nb ((VBox theLine):l) y = do - let h = boxHeight theLine - y' = y + boxDescent theLine - h - strokeBox theLine (fx nb) y' -- Adjustement ratio is forced by the HBox so we can pass 1.0 + recurseStrokeVBoxes nb (a@(VGlue _ _ _):l) y = recurseStrokeVBoxes nb l (y-(boxHeight a)) + + recurseStrokeVBoxes nb (a:l) y = do + let h = boxHeight a + strokeBox a (fx nb) y hunk ./Graphics/PDF/Typesetting/Vertical.hs 197 - hunk ./Graphics/PDF/Typesetting.hs 28 - , glue + , kern hunk ./Graphics/PDF/Typesetting.hs 39 + , setBaseLineSkip + , setLineSkipLimit + , setLineSkip + , getFirstPassTolerance + , getSecondPassTolerance + , getHyphenPenaltyValue + , getFitnessDemerit + , getHyphenDemerit + , getLinePenalty + , getBaseLineSkip + , getLineSkipLimit + , getLineSkip + , rlap + , llap hunk ./Graphics/PDF/Typesetting.hs 61 +import Graphics.PDF.Typesetting.Horizontal hunk ./Graphics/PDF/Typesetting.hs 81 - let (a, s', boxes) = (runRWS . unTM $ t >>= \x' -> do {return x'} ) () (TMState (AnyStyle defaultStyle) defaultBreakingSettings) - strokeVBoxes (createVBoxes (breakSettings s') 0 area boxes) 1.0 fx y + let (a, s', boxes) = (runRWS . unTM $ t >>= \x' -> do {return x'} ) () (defaultTmState defaultStyle) + strokeVBoxes (verticalPostProcess (pageSettings s',paraSettings s') 0 area boxes) fx y hunk ./Graphics/PDF/Typesetting.hs 86 -endParagraphBoxes = [glue 0 10000.0 0,penalty (-infinity)] +endParagraphBoxes = [glueBox Nothing 0 10000.0 0,penalty (-infinity)] hunk ./Graphics/PDF/Typesetting.hs 94 +defaultTmState :: Style s => s -> TMState +defaultTmState s = TMState { tmStyle = AnyStyle s + , paraSettings = defaultBreakingSettings + , pageSettings = defaultVerState + } hunk ./Graphics/PDF/Typesetting.hs 101 - , breakSettings :: !BRState + , paraSettings :: !BRState + , pageSettings :: !VerState hunk ./Graphics/PDF/Typesetting.hs 130 - + glue :: PDFFloat -> PDFFloat -> PDFFloat -> m () hunk ./Graphics/PDF/Typesetting.hs 140 - addBox a = TM . tell $ ([VBox (AnyBox a)]) + addBox a = TM . tell $ ([SomeVBox (AnyBox a)]) hunk ./Graphics/PDF/Typesetting.hs 142 + -- | Add a glue + glue w y z = addBox $ vglue w y z hunk ./Graphics/PDF/Typesetting.hs 155 + -- | Add a glue + glue w y z = do + f <- currentStyle + tell $ [glueBox (Just f) w y z] + hunk ./Graphics/PDF/Typesetting.hs 163 - TMState f settings <- get + TMState f settings pagesettings <- get hunk ./Graphics/PDF/Typesetting.hs 165 - put $! TMState s' settings + put $! TMState s' settings pagesettings hunk ./Graphics/PDF/Typesetting.hs 185 +-- | add a kern +kern :: PDFFloat -> Para() +kern w = do + f <- currentStyle + tell $ [kernBox f w] + +setBaseLineSkip :: PDFFloat -> PDFFloat -> PDFFloat -> TM () +setBaseLineSkip w y z = modifyStrict $ \s -> s {pageSettings = (pageSettings s){baselineskipW = w,baselineskipY=y,baselineskipZ=z}} + +getBaseLineSkip :: TM (PDFFloat,PDFFloat,PDFFloat) +getBaseLineSkip = do + s <- gets pageSettings + return (baselineskipW s,baselineskipY s,baselineskipZ s) + +setLineSkipLimit :: PDFFloat -> TM () +setLineSkipLimit l = modifyStrict $ \s -> s {pageSettings = (pageSettings s){lineskiplimit=l}} + +getLineSkipLimit :: TM PDFFloat +getLineSkipLimit = gets pageSettings >>= return . lineskiplimit + +setLineSkip :: PDFFloat -> PDFFloat -> PDFFloat -> TM () +setLineSkip w y z = modifyStrict $ \s -> s {pageSettings = (pageSettings s){lineskip = vglue w y z}} + +getLineSkip :: TM VBox +getLineSkip = gets pageSettings >>= return . lineskip + hunk ./Graphics/PDF/Typesetting.hs 212 -setFirstPassTolerance x = modifyStrict $ \s -> s {breakSettings = (breakSettings s){firstPassTolerance = x}} +setFirstPassTolerance x = modifyStrict $ \s -> s {paraSettings = (paraSettings s){firstPassTolerance = x}} + +getFirstPassTolerance :: TM PDFFloat +getFirstPassTolerance = gets paraSettings >>= return . firstPassTolerance hunk ./Graphics/PDF/Typesetting.hs 218 -setSecondPassTolerance x = modifyStrict $ \s -> s {breakSettings = (breakSettings s){secondPassTolerance = x}} +setSecondPassTolerance x = modifyStrict $ \s -> s {paraSettings = (paraSettings s){secondPassTolerance = x}} + +getSecondPassTolerance :: TM PDFFloat +getSecondPassTolerance = gets paraSettings >>= return . secondPassTolerance hunk ./Graphics/PDF/Typesetting.hs 224 -setHyphenPenaltyValue x = modifyStrict $ \s -> s {breakSettings = (breakSettings s){hyphenPenaltyValue = x}} +setHyphenPenaltyValue x = modifyStrict $ \s -> s {paraSettings = (paraSettings s){hyphenPenaltyValue = x}} + +getHyphenPenaltyValue :: TM Int +getHyphenPenaltyValue = gets paraSettings >>= return . hyphenPenaltyValue hunk ./Graphics/PDF/Typesetting.hs 230 -setFitnessDemerit x = modifyStrict $ \s -> s {breakSettings = (breakSettings s){fitness_demerit = x}} +setFitnessDemerit x = modifyStrict $ \s -> s {paraSettings = (paraSettings s){fitness_demerit = x}} + +getFitnessDemerit :: TM PDFFloat +getFitnessDemerit = gets paraSettings >>= return . fitness_demerit hunk ./Graphics/PDF/Typesetting.hs 236 -setHyphenDemerit x = modifyStrict $ \s -> s {breakSettings = (breakSettings s){flagged_demerit = x}} +setHyphenDemerit x = modifyStrict $ \s -> s {paraSettings = (paraSettings s){flagged_demerit = x}} + +getHyphenDemerit :: TM PDFFloat +getHyphenDemerit = gets paraSettings >>= return . flagged_demerit hunk ./Graphics/PDF/Typesetting.hs 242 -setLinePenalty x = modifyStrict $ \s -> s {breakSettings = (breakSettings s){line_penalty = x}} +setLinePenalty x = modifyStrict $ \s -> s {paraSettings = (paraSettings s){line_penalty = x}} hunk ./Graphics/PDF/Typesetting.hs 244 +getLinePenalty :: TM PDFFloat +getLinePenalty = gets paraSettings >>= return . line_penalty + +rlap :: (Show a, DisplayableBox a, Box a) => a -> Para () +rlap a = do + addBox $ HBox 0 (boxHeight a) (boxDescent a) [ SomeHBox (AnyBox a) + , HGlue (- (boxWidth a)) Nothing Nothing + ] + +llap :: (Show a, DisplayableBox a, Box a) => a -> Para () +llap a = do + addBox $ HBox 0 (boxHeight a) (boxDescent a) [ HGlue (- (boxWidth a)) Nothing Nothing + , SomeHBox (AnyBox a) + ] + hunk ./Test/test.hs 208 - let ws = textWidth (PDFFont Times_Roman 10) (toPDFString " ") - h = getHeight (PDFFont Times_Roman 10) - r = 60.0 * ws + let nbLines = 15.0 + r = nbLines * (getHeight . textFont . textStyle $ Normal) hunk ./Test/test.hs 211 - angle l = pasin $ (r - (fromIntegral l) * h ) / r + angle l = pasin $ (nbLines - (fromIntegral l) ) / nbLines hunk ./Test/test.hs 263 - 1 -> displayFormattedText (rectangleArea 10 300 maxw) Normal myText + 1 -> do + strokeColor red + stroke $ Line 10 300 600 300 + displayFormattedText (rectangleArea 10 300 maxw) Normal myText hunk ./Test/test.hs 272 + setLineSkip 0 0 0 + setBaseLineSkip 0 0 0 + setLineSkipLimit 0 hunk ./Test/test.hs 276 - mapM_ (const normalPar) ([1..4]::[Int]) + mapM_ (const normalPar) ([1..3]::[Int]) hunk ./Graphics/PDF/Typesetting/Box.hs 23 + , BoxDimension hunk ./Graphics/PDF/Typesetting/Box.hs 31 +type BoxDimension = (PDFFloat,PDFFloat,PDFFloat) hunk ./Graphics/PDF/Typesetting/Box.hs 93 - -- | Distance between bow bottom and point where the base of the text line is + -- | Distance between box bottom and point where the base of the text line is hunk ./Graphics/PDF/Typesetting/Box.hs 95 + -- | Distance between box top and point where the base of the text line is + boxAscent :: a -> PDFFloat + boxAscent a = boxHeight a - boxDescent a + +instance Box BoxDimension where + boxWidth (w,_,_) = w + boxHeight (_,h,_) = h + boxDescent (_,_,d) = d hunk ./Graphics/PDF/Typesetting/Box.hs 109 - -> PDFFloat -- ^ Vertical position + -> PDFFloat -- ^ Vertical position (top of the box and NOT baseline) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 146 - strokeBox a x y + let h = styleHeight style + d = styleDescent style + y' = y + h - d + strokeBox a x y' hunk ./Graphics/PDF/Typesetting/Horizontal.hs 174 -drawLineOfHboxes :: [HBox] -> PDFFloat -> PDFFloat -> Draw () -drawLineOfHboxes [] _ _ = return () +drawLineOfHboxes :: PDFFloat -- ^ Height of the total line first time this function is called + -> PDFFloat -- ^ Descent of the total line first time this function is called + -> [HBox] -- ^ Remaining box to display + -> PDFFloat -- ^ x for the remaining boxes + -> PDFFloat -- ^ y for the whole line + -> Draw () +drawLineOfHboxes _ _ [] _ _ = return () hunk ./Graphics/PDF/Typesetting/Horizontal.hs 182 -drawLineOfHboxes l@((Text style _ _):_) x y = do +drawLineOfHboxes hl dl l@((Text style _ _):_) x y = do hunk ./Graphics/PDF/Typesetting/Horizontal.hs 185 + -- Position of draw line based upon the whole line and not just this word + y' = y - hl + dl hunk ./Graphics/PDF/Typesetting/Horizontal.hs 188 - w' = foldl' (\x' y' -> x' + boxWidth y') 0.0 l' + w' = foldl' (\x' ny -> x' + boxWidth ny) 0.0 l' hunk ./Graphics/PDF/Typesetting/Horizontal.hs 191 - (fromJust . sentenceStyle $ style) (Rectangle x (y - de) (x+w') (y - de + he)) (drawTextLine style l' x y) + (fromJust . sentenceStyle $ style) (Rectangle x (y' - de) (x+w') (y' - de + he)) (drawTextLine style l' x y') hunk ./Graphics/PDF/Typesetting/Horizontal.hs 193 - drawTextLine style l' x y - drawLineOfHboxes l'' (x + w') y + drawTextLine style l' x y' + drawLineOfHboxes hl dl l'' (x + w') y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 196 -drawLineOfHboxes (a:l) x y = do - strokeBox a x y - drawLineOfHboxes l (x + boxWidth a) y +drawLineOfHboxes hl dl (a:l) x y = do + let h = boxHeight a + d = boxDescent a + -- Compute top of box a + y' = y - hl + dl - d + h + strokeBox a x y' + drawLineOfHboxes hl dl l (x + boxWidth a) y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 262 - strokeBox (HBox _ _ _ l) x y = drawLineOfHboxes l x y + strokeBox a@(HBox _ _ _ l) x y = do + let he = boxHeight a + de = boxDescent a + drawLineOfHboxes he de l x y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 270 + y' = y - he + de hunk ./Graphics/PDF/Typesetting/Horizontal.hs 275 - (fromJust . wordStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) DrawGlue (return ()) + (fromJust . wordStyle $ style) (Rectangle x (y' - de) (x+w) (y' - de + he)) DrawGlue (return ()) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 282 + y' = y - he + de hunk ./Graphics/PDF/Typesetting/Horizontal.hs 287 - (fromJust . wordStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) DrawWord (drawText $ drawTheTextBox OneBlock style x y t) + (fromJust . wordStyle $ style) (Rectangle x (y' - de) (x+w) (y' - de + he)) DrawWord (drawText $ drawTheTextBox OneBlock style x y' t) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 289 - --if (isJust . sentenceStyle $ style) - -- then - -- (fromJust . sentenceStyle $ style) (Rectangle x (y - de) (x+w) (y - de + he)) (drawText $ drawTheTextBox OneBlock style x y t) - -- else - drawText $ drawTheTextBox OneBlock style x y t + drawText $ drawTheTextBox OneBlock style x y' t hunk ./Graphics/PDF/Typesetting/Vertical.hs 176 - strokeBox (SomeVBox a) x y = do - let h = boxHeight a - y' = y + boxDescent a - h - strokeBox a x y' + strokeBox (SomeVBox a) x y = strokeBox a x y hunk ./Test/test.hs 265 - stroke $ Line 10 300 600 300 + stroke $ Line 10 300 (10+maxw) 300 hunk ./Test/test.hs 267 - 2 -> displayFormattedText (rectangleArea 10 300 maxw) Normal debugText + 2 -> do + strokeColor red + stroke $ Line 10 300 (10+maxw) 300 + displayFormattedText (rectangleArea 10 300 maxw) Normal debugText hunk ./Graphics/PDF/Typesetting/Box.hs 24 + , DrawBox + ,mkDrawBox hunk ./Graphics/PDF/Typesetting/Box.hs 32 +import Graphics.PDF.Coordinates + +-- | Make a drawing box +mkDrawBox :: Draw () -> DrawBox +mkDrawBox d = DrawBox d + +-- | A box containing a drawing +newtype DrawBox = DrawBox (Draw()) + +instance Box DrawBox where + boxWidth _ = 0 + boxHeight _ = 0 + boxDescent _ = 0 + +instance DisplayableBox DrawBox where + strokeBox (DrawBox a) x y = do + withNewContext $ do + applyMatrix $ translate x y + a + +instance Show DrawBox where + show _ = "DrawBox" hunk ./Graphics/PDF/Typesetting/Breaking.hs 30 + , mkLetter hunk ./Graphics/PDF/Typesetting/Breaking.hs 40 - - hunk ./Graphics/PDF/Typesetting/Breaking.hs 42 -nullLetter = Letter (AnyBox NullChar) +nullLetter = mkLetter (0,0,0) NullChar Nothing hunk ./Graphics/PDF/Typesetting/Breaking.hs 44 +-- | Make a letter from any box +mkLetter :: (Show a, Box a, DisplayableBox a) => BoxDimension -- ^ Dimension of the box + -> a -- ^ Box + -> Maybe AnyStyle + -> Letter +mkLetter d a s = Letter d (AnyBox a) s hunk ./Graphics/PDF/Typesetting/Breaking.hs 52 -data Letter = Letter !AnyBox -- ^ Any box as a letter +data Letter = Letter BoxDimension !AnyBox !(Maybe AnyStyle) -- ^ Any box as a letter hunk ./Graphics/PDF/Typesetting/Breaking.hs 78 -letterWidth (Letter a) _ = boxWidth a +letterWidth (Letter dim _ _) _ = boxWidth dim hunk ./Graphics/PDF/Typesetting/Breaking.hs 85 - show (Letter a) = "(Letter " ++ show a ++ ")" + show (Letter _ a _) = "(Letter " ++ show a ++ ")" hunk ./Graphics/PDF/Typesetting/Breaking.hs 255 -createBreaknode prev (ZList _ (w,y,z,_,Letter _) _) = BreakNode w y z 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,Letter _ _ _) _) = BreakNode w y z 0.0 False 0 0.0 prev hunk ./Graphics/PDF/Typesetting/Breaking.hs 287 -isFeasibleBreakpoint _ (ZList (OneCB (_,_,_,_,Letter _)) (_,_,_,_,Glue _ _ _ _) _) = True +isFeasibleBreakpoint _ (ZList (OneCB (_,_,_,_,Letter _ _ _)) (_,_,_,_,Glue _ _ _ _) _) = True hunk ./Graphics/PDF/Typesetting/Horizontal.hs 3 --- Copyright : (c) alpha 2006 +-- Copyright : (c) alpha 2006f hunk ./Graphics/PDF/Typesetting/Horizontal.hs 70 -createWords r Nothing ((Letter a):l) = (SomeHBox a):createWords r Nothing l -createWords r (Just (s,t,w)) ((Letter a):l) = (createText s (saveCurrentword $ t) w):(SomeHBox a):createWords r Nothing l +createWords r Nothing ((Letter d a s):l) = (SomeHBox d a s):createWords r Nothing l +createWords r (Just (s,t,w)) ((Letter d a st):l) = (createText s (saveCurrentword $ t) w):(SomeHBox d a st):createWords r Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 102 - | SomeHBox !AnyBox + | SomeHBox !BoxDimension !AnyBox !(Maybe AnyStyle) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 111 -mkHboxWithRatio _ [] = SomeHBox (AnyBox NullChar) +mkHboxWithRatio _ [] = SomeHBox (0,0,0) (AnyBox NullChar) Nothing hunk ./Graphics/PDF/Typesetting/Horizontal.hs 114 - h = maximum . map boxHeight $ l + --h = maximum . map boxHeight $ l + ascent = maximum . map boxAscent $ l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 117 + h = ascent + d hunk ./Graphics/PDF/Typesetting/Horizontal.hs 142 - show (SomeHBox t) = "(SomeHBox " ++ show t ++ ")" + show (SomeHBox _ t _) = "(SomeHBox " ++ show t ++ ")" hunk ./Graphics/PDF/Typesetting/Horizontal.hs 148 - let h = styleHeight style - d = styleDescent style + let h = boxHeight a + d = boxDescent a hunk ./Graphics/PDF/Typesetting/Horizontal.hs 153 - | otherwise = drawText $ drawWords True style l x y + | otherwise = drawWords style l x y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 155 --- | Draw a line of words glue without word style -drawWords :: Bool -> AnyStyle -> [HBox] -> PDFFloat -> PDFFloat -> PDFText() -drawWords False s [] x y = drawTheTextBox StopText s x y (toPDFString "") -drawWords True _ [] _ _ = return () +-- | Draw a line of words, glue, or any box without word style +drawWords :: AnyStyle -> [HBox] -> PDFFloat -> PDFFloat -> Draw () +drawWords _ [] _ _ = return () hunk ./Graphics/PDF/Typesetting/Horizontal.hs 159 -drawWords True s ((Text _ t w):l) x y = do - drawTheTextBox StartText s x y t - drawWords False s l (x + w) y - -drawWords False s ((Text _ t w):l) x y = do - drawTheTextBox ContinueText s x y t - drawWords False s l (x + w) y +drawWords s ((Text _ t w):l) x y = do + (l',x') <- drawText $ do + drawTheTextBox StartText s x y (Just t) + drawPureWords s l (x + w) y + drawWords s l' x' y + +drawWords s l@((HGlue _ _ _ ):_) x y = do + (l',x') <- drawText $ do + drawTheTextBox StartText s x y Nothing + drawPureWords s l x y + drawWords s l' x' y + +drawWords s (a@(SomeHBox _ _ _):l) x y = do + let h = boxHeight a + d = boxDescent a + w = boxWidth a + y' = y - d + h + strokeBox a x y' + drawWords s l (x + w) y + +drawWords _ _ _ _ = return () + +-- | Draw only words and glues using PDF text commands +drawPureWords :: AnyStyle -> [HBox] -> PDFFloat -> PDFFloat -> PDFText ([HBox],PDFFloat) + +drawPureWords s [] x y = do + drawTheTextBox StopText s x y Nothing + return ([],x) + +drawPureWords s ((Text _ t w):l) x y = do + drawTheTextBox ContinueText s x y (Just t) + drawPureWords s l (x + w) y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 192 -drawWords False s ((HGlue w _ _):l) x y = do +drawPureWords s ((HGlue w _ _):l) x y = do hunk ./Graphics/PDF/Typesetting/Horizontal.hs 194 - drawWords False s l (x + w) y + drawPureWords s l (x + w) y + +drawPureWords s l@((SomeHBox _ _ _):_) x y = do + drawTheTextBox StopText s x y Nothing + return (l,x) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 200 -drawWords True _ _ _ _ = return () -drawWords False _ _ _ _ = return () +drawPureWords s (_:l) x y = drawPureWords s l x y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 212 - let de = styleDescent style - he = styleHeight style hunk ./Graphics/PDF/Typesetting/Horizontal.hs 213 - y' = y - hl + dl + let y' = y - hl + dl hunk ./Graphics/PDF/Typesetting/Horizontal.hs 218 - (fromJust . sentenceStyle $ style) (Rectangle x (y' - de) (x+w') (y' - de + he)) (drawTextLine style l' x y') + (fromJust . sentenceStyle $ style) (Rectangle x (y - hl) (x+w') (y)) (drawTextLine style l' x y') hunk ./Graphics/PDF/Typesetting/Horizontal.hs 234 - boxWidth (SomeHBox a) = boxWidth a + boxWidth (SomeHBox d _ _) = boxWidth d hunk ./Graphics/PDF/Typesetting/Horizontal.hs 239 - boxHeight (SomeHBox a) = boxHeight a + boxHeight (SomeHBox d _ _) = boxHeight d + boxHeight (HGlue _ _ (Just s)) = styleHeight s hunk ./Graphics/PDF/Typesetting/Horizontal.hs 245 - boxDescent (SomeHBox a) = boxDescent a + boxDescent (SomeHBox d _ _) = boxDescent d + boxDescent (HGlue _ _ (Just s)) = styleDescent s hunk ./Graphics/PDF/Typesetting/Horizontal.hs 255 - -> PDFString + -> Maybe PDFString hunk ./Graphics/PDF/Typesetting/Horizontal.hs 267 - tell $ toPDF t) + case t of + Nothing -> return () + Just myText -> tell $ toPDF myText + ) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 299 - strokeBox (HGlue w _ (Just style)) x y = do - let de = styleDescent style - he = styleHeight style + strokeBox a@(HGlue w _ (Just style)) x y = do + let de = boxDescent a + he = boxHeight a hunk ./Graphics/PDF/Typesetting/Horizontal.hs 311 - strokeBox (Text style t w) x y = do - let de = styleDescent style - he = styleHeight style + strokeBox a@(Text style t w) x y = do + let de = boxDescent a + he = boxHeight a hunk ./Graphics/PDF/Typesetting/Horizontal.hs 319 - (fromJust . wordStyle $ style) (Rectangle x (y' - de) (x+w) (y' - de + he)) DrawWord (drawText $ drawTheTextBox OneBlock style x y' t) + (fromJust . wordStyle $ style) (Rectangle x (y' - de) (x+w) (y' - de + he)) DrawWord (drawText $ drawTheTextBox OneBlock style x y' (Just t)) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 321 - drawText $ drawTheTextBox OneBlock style x y' t + drawText $ drawTheTextBox OneBlock style x y' (Just t) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 323 - strokeBox (SomeHBox a) x y = strokeBox a x y + strokeBox (SomeHBox _ a _) x y = strokeBox a x y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 332 +isSameStyle s (SomeHBox _ _ (Just style)) = styleCode s == styleCode style hunk ./Graphics/PDF/Typesetting.hs 31 + , mkDrawBox hunk ./Graphics/PDF/Typesetting.hs 52 - , rlap - , llap hunk ./Graphics/PDF/Typesetting.hs 60 -import Graphics.PDF.Typesetting.Horizontal hunk ./Graphics/PDF/Typesetting.hs 127 - addBox :: (Show a, DisplayableBox a, Box a) => a -> m () + addBox :: (Show a, DisplayableBox a, Box a) => a -> PDFFloat -> PDFFloat -> PDFFloat -> m () hunk ./Graphics/PDF/Typesetting.hs 138 - addBox a = TM . tell $ ([SomeVBox (AnyBox a)]) + addBox a _ _ _ = TM . tell $ ([SomeVBox (AnyBox a)]) hunk ./Graphics/PDF/Typesetting.hs 141 - glue w y z = addBox $ vglue w y z + glue w y z = addBox (vglue w y z) w 0 0 hunk ./Graphics/PDF/Typesetting.hs 151 - addBox a = tell ([Letter (AnyBox a)]) + addBox a w h d = do + f <- currentStyle + addLetter . mkLetter (w,h,d) a $ (Just f) hunk ./Graphics/PDF/Typesetting.hs 169 +-- | Add a letter to the paragraph +addLetter :: Letter -> Para () +addLetter l = tell [l] hunk ./Graphics/PDF/Typesetting.hs 250 -rlap :: (Show a, DisplayableBox a, Box a) => a -> Para () -rlap a = do - addBox $ HBox 0 (boxHeight a) (boxDescent a) [ SomeHBox (AnyBox a) - , HGlue (- (boxWidth a)) Nothing Nothing - ] - -llap :: (Show a, DisplayableBox a, Box a) => a -> Para () -llap a = do - addBox $ HBox 0 (boxHeight a) (boxDescent a) [ HGlue (- (boxWidth a)) Nothing Nothing - , SomeHBox (AnyBox a) - ] hunk ./Test/test.hs 111 +data BlueStyle = BlueStyle deriving(Eq) hunk ./Test/test.hs 218 +instance Style BlueStyle where + sentenceStyle _ = Just $ \r d -> do + fillColor $ Rgb 0.6 0.6 1 + fill r + d + return() + wordStyle _ = Nothing + textStyle _ = TextStyle (PDFFont Times_Roman 10) black black FillText 1.0 1.0 1.0 1.0 + styleCode _ = 7 + updateStyle = id + hunk ./Test/test.hs 231 - let debugText = do + let symbol = mkDrawBox $ do + applyMatrix $ translate 0 (-5) + strokeColor red + fillColor red + fillAndStroke $ Polygon [ (0,0) + , (5,5) + , (10,0) + , (0,0) + ] + strokeColor blue + fillColor blue + fillAndStroke $ Polygon [ (0,0) + , (5,-5) + , (10,0) + , (0,0) + ] + strokeColor red + stroke $ Rectangle 0 (-5) 10 5 + debugText = do hunk ./Test/test.hs 283 - mapM_ (const (paragraph par)) ([1..4]::[Int]) + paragraph normalPar + setStyle BlueStyle + paragraph $ do + txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + txt $ "Ut enim ad minim veniam, quis nostrud exercitation ull" + kern 3 + addBox symbol 10 10 5 + kern 3 + txt $ "amco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor " + txt $ "in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, " + txt $ "sunt in culpa qui officia deserunt mollit anim id est laborum." + setStyle Normal + paragraph normalPar + paragraph normalPar hunk ./Test/test.hs 394 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = True}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = False}) rect $ do hunk ./Graphics/PDF/Typesetting/Breaking.hs 450 -formatList settings fmaxw boxes = +formatList settings maxw boxes = hunk ./Graphics/PDF/Typesetting/Breaking.hs 452 - theBreaks = analyzeBoxes settings False fmaxw active (createZList boxes) + theBreaks = analyzeBoxes settings False maxw active (createZList boxes) hunk ./Graphics/PDF/Typesetting/Vertical.hs 15 - , TextArea(..) hunk ./Graphics/PDF/Typesetting/Vertical.hs 21 + , ParagraphStyle(..) + , AnyParagraphStyle(..) hunk ./Graphics/PDF/Typesetting/Vertical.hs 29 +import Graphics.PDF.Shapes(Rectangle(..)) hunk ./Graphics/PDF/Typesetting/Vertical.hs 33 -data VerState = VerState { baselineskipW :: !PDFFloat - , baselineskipY :: !PDFFloat - , baselineskipZ :: !PDFFloat - , lineskip :: !VBox - , lineskiplimit :: !PDFFloat} +import Debug.Trace + + +debug a = trace (show a) a + +data VerState = VerState { baselineskip :: !(PDFFloat,PDFFloat,PDFFloat) + , lineskip :: !(PDFFloat,PDFFloat,PDFFloat) + , lineskiplimit :: !PDFFloat + , paraStyle :: !AnyParagraphStyle + } hunk ./Graphics/PDF/Typesetting/Vertical.hs 44 -defaultVerState :: VerState -defaultVerState = VerState { baselineskipW = 12 - , baselineskipY = 0.17 - , baselineskipZ = 0.0 - , lineskip = vglue 3.0 0.33 0.0 - , lineskiplimit = 2 - } +defaultVerState :: ParagraphStyle s => s -> VerState +defaultVerState s = VerState { baselineskip = (12,0.17,0.0) + , lineskip = (3.0,0.33,0.0) + , lineskiplimit = 2 + , paraStyle = AnyParagraphStyle s + } hunk ./Graphics/PDF/Typesetting/Vertical.hs 53 -data TextArea = TextArea (Int -> PDFFloat) PDFFloat (Int -> PDFFloat) hunk ./Graphics/PDF/Typesetting/Vertical.hs 54 -data VBox = Paragraph [Letter] - | VBox !PDFFloat !PDFFloat !PDFFloat ![VBox] - | VGlue !PDFFloat !(Maybe (PDFFloat,PDFFloat)) !(Maybe AnyStyle) - | SomeVBox !AnyBox +data VBox = Paragraph [Letter] !(Maybe AnyParagraphStyle) + | VBox !PDFFloat !PDFFloat !PDFFloat ![VBox] !(Maybe AnyParagraphStyle) + | VGlue !PDFFloat !(Maybe (PDFFloat,PDFFloat)) !(Maybe AnyParagraphStyle) + | SomeVBox !PDFFloat !BoxDimension !AnyBox !(Maybe AnyParagraphStyle) hunk ./Graphics/PDF/Typesetting/Vertical.hs 59 -vglue :: PDFFloat +vglue :: Maybe AnyParagraphStyle + -> PDFFloat hunk ./Graphics/PDF/Typesetting/Vertical.hs 64 -vglue w y z = VGlue w (Just(y,z)) Nothing +vglue s w y z = VGlue w (Just(y,z)) s hunk ./Graphics/PDF/Typesetting/Vertical.hs 67 - show (VBox _ _ _ a) = "(HBox " ++ show a ++ ")" + show (VBox _ _ _ a _) = "(HBox " ++ show a ++ ")" hunk ./Graphics/PDF/Typesetting/Vertical.hs 69 - show (Paragraph _) = "(Paragraph)" - show (SomeVBox t) = "(SomeHBox " ++ show t ++ ")" + show (Paragraph _ _) = "(Paragraph)" + show (SomeVBox _ _ t _) = "(SomeHBox " ++ show t ++ ")" hunk ./Graphics/PDF/Typesetting/Vertical.hs 78 -mkVboxWithRatio _ [] = SomeVBox (AnyBox NullChar) +mkVboxWithRatio _ [] = SomeVBox 0.0 (0,0,0) (AnyBox NullChar) Nothing hunk ./Graphics/PDF/Typesetting/Vertical.hs 83 - addBox (VGlue gw (Just(y,z)) s) (VBox w' h' d' l') = VBox w' h' d' (VGlue (glueWidth gw y z r) Nothing s:l') - addBox a (VBox w' h' d' l') = VBox w' h' d' (a:l') + addBox (VGlue gw (Just(y,z)) s) (VBox w' h' d' l' s') = VBox w' h' d' (VGlue (glueWidth gw y z r) Nothing s:l') s' + addBox a (VBox w' h' d' l' s') = VBox w' h' d' (a:l') s' hunk ./Graphics/PDF/Typesetting/Vertical.hs 88 - foldr addBox (VBox w h d []) l + foldr addBox (VBox w h d [] Nothing) l hunk ./Graphics/PDF/Typesetting/Vertical.hs 94 --- | Force width of text area to positive value -onlyPositive :: (Int -> PDFFloat) -> (Int -> PDFFloat) -onlyPositive f = \l -> let w = f l in - if w <= 0 - then - error $ "One of your line width is negative or null at line " ++ (show l) - else - w - --- | Shift origin for the text area -shiftBy :: Int -> (Int -> PDFFloat) -> (Int -> PDFFloat) -shiftBy o f = \x -> f (x + o) - hunk ./Graphics/PDF/Typesetting/Vertical.hs 96 -toVBoxes :: [HBox] -- ^ List of lines +toVBoxes :: Maybe AnyParagraphStyle + -> PDFFloat -- ^ Max width + -> [HBox] -- ^ List of lines hunk ./Graphics/PDF/Typesetting/Vertical.hs 100 -toVBoxes = map createVBox +toVBoxes Nothing _ l = map createVBox l + where + createVBox a = SomeVBox 0.0 (boxWidth a,boxHeight a,boxDescent a) (AnyBox a) Nothing + +toVBoxes s@(Just style) w l = map createVBoxAndAddKern $ zip [1..] l hunk ./Graphics/PDF/Typesetting/Vertical.hs 106 - createVBox = SomeVBox . AnyBox + createVBoxAndAddKern (nb,a) = + let delta = (linePositions style) w nb + in + SomeVBox delta (boxWidth a,boxHeight a,boxDescent a) (AnyBox a) s hunk ./Graphics/PDF/Typesetting/Vertical.hs 114 - -> TextArea -- ^ Text area + -> Rectangle -- ^ Text area hunk ./Graphics/PDF/Typesetting/Vertical.hs 118 -createVBoxes paraSettings o t@(TextArea _ _ fmaxw) ((Paragraph l):l') = - let fl = formatList paraSettings (onlyPositive . shiftBy o $ fmaxw) l +createVBoxes paraSettings o rect@(Rectangle xa _ xb _) ((Paragraph l style):l') = + let fl = case style of + Nothing -> formatList paraSettings (const $ xb-xa) l + Just aStyle -> formatList paraSettings (\nb -> (lineWidths aStyle) (xb-xa) nb ) l hunk ./Graphics/PDF/Typesetting/Vertical.hs 123 - (toVBoxes . horizontalPostProcess $ fl) ++ createVBoxes paraSettings (o + length fl) t l' -createVBoxes paraSettings o t (a:l') = a:createVBoxes paraSettings (o+1) t l' + (toVBoxes style (xb - xa) . horizontalPostProcess $ fl) ++ createVBoxes paraSettings (o + length fl) rect l' +createVBoxes paraSettings o rect (a:l') = a:createVBoxes paraSettings (o+1) rect l' hunk ./Graphics/PDF/Typesetting/Vertical.hs 128 - -> TextArea -- ^ Text area + -> Rectangle -- ^ Text area hunk ./Graphics/PDF/Typesetting/Vertical.hs 131 -verticalPostProcess (pageSettings,paraSettings) i t l = addInterlineGlue pageSettings . createVBoxes paraSettings i t $ l +verticalPostProcess (pageSettings,paraSettings) i rect l = addInterlineGlue pageSettings . createVBoxes paraSettings i rect $ l hunk ./Graphics/PDF/Typesetting/Vertical.hs 136 -notGlue (Paragraph _) = False +notGlue (Paragraph _ _) = False hunk ./Graphics/PDF/Typesetting/Vertical.hs 139 +-- | Get the required style for the interline glue +getInterlineStyle :: VBox -> VBox -> Maybe AnyParagraphStyle +getInterlineStyle (VBox _ _ _ _ (Just s)) (SomeVBox _ _ _ (Just s')) | paraStyleCode s == paraStyleCode s' = Just s + | otherwise = Nothing + +getInterlineStyle (VBox _ _ _ _ (Just s)) (VBox _ _ _ _ (Just s')) | paraStyleCode s == paraStyleCode s' = Just s + | otherwise = Nothing + +getInterlineStyle (SomeVBox _ _ _ (Just s)) (SomeVBox _ _ _ (Just s')) | paraStyleCode s == paraStyleCode s' = Just s + | otherwise = Nothing + +getInterlineStyle (SomeVBox _ _ _ (Just s)) (VBox _ _ _ _ (Just s')) | paraStyleCode s == paraStyleCode s' = Just s + | otherwise = Nothing + +getInterlineStyle _ _ = Nothing + hunk ./Graphics/PDF/Typesetting/Vertical.hs 161 - ba = baselineskipW settings + (ba,by,bz) = baselineskip settings + (lw,ly,lz) = lineskip settings hunk ./Graphics/PDF/Typesetting/Vertical.hs 164 + istyle = getInterlineStyle a b hunk ./Graphics/PDF/Typesetting/Vertical.hs 172 - a:(vglue (ba-p-h) (baselineskipY settings) (baselineskipZ settings)):addInterlineGlue settings (b:l) + a:(vglue istyle (ba-p-h) by bz):addInterlineGlue settings (b:l) hunk ./Graphics/PDF/Typesetting/Vertical.hs 174 - a:(lineskip settings):addInterlineGlue settings (b:l) + a:(vglue istyle lw ly lz):addInterlineGlue settings (b:l) hunk ./Graphics/PDF/Typesetting/Vertical.hs 178 - boxWidth (Paragraph _) = 0 - boxWidth (VBox _ _ _ _) = 0 - boxWidth (SomeVBox _) = 0 + boxWidth (Paragraph _ _) = 0 + boxWidth (VBox w _ _ _ _) = w + boxWidth (SomeVBox _ d _ _) = boxWidth d hunk ./Graphics/PDF/Typesetting/Vertical.hs 183 - boxHeight (Paragraph _) = 0 - boxHeight (VBox _ h _ _) = h - boxHeight (SomeVBox a) = boxHeight a + boxHeight (Paragraph _ _) = 0 + boxHeight (VBox _ h _ _ _) = h + boxHeight (SomeVBox _ d _ _) = boxHeight d hunk ./Graphics/PDF/Typesetting/Vertical.hs 188 - boxDescent (Paragraph _) = 0 - boxDescent (VBox _ _ d _) = d - boxDescent (SomeVBox a) = boxDescent a + boxDescent (Paragraph _ _) = 0 + boxDescent (VBox _ _ d _ _) = d + boxDescent (SomeVBox _ d _ _) = boxDescent d hunk ./Graphics/PDF/Typesetting/Vertical.hs 194 - strokeBox (Paragraph _) _ _ = return () - strokeBox (VBox _ _ _ l) x y = strokeVBoxes l (const x) y + strokeBox (Paragraph _ _) _ _ = return () + strokeBox b@(VBox _ _ _ l _) x y'' = strokeVBoxes l (x,y',y'') + where + y' = y'' - boxHeight b hunk ./Graphics/PDF/Typesetting/Vertical.hs 200 - strokeBox (SomeVBox a) x y = strokeBox a x y + strokeBox (SomeVBox delta _ a _) x y = strokeBox a (x+delta) y hunk ./Graphics/PDF/Typesetting/Vertical.hs 205 - -> (Int -> PDFFloat) -- ^ x - -> PDFFloat -- ^ y + -> (PDFFloat,PDFFloat,PDFFloat) hunk ./Graphics/PDF/Typesetting/Vertical.hs 207 -strokeVBoxes b fx y'' = recurseStrokeVBoxes 1 b y'' +strokeVBoxes b (xa,y',y'') = recurseStrokeVBoxes 1 b y'' hunk ./Graphics/PDF/Typesetting/Vertical.hs 209 + recurseStrokeVBoxes :: Int -> [VBox] -> PDFFloat -> Draw () hunk ./Graphics/PDF/Typesetting/Vertical.hs 211 - recurseStrokeVBoxes _ (Paragraph _:_) _ = return () + recurseStrokeVBoxes _ (Paragraph _ _:_) _ = return () hunk ./Graphics/PDF/Typesetting/Vertical.hs 216 - strokeBox a (fx nb) y - recurseStrokeVBoxes (nb+1) l (y - h) + strokeBox a xa y + if y - h >= y' + then + recurseStrokeVBoxes (nb+1) l (y - h) + else + return () + +class ParagraphStyle a where + lineWidths :: a -> PDFFloat -> Int -> PDFFloat + linePositions :: a -> PDFFloat -> Int -> PDFFloat + paraStyleCode :: a -> Int + +data AnyParagraphStyle = forall a . ParagraphStyle a => AnyParagraphStyle a + +instance ParagraphStyle AnyParagraphStyle where + lineWidths (AnyParagraphStyle a) = lineWidths a + linePositions (AnyParagraphStyle a) = linePositions a + paraStyleCode (AnyParagraphStyle a) = paraStyleCode a + + hunk ./Graphics/PDF/Typesetting.hs 22 + , ParagraphStyle(..) + , AnyParagraphStyle(..) hunk ./Graphics/PDF/Typesetting.hs 27 - , TM - , Para +-- , TM +-- , Para hunk ./Graphics/PDF/Typesetting.hs 34 - , TextArea(..) - , rectangleArea hunk ./Graphics/PDF/Typesetting.hs 52 + , getParaStyle + , setParaStyle + , endParagraph hunk ./Graphics/PDF/Typesetting.hs 60 +import Graphics.PDF.Shapes hunk ./Graphics/PDF/Typesetting.hs 66 -rectangleArea :: PDFFloat -- ^ x - -> PDFFloat -- ^ y - -> PDFFloat -- ^ w - -> TextArea -- ^ Text area -rectangleArea x y w = TextArea (const x) y (const w) - ---import Debug.Trace - ---debug s x = trace (show s ++ " : " ++ show x) x - - hunk ./Graphics/PDF/Typesetting.hs 67 -displayFormattedText :: Style s => TextArea -- ^ Text area - -> s -- ^ Default style +displayFormattedText :: (Style s, ParagraphStyle s') => Rectangle -- ^ Text area + -> s' -- ^ default vertical style + -> s -- ^ Default horizontal style hunk ./Graphics/PDF/Typesetting.hs 72 -displayFormattedText area@(TextArea fx y _) defaultStyle t = do - let (a, s', boxes) = (runRWS . unTM $ t >>= \x' -> do {return x'} ) () (defaultTmState defaultStyle) - strokeVBoxes (verticalPostProcess (pageSettings s',paraSettings s') 0 area boxes) fx y - return a +displayFormattedText area@(Rectangle xa y' xb y'') defaultVStyle defaultHStyle t = + withNewContext $ do + addShape $ Rectangle (xa-1) y' (xb+1) y'' + closePath + setAsClipPath + let (a, s', boxes) = (runRWS . unTM $ t >>= \x' -> do {return x'} ) () (defaultTmState defaultVStyle defaultHStyle) + strokeVBoxes (verticalPostProcess (pageSettings s',paraSettings s') 0 area boxes) (xa,y',y'') + return a hunk ./Graphics/PDF/Typesetting.hs 90 -defaultTmState :: Style s => s -> TMState -defaultTmState s = TMState { tmStyle = AnyStyle s - , paraSettings = defaultBreakingSettings - , pageSettings = defaultVerState - } +defaultTmState :: (Style s, ParagraphStyle s') => s' -> s -> TMState +defaultTmState s' s = TMState { tmStyle = AnyStyle s + , paraSettings = defaultBreakingSettings + , pageSettings = defaultVerState s' + } hunk ./Graphics/PDF/Typesetting.hs 136 - addBox a _ _ _ = TM . tell $ ([SomeVBox (AnyBox a)]) + addBox a w h d = do + style <- getParaStyle + tell $ ([SomeVBox 0 (w,h,d) (AnyBox a) (Just style)]) hunk ./Graphics/PDF/Typesetting.hs 141 - glue w y z = addBox (vglue w y z) w 0 0 + glue w y z = do + style <- getParaStyle + tell $ [vglue (Just style) w y z] hunk ./Graphics/PDF/Typesetting.hs 168 - tell $ [Paragraph boxes] + style <- getParaStyle + tell $ [Paragraph boxes (Just style)] hunk ./Graphics/PDF/Typesetting.hs 171 + +getParaStyle :: TM AnyParagraphStyle +getParaStyle = gets pageSettings >>= TM . return . paraStyle + +setParaStyle :: ParagraphStyle s => s -> TM () +setParaStyle style = do + modifyStrict $ \s -> s {pageSettings = (pageSettings s){paraStyle = AnyParagraphStyle style}} hunk ./Graphics/PDF/Typesetting.hs 205 -setBaseLineSkip w y z = modifyStrict $ \s -> s {pageSettings = (pageSettings s){baselineskipW = w,baselineskipY=y,baselineskipZ=z}} +setBaseLineSkip w y z = modifyStrict $ \s -> s {pageSettings = (pageSettings s){baselineskip = (w,y,z)}} hunk ./Graphics/PDF/Typesetting.hs 210 - return (baselineskipW s,baselineskipY s,baselineskipZ s) + return (baselineskip s) hunk ./Graphics/PDF/Typesetting.hs 219 -setLineSkip w y z = modifyStrict $ \s -> s {pageSettings = (pageSettings s){lineskip = vglue w y z}} +setLineSkip w y z = modifyStrict $ \s -> s {pageSettings = (pageSettings s){lineskip = (w,y,z)}} hunk ./Graphics/PDF/Typesetting.hs 221 -getLineSkip :: TM VBox +getLineSkip :: TM (PDFFloat,PDFFloat,PDFFloat) hunk ./Graphics/PDF.hs 178 + , (PDFName "Producer",AnyPdfObject $ toPDFString "HPDF - The Haskell PDF Library" ) hunk ./Test/test.hs 20 + hunk ./Test/test.hs 203 - -triangleArea :: PDFFloat -> PDFFloat -> TextArea -triangleArea x y = let ws = textWidth (PDFFont Times_Roman 10) (toPDFString " ") in - TextArea (\l -> x + 300.0 - ws * 5.0 * (fromIntegral (l-1))) y (\l -> ws*10.0 + 10.0*ws*(fromIntegral (l-1))) - -circleArea :: PDFFloat -> PDFFloat -> TextArea -circleArea x y = - let nbLines = 15.0 - r = nbLines * (getHeight . textFont . textStyle $ Normal) - pasin x' = if x' >= 1.0 then pi/2 else if x' <= -1.0 then (-pi/2) else asin x' - angle l = pasin $ (nbLines - (fromIntegral l) ) / nbLines - xpos l = x - r * cos (angle l) - width l = 2*r*cos (angle l) - in - TextArea xpos y width + +instance ParagraphStyle Normal where + lineWidths _ w _ = w + linePositions _ _ = const 0.0 + paraStyleCode _ = 1 hunk ./Test/test.hs 209 +data CirclePara = CirclePara deriving(Eq) + +instance ParagraphStyle CirclePara where + lineWidths _ _ nb = + let nbLines = 15.0 + r = nbLines * (getHeight . textFont . textStyle $ Normal) + pasin x' = if x' >= 1.0 then pi/2 else if x' <= -1.0 then (-pi/2) else asin x' + angle l = pasin $ (nbLines - (fromIntegral l) ) / nbLines + in + abs(2*r*cos (angle nb)) + linePositions a w nb = max 0 ((w - lineWidths a w nb) / 2.0) + paraStyleCode _ = 2 + hunk ./Test/test.hs 313 - displayFormattedText (rectangleArea 10 300 maxw) Normal myText + displayFormattedText (Rectangle 10 0 (10+maxw) 300) Normal Normal myText hunk ./Test/test.hs 317 - displayFormattedText (rectangleArea 10 300 maxw) Normal debugText - 3 -> displayFormattedText (circleArea 300 350) Normal $ do + displayFormattedText (Rectangle 10 0 (10+maxw) 300) Normal Normal debugText + 3 -> do + let r = (Rectangle 10 200 (10+maxw) 300) + displayFormattedText r CirclePara Normal $ do hunk ./Test/test.hs 331 - _ -> displayFormattedText (rectangleArea 10 300 maxw) Normal myText + strokeColor red + stroke r + _ -> displayFormattedText ((Rectangle 0 300 (10+maxw) 300)) Normal Normal myText hunk ./Test/test.hs 402 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = False}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = True}) rect $ do hunk ./Graphics/PDF/Typesetting/Box.hs 80 + sentenceStyle _ = Nothing hunk ./Graphics/PDF/Typesetting/Box.hs 84 + wordStyle _ = Nothing hunk ./Graphics/PDF/Typesetting/Box.hs 90 + updateStyle = id hunk ./Graphics/PDF/Typesetting/Breaking.hs 42 -nullLetter = mkLetter (0,0,0) NullChar Nothing +nullLetter = mkLetter (0,0,0) Nothing NullChar hunk ./Graphics/PDF/Typesetting/Breaking.hs 46 - -> a -- ^ Box hunk ./Graphics/PDF/Typesetting/Breaking.hs 47 + -> a -- ^ Box hunk ./Graphics/PDF/Typesetting/Breaking.hs 49 -mkLetter d a s = Letter d (AnyBox a) s +mkLetter d s a = Letter d (AnyBox a) s hunk ./Graphics/PDF/Typesetting/Breaking.hs 51 --- | A letter which can be anything +-- | A letter which can be anything. Sizes are widths and for glue the dilation and compression factors +-- For the generic letter, height and descent are also provided hunk ./Graphics/PDF/Typesetting/Breaking.hs 190 -data BRState = BRState { firstPassTolerance :: !PDFFloat - , secondPassTolerance :: !PDFFloat - , hyphenPenaltyValue :: !Int - , fitness_demerit :: !PDFFloat - , flagged_demerit :: !PDFFloat - , line_penalty :: !PDFFloat +data BRState = BRState { firstPassTolerance :: !PDFFloat -- ^ Default value 100 + , secondPassTolerance :: !PDFFloat -- ^ Default value 200 + , hyphenPenaltyValue :: !Int -- ^ Default value 50 + , fitness_demerit :: !PDFFloat -- ^ Default value 10000 + , flagged_demerit :: !PDFFloat -- ^ Default value 10000 + , line_penalty :: !PDFFloat -- ^ Default value 10 hunk ./Graphics/PDF/Typesetting/Horizontal.hs 202 +-- When a start of line is detected by drawLineOfHBoxes, we start the drawing +startDrawingNewLineOfText :: PDFFloat -> PDFFloat -> [HBox] -> PDFFloat -> PDFFloat -> AnyStyle -> Draw () +startDrawingNewLineOfText hl dl l x y style = + do + -- Position of draw line based upon the whole line and not just this word + let y' = y - hl + dl + (l',l'') = span (isSameStyle style) l + w' = foldl' (\x' ny -> x' + boxWidth ny) 0.0 l' + if (isJust . sentenceStyle $ style) + then do + (fromJust . sentenceStyle $ style) (Rectangle x (y - hl) (x+w') (y)) (drawTextLine style l' x y') + else do + drawTextLine style l' x y' + drawLineOfHboxes hl dl l'' (x + w') y + hunk ./Graphics/PDF/Typesetting/Horizontal.hs 226 -drawLineOfHboxes hl dl l@((Text style _ _):_) x y = do - -- Position of draw line based upon the whole line and not just this word - let y' = y - hl + dl - (l',l'') = span (isSameStyle style) l - w' = foldl' (\x' ny -> x' + boxWidth ny) 0.0 l' - if (isJust . sentenceStyle $ style) - then do - (fromJust . sentenceStyle $ style) (Rectangle x (y - hl) (x+w') (y)) (drawTextLine style l' x y') - else do - drawTextLine style l' x y' - drawLineOfHboxes hl dl l'' (x + w') y - +drawLineOfHboxes hl dl l@((Text style _ _):_) x y = startDrawingNewLineOfText hl dl l x y style +drawLineOfHboxes hl dl l@((HGlue _ _ (Just style)):_) x y = startDrawingNewLineOfText hl dl l x y style + hunk ./Graphics/PDF/Typesetting/Vertical.hs 2 --- | +-- |f hunk ./Graphics/PDF/Typesetting/Vertical.hs 32 +import Data.Maybe(isJust,fromJust) hunk ./Graphics/PDF/Typesetting/Vertical.hs 34 -import Debug.Trace - - -debug a = trace (show a) a - -data VerState = VerState { baselineskip :: !(PDFFloat,PDFFloat,PDFFloat) - , lineskip :: !(PDFFloat,PDFFloat,PDFFloat) - , lineskiplimit :: !PDFFloat +data VerState = VerState { baselineskip :: !(PDFFloat,PDFFloat,PDFFloat) -- ^ Default value (12,0.17,0.0) + , lineskip :: !(PDFFloat,PDFFloat,PDFFloat) -- ^ Default value (3.0,0.33,0.0) + , lineskiplimit :: !PDFFloat -- ^ Default value 2 hunk ./Graphics/PDF/Typesetting/Vertical.hs 50 -data VBox = Paragraph [Letter] !(Maybe AnyParagraphStyle) +data VBox = Paragraph [Letter] !(Maybe AnyParagraphStyle) !BRState hunk ./Graphics/PDF/Typesetting/Vertical.hs 52 - | VGlue !PDFFloat !(Maybe (PDFFloat,PDFFloat)) !(Maybe AnyParagraphStyle) + | VGlue !PDFFloat !PDFFloat !PDFFloat !(Maybe (PDFFloat,PDFFloat)) !(Maybe AnyParagraphStyle) hunk ./Graphics/PDF/Typesetting/Vertical.hs 56 - -> PDFFloat - -> PDFFloat - -> PDFFloat + -> PDFFloat -- ^ Glue height + -> PDFFloat -- ^ Glue dilatation factor + -> PDFFloat -- ^ Glue compression factor + -> PDFFloat -- ^ Glue width + -> PDFFloat -- ^ Glue delta hunk ./Graphics/PDF/Typesetting/Vertical.hs 62 -vglue s w y z = VGlue w (Just(y,z)) s +vglue s h y z width delta = VGlue h width delta (Just(y,z)) s hunk ./Graphics/PDF/Typesetting/Vertical.hs 66 - show (VGlue a _ _) = "(HGlue " ++ show a ++ ")" - show (Paragraph _ _) = "(Paragraph)" + show (VGlue a _ _ _ _) = "(HGlue " ++ show a ++ ")" + show (Paragraph _ _ _) = "(Paragraph)" hunk ./Graphics/PDF/Typesetting/Vertical.hs 81 - addBox (VGlue gw (Just(y,z)) s) (VBox w' h' d' l' s') = VBox w' h' d' (VGlue (glueWidth gw y z r) Nothing s:l') s' + addBox (VGlue gw gh gdelta (Just(y,z)) s) (VBox w' h' d' l' s') = VBox w' h' d' (VGlue (glueWidth gw y z r) gh gdelta Nothing s:l') s' hunk ./Graphics/PDF/Typesetting/Vertical.hs 89 - boxWidthWithRatio (VGlue w (Just(y,z)) _) r = glueWidth w y z r + boxWidthWithRatio (VGlue w _ _ (Just(y,z)) _) r = glueWidth w y z r hunk ./Graphics/PDF/Typesetting/Vertical.hs 102 -toVBoxes s@(Just style) w l = map createVBoxAndAddKern $ zip [1..] l +toVBoxes s@(Just style) w l = map createVBoxAndAddKern $ zip [1..] (l ) hunk ./Graphics/PDF/Typesetting/Vertical.hs 109 --- | Create VBoxes. Paragraphs are analyzd and cut into VBoxes -createVBoxes :: BRState +-- | Create VBoxes. Paragraphs are analyzed and cut into VBoxes. The pragraph style is updated and used +-- to transform the list of letters +verticalPostProcess :: VerState hunk ./Graphics/PDF/Typesetting/Vertical.hs 116 -createVBoxes _ _ _ [] = [] -createVBoxes paraSettings o rect@(Rectangle xa _ xb _) ((Paragraph l style):l') = - let fl = case style of - Nothing -> formatList paraSettings (const $ xb-xa) l - Just aStyle -> formatList paraSettings (\nb -> (lineWidths aStyle) (xb-xa) nb ) l +verticalPostProcess _ _ _ [] = [] +verticalPostProcess pageSettings o rect@(Rectangle xa _ xb _) ((Paragraph l style paraSettings):l') = + let (fl,newStyle) = case style of + Nothing -> (formatList paraSettings (const $ xb-xa) l,Nothing) + Just aStyle -> let (style',nl) = paraChange aStyle l + in + (formatList paraSettings (\nb -> (lineWidths style') (xb-xa) nb ) nl,Just style') hunk ./Graphics/PDF/Typesetting/Vertical.hs 124 - (toVBoxes style (xb - xa) . horizontalPostProcess $ fl) ++ createVBoxes paraSettings (o + length fl) rect l' -createVBoxes paraSettings o rect (a:l') = a:createVBoxes paraSettings (o+1) rect l' - -verticalPostProcess :: (VerState,BRState) - -> Int -- ^ Line offset for the text area - -> Rectangle -- ^ Text area - -> [VBox] -- ^ List of VBox with paragraphs - -> [VBox] -- ^ List of VBox where paragraphs have been line broken -verticalPostProcess (pageSettings,paraSettings) i rect l = addInterlineGlue pageSettings . createVBoxes paraSettings i rect $ l + (addInterlineGlue pageSettings . toVBoxes newStyle (xb - xa) . horizontalPostProcess $ fl) ++ verticalPostProcess pageSettings (o + length fl) rect l' +verticalPostProcess pageSettings o rect (a:l') = a:verticalPostProcess pageSettings (o+1) rect l' hunk ./Graphics/PDF/Typesetting/Vertical.hs 129 -notGlue (VGlue _ _ _) = False -notGlue (Paragraph _ _) = False +notGlue (VGlue _ _ _ _ _) = False +notGlue (Paragraph _ _ _) = False hunk ./Graphics/PDF/Typesetting/Vertical.hs 149 +-- | Get the delta used to position a box with non rectangular shapes +getBoxDelta :: VBox -> PDFFloat +getBoxDelta (Paragraph _ _ _) = 0.0 +getBoxDelta (VBox _ _ _ _ _) = 0.0 +getBoxDelta (VGlue _ _ delta _ _) = delta +getBoxDelta (SomeVBox delta _ _ _) = delta + hunk ./Graphics/PDF/Typesetting/Vertical.hs 166 + theWidth = boxWidth a + theDelta = getBoxDelta a hunk ./Graphics/PDF/Typesetting/Vertical.hs 175 - a:(vglue istyle (ba-p-h) by bz):addInterlineGlue settings (b:l) + a:(vglue istyle (ba-p-h) by bz theWidth theDelta):addInterlineGlue settings (b:l) hunk ./Graphics/PDF/Typesetting/Vertical.hs 177 - a:(vglue istyle lw ly lz):addInterlineGlue settings (b:l) + a:(vglue istyle lw ly lz theWidth theDelta):addInterlineGlue settings (b:l) hunk ./Graphics/PDF/Typesetting/Vertical.hs 181 - boxWidth (Paragraph _ _) = 0 + boxWidth (Paragraph _ _ _) = 0 hunk ./Graphics/PDF/Typesetting/Vertical.hs 184 - boxWidth (VGlue _ _ _) = 0 + boxWidth (VGlue _ w _ _ _) = w hunk ./Graphics/PDF/Typesetting/Vertical.hs 186 - boxHeight (Paragraph _ _) = 0 + boxHeight (Paragraph _ _ _) = 0 hunk ./Graphics/PDF/Typesetting/Vertical.hs 189 - boxHeight (VGlue w _ _) = w + boxHeight (VGlue h _ _ _ _) = h hunk ./Graphics/PDF/Typesetting/Vertical.hs 191 - boxDescent (Paragraph _ _) = 0 + boxDescent (Paragraph _ _ _) = 0 hunk ./Graphics/PDF/Typesetting/Vertical.hs 194 - boxDescent (VGlue _ _ _) = 0 + boxDescent (VGlue _ _ _ _ _) = 0 hunk ./Graphics/PDF/Typesetting/Vertical.hs 197 - strokeBox (Paragraph _ _) _ _ = return () + strokeBox (Paragraph _ _ _) _ _ = return () hunk ./Graphics/PDF/Typesetting/Vertical.hs 201 - strokeBox (VGlue _ _ _) _ _ = return () + strokeBox (VGlue h w delta _ (Just style)) x y = + if (isJust . interline $ style) + then + (fromJust . interline $ style) $ Rectangle (x+delta) (y-h) (x+w+delta) y + else + return() + strokeBox (VGlue _ _ _ _ _) _ _ = return () hunk ./Graphics/PDF/Typesetting/Vertical.hs 220 - recurseStrokeVBoxes _ (Paragraph _ _:_) _ = return () - recurseStrokeVBoxes nb (a@(VGlue _ _ _):l) y = recurseStrokeVBoxes nb l (y-(boxHeight a)) + recurseStrokeVBoxes _ (Paragraph _ _ _:_) _ = return () + recurseStrokeVBoxes nb (a@(VGlue _ _ _ _ _):l) y = do + let h = boxHeight a + strokeBox a xa y + if y - h >= y' + then + recurseStrokeVBoxes nb l (y-h) + else + return () hunk ./Graphics/PDF/Typesetting/Vertical.hs 243 + interline :: a -> Maybe (Rectangle -> Draw ()) + interline _ = Nothing + lineWidths _ w _ = w + linePositions _ _ = const 0.0 + paraChange :: a -> [Letter] -> (a,[Letter]) + paraChange a l = (a,l) hunk ./Graphics/PDF/Typesetting/Vertical.hs 256 - - + interline (AnyParagraphStyle a) = interline a + paraChange (AnyParagraphStyle a) l = let (a',l') = paraChange a l in (AnyParagraphStyle a',l') hunk ./Graphics/PDF/Typesetting.hs 30 + , Letter(..) hunk ./Graphics/PDF/Typesetting.hs 35 + , mkLetter hunk ./Graphics/PDF/Typesetting.hs 57 + , getTextArea hunk ./Graphics/PDF/Typesetting.hs 75 -displayFormattedText area@(Rectangle xa y' xb y'') defaultVStyle defaultHStyle t = - withNewContext $ do - addShape $ Rectangle (xa-1) y' (xb+1) y'' - closePath - setAsClipPath - let (a, s', boxes) = (runRWS . unTM $ t >>= \x' -> do {return x'} ) () (defaultTmState defaultVStyle defaultHStyle) - strokeVBoxes (verticalPostProcess (pageSettings s',paraSettings s') 0 area boxes) (xa,y',y'') +displayFormattedText area@(Rectangle xa y' _ y'') defaultVStyle defaultHStyle t = + do + --withNewContext $ do + -- addShape $ Rectangle (xa-1) y' (xb+1) y'' + -- closePath + -- setAsClipPath + let (a, s', boxes) = (runRWS . unTM $ t >>= \x' -> do {return x'} ) area (defaultTmState defaultVStyle defaultHStyle) + strokeVBoxes (verticalPostProcess (pageSettings s') 0 area boxes) (xa,y',y'') hunk ./Graphics/PDF/Typesetting.hs 93 + +-- | Get the rectangle containing the text +getTextArea :: TM Rectangle +getTextArea = ask hunk ./Graphics/PDF/Typesetting.hs 109 -newtype TM a = TM { unTM :: RWS () [VBox] TMState a} +newtype TM a = TM { unTM :: RWS Rectangle [VBox] TMState a} hunk ./Graphics/PDF/Typesetting.hs 111 - deriving(Monad,MonadWriter [VBox], MonadState TMState, Functor) + deriving(Monad,MonadWriter [VBox], MonadState TMState, MonadReader Rectangle, Functor) hunk ./Graphics/PDF/Typesetting.hs 117 +instance MonadReader Rectangle TM hunk ./Graphics/PDF/Typesetting.hs 150 - glue w y z = do + glue h y z = do hunk ./Graphics/PDF/Typesetting.hs 152 - tell $ [vglue (Just style) w y z] + Rectangle xa _ xb _ <- getTextArea + tell $ [vglue (Just style) h y z (xb-xa) 0] hunk ./Graphics/PDF/Typesetting.hs 165 - addLetter . mkLetter (w,h,d) a $ (Just f) + addLetter . mkLetter (w,h,d) (Just f) $ a hunk ./Graphics/PDF/Typesetting.hs 179 - tell $ [Paragraph boxes (Just style)] + tell $ [Paragraph boxes (Just style) settings] hunk ./Test/test.hs 115 - sentenceStyle _ = Nothing - wordStyle _ = Nothing hunk ./Test/test.hs 117 - updateStyle = id hunk ./Test/test.hs 119 - sentenceStyle _ = Nothing - wordStyle _ = Nothing hunk ./Test/test.hs 121 - updateStyle = id hunk ./Test/test.hs 128 - wordStyle _ = Nothing hunk ./Test/test.hs 130 - updateStyle = id hunk ./Test/test.hs 132 - sentenceStyle _ = Nothing hunk ./Test/test.hs 138 - updateStyle = id hunk ./Test/test.hs 159 - updateStyle = id hunk ./Test/test.hs 168 - sentenceStyle _ = Nothing hunk ./Test/test.hs 193 - lineWidths _ w _ = w - linePositions _ _ = const 0.0 hunk ./Test/test.hs 196 +data BluePara = BluePara PDFFloat deriving(Eq) + +instance ParagraphStyle BluePara where + paraStyleCode _ = 3 + lineWidths (BluePara a) w nb = if nb > 3 then w else w-a + linePositions (BluePara a) _ nb = if nb > 3 then 0.0 else a + interline _ = Just $ \r -> do + fillColor $ Rgb 0.6 0.6 1 + strokeColor $ Rgb 0.6 0.6 1 + fillAndStroke r + paraChange s [] = (s,[]) + paraChange _ (AChar st c _:l) = + let f = PDFFont Helvetica_Bold 45 + w' = charWidth f c + charRect = Rectangle 0 (- getDescent f) w' (getHeight f - getDescent f) + c' = mkLetter (0,0,0) Nothing . mkDrawBox $ do + withNewContext $ do + applyMatrix $ translate (-w') (getDescent f - getHeight f + styleHeight st - styleDescent st) + fillColor $ Rgb 0.6 0.6 1 + strokeColor $ Rgb 0.6 0.6 1 + fillAndStroke $ charRect + fillColor black + drawText $ do + renderMode AddToClip + textStart 0 0 + setFont f + displayText (toPDFString [c]) + paintWithShading (AxialShading 0 (- getDescent f) w' (getHeight f - getDescent f) (Rgb 1 0 0) (Rgb 0 0 1)) (addShape charRect) + in + (BluePara w', c':l) + paraChange s l = (s,l) hunk ./Test/test.hs 242 - fill r + strokeColor $ Rgb 0.6 0.6 1 + fillAndStroke r hunk ./Test/test.hs 246 - wordStyle _ = Nothing hunk ./Test/test.hs 248 - updateStyle = id hunk ./Test/test.hs 251 - let symbol = mkDrawBox $ do - applyMatrix $ translate 0 (-5) - strokeColor red - fillColor red - fillAndStroke $ Polygon [ (0,0) - , (5,5) - , (10,0) - , (0,0) - ] - strokeColor blue - fillColor blue - fillAndStroke $ Polygon [ (0,0) - , (5,-5) - , (10,0) - , (0,0) - ] - strokeColor red - stroke $ Rectangle 0 (-5) 10 5 + let --symbol = mkDrawBox $ do + -- applyMatrix $ translate 0 (-4) + -- strokeColor red + -- fillColor red + -- fillAndStroke $ Polygon [ (0,0) + -- , (5,5) + -- , (10,0) + -- , (0,0) + -- ] + -- strokeColor blue + -- fillColor blue + -- fillAndStroke $ Polygon [ (0,0) + -- , (5,-5) + -- , (10,0) + -- , (0,0) + -- ] hunk ./Test/test.hs 277 + glue 3 0 0 hunk ./Test/test.hs 285 + glue 3 0 0 hunk ./Test/test.hs 304 + glue 3 0 0 hunk ./Test/test.hs 306 + setParaStyle (BluePara 0) + setFirstPassTolerance 5000 + setSecondPassTolerance 10000 hunk ./Test/test.hs 311 - txt $ "Ut enim ad minim veniam, quis nostrud exercitation ull" - kern 3 - addBox symbol 10 10 5 - kern 3 - txt $ "amco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor " + txt $ "Ut enim ad minim veniam, quis nostrud exercitation ullamco " + --addBox symbol 10 10 5 + txt $ " laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor " hunk ./Test/test.hs 316 + setFirstPassTolerance 100 + setSecondPassTolerance 200 hunk ./Test/test.hs 319 + setParaStyle Normal + glue 3 0 0 hunk ./Test/test.hs 322 + glue 3 0 0 hunk ./Graphics/PDF/Demo.hs 1 ---------------------------------------------------------- --- | --- Copyright : (c) alpha 2007 --- License : BSD-style --- --- Maintainer : misc@NOSPAMalpheccar.org --- Stability : experimental --- Portability : portable --- --- PDF demo. Generate a file demo.pdf ---------------------------------------------------------- -module Graphics.PDF.Demo(demo) where - -import Graphics.PDF - -fontDebug :: PDFFont -> PDFString -> Draw () -fontDebug f t = do - drawText $ do - setFont f - textStart 10 200.0 - leading $ getHeight f - renderMode FillText - displayText t - startNewLine - displayText $ toPDFString "Another little test" - strokeColor $ Rgb 1 0 0 - stroke $ Line 10 200 612 200 - fill $ Circle 10 200 10 - stroke $ Rectangle 10 (200.0 - (getDescent f)) (10.0 + textWidth f t) (200.0 - getDescent f + getHeight f) - - -geometryTest :: Draw () -geometryTest = do - strokeColor red - stroke $ Rectangle 0 0 200 100 - fillColor blue - fill $ Ellipse 100 100 300 200 - fillAndStroke $ RoundRectangle 32 32 200 200 600 400 - -lineStyle ::Draw () -lineStyle = do - withNewContext $ do - setWidth 2 - setDash $ DashPattern [3] 0 - geometryTest - - -shadingTest :: Draw () -shadingTest = do - paintWithShading (RadialShading 0 0 50 0 0 600 (Rgb 1 0 0) (Rgb 0 0 1)) (addShape $ Rectangle 0 0 300 300) - paintWithShading (AxialShading 300 300 600 400 (Rgb 1 0 0) (Rgb 0 0 1)) (addShape $ Ellipse 300 300 600 400) - - -patternTest :: PDFReference PDFPage -> PDF () -patternTest page = do - p <- createUncoloredTiling 0 0 100 50 100 50 ConstantSpacing pattern - cp <- createColoredTiling 0 0 100 50 100 50 ConstantSpacing cpattern - drawWithPage page $ do - strokeColor green - setUncoloredFillPattern p (Rgb 1 0 0) - fillAndStroke $ Ellipse 0 0 300 300 - setColoredFillPattern cp - fillAndStroke $ Ellipse 300 300 600 400 - - where - myDrawing = do - stroke (Line 0 0 100 100) - fill (Rectangle 100 100 200 200) - pattern = do - stroke (Ellipse 0 0 100 50) - cpattern = do - strokeColor (Rgb 0 0 1) - stroke (Ellipse 0 0 100 50) - -testAnnotation :: Draw () -testAnnotation = do - strokeColor red - newAnnotation (URLLink (toPDFString "Go to my blog") [0,0,100,100] "http://www.alpheccar.org" True) - drawText $ text (PDFFont Times_Roman 12) 10 30 (toPDFString "Go to my blog") - stroke $ Rectangle 0 0 100 100 - newAnnotation (TextAnnotation (toPDFString "Key annotation") [100,100,130,130] Key) - -textTest :: Draw () -textTest = do - strokeColor red - fillColor blue - fontDebug (PDFFont Times_Roman 48) (toPDFString "This is a test !") - - ---testImage :: FilePath -> PDFReference PDFPage -> PDF () ---testImage logo page = do --- Right jpg <- createPDFJpeg logo --- drawWithPage page $ do --- withNewContext $ do --- setFillAlpha 0.4 --- drawXObject jpg --- withNewContext $ do --- applyMatrix $ rotate (Degree 20) --- applyMatrix $ translate 200 200 --- applyMatrix $ scale 2 2 --- drawXObject jpg - -testAll :: FilePath -> PDF () -testAll logo = do - page <- addPage Nothing - newSection (toPDFString "Shapes") Nothing Nothing $ do - - newSection (toPDFString "Geometry") Nothing Nothing $ do - drawWithPage page $ do - geometryTest - - page <- addPage Nothing - newSection (toPDFString "Line style") Nothing Nothing $ do - drawWithPage page $ do - lineStyle - page <- addPage Nothing - newSection (toPDFString "Object reuse") Nothing Nothing $ do - r <- createPDFXForm 0 0 200 200 lineStyle - drawWithPage page $ do - drawXObject r - - page <- addPage Nothing - newSectionWithPage (toPDFString "Painting") Nothing Nothing page $ do - newSection (toPDFString "Patterns") Nothing Nothing $ do - patternTest page - page <- addPage Nothing - newSection (toPDFString "Shading") Nothing Nothing $ do - drawWithPage page $ do - shadingTest - page <- addPage Nothing - --newSection (toPDFString "Media") Nothing Nothing $ do - -- newSection (toPDFString "image") Nothing Nothing $ do - -- testImage logo page - - page <- addPage Nothing - newSection (toPDFString "Annotations") Nothing Nothing $ do - drawWithPage page $ do - testAnnotation - page <- addPage Nothing - newSection (toPDFString "Text") Nothing Nothing $ do - drawWithPage page $ do - textTest - - --- | Run the demo and create a demo.pdf file -demo :: IO() -demo = do - let rect = PDFRect 0 0 600 400 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString $ "alpheccar"}) rect $ do - testAll "" - + rmfile ./Graphics/PDF/Demo.hs hunk ./Graphics/PDF/Typesetting.hs 131 +-- | A MonadStyle where some typesetting operators can be used hunk ./Graphics/PDF/Typesetting.hs 133 + -- | Set the current text style hunk ./Graphics/PDF/Typesetting.hs 135 + + -- | Get the current text style hunk ./Graphics/PDF/Typesetting.hs 138 - addBox :: (Show a, DisplayableBox a, Box a) => a -> PDFFloat -> PDFFloat -> PDFFloat -> m () - glue :: PDFFloat -> PDFFloat -> PDFFloat -> m () + + -- | Add a box using the current mode (horizontal or vertical) + addBox :: (Show a, DisplayableBox a, Box a) => a + -> PDFFloat -- ^ Width + -> PDFFloat -- ^ Height + -> PDFFloat -- ^ Descent + -> m () + + -- | Add a glue using the current style + glue :: PDFFloat -- ^ Size of glue (width or height depending on the mode) + -> PDFFloat -- ^ Dilatation factor + -> PDFFloat -- ^ Compression factor + -> m () + + -- | Add a glue with no style (it is just a translation) + unstyledGlue :: PDFFloat -- ^ Size of glue (width or height depending on the mode) + -> PDFFloat -- ^ Dilatation factor + -> PDFFloat -- ^ Compression factor + -> m () + hunk ./Graphics/PDF/Typesetting.hs 176 + + -- | Add a glue + unstyledGlue h y z = do + Rectangle xa _ xb _ <- getTextArea + tell $ [vglue Nothing h y z (xb-xa) 0] hunk ./Graphics/PDF/Typesetting.hs 198 + + -- | Add a glue + unstyledGlue w y z = do + tell $ [glueBox Nothing w y z] hunk ./HPDF.cabal 44 - Graphics.PDF.Demo hunk ./Graphics/PDF/Typesetting/Vertical.hs 2 --- |f +-- | hunk ./Graphics/PDF/Typesetting/Vertical.hs 210 - + +isSameParaStyle :: AnyParagraphStyle -> VBox -> Bool +isSameParaStyle s (Paragraph _ (Just s') _) = paraStyleCode s == paraStyleCode s' +isSameParaStyle s (VBox _ _ _ _ (Just s')) = paraStyleCode s == paraStyleCode s' +isSameParaStyle s (VGlue _ _ _ _ (Just s')) = paraStyleCode s == paraStyleCode s' +isSameParaStyle s (SomeVBox _ _ _ (Just s')) = paraStyleCode s == paraStyleCode s' +isSameParaStyle _ _ = False + +recurseStrokeVBoxes :: Int -> [VBox] -> (PDFFloat,PDFFloat,PDFFloat) -> Draw () +recurseStrokeVBoxes _ [] _ = return () +recurseStrokeVBoxes _ (Paragraph _ _ _:_) _ = return () +recurseStrokeVBoxes nb (a@(VGlue _ _ _ _ _):l) (xa,y',y) = do + let h = boxHeight a + strokeBox a xa y + if y - h >= y' + then + recurseStrokeVBoxes nb l (xa,y',(y-h)) + else + return () + +recurseStrokeVBoxes nb (a:l) (xa,y',y) = do + let h = boxHeight a + strokeBox a xa y + if y - h >= y' + then + recurseStrokeVBoxes (nb+1) l (xa,y',(y-h)) + else + return () + +drawWithParaStyle :: AnyParagraphStyle -> [VBox] -> (PDFFloat,PDFFloat,PDFFloat) -> Draw () +drawWithParaStyle style b (xa,y',y'') = do + let (l',l'') = span (isSameParaStyle style) b + h' = foldl' (\x' ny -> x' + boxHeight ny) 0.0 l' + if (isJust . paragraphStyle $ style) + then do + let xleft = (minimum $ 100000:map getBoxDelta l' ) + xa + xright = (maximum $ 0:(map (\x -> boxWidth x + getBoxDelta x) l')) + xa + (fromJust . paragraphStyle $ style) (Rectangle xleft (y''- h') xright (y'')) (recurseStrokeVBoxes 1 l' (xa,y',y'')) + else + recurseStrokeVBoxes 1 l' (xa,y',y'') + strokeVBoxes l'' (xa,y',y''-h') hunk ./Graphics/PDF/Typesetting/Vertical.hs 256 -strokeVBoxes b (xa,y',y'') = recurseStrokeVBoxes 1 b y'' - where - recurseStrokeVBoxes :: Int -> [VBox] -> PDFFloat -> Draw () - recurseStrokeVBoxes _ [] _ = return () - recurseStrokeVBoxes _ (Paragraph _ _ _:_) _ = return () - recurseStrokeVBoxes nb (a@(VGlue _ _ _ _ _):l) y = do +strokeVBoxes [] (_,_,_) = return () +strokeVBoxes b@((Paragraph _ (Just s') _):_) (xa,y',y'') = drawWithParaStyle s' b (xa,y',y'') +strokeVBoxes b@((VBox _ _ _ _ (Just s')):_) (xa,y',y'') = drawWithParaStyle s' b (xa,y',y'') +strokeVBoxes b@((VGlue _ _ _ _ (Just s')):_) (xa,y',y'') = drawWithParaStyle s' b (xa,y',y'') +strokeVBoxes b@((SomeVBox _ _ _ (Just s')):_) (xa,y',y'') = drawWithParaStyle s' b (xa,y',y'') +strokeVBoxes (a:l) (xa,y',y'') = + do hunk ./Graphics/PDF/Typesetting/Vertical.hs 264 - strokeBox a xa y - if y - h >= y' + strokeBox a xa y'' + if y'' - h >= y' hunk ./Graphics/PDF/Typesetting/Vertical.hs 267 - recurseStrokeVBoxes nb l (y-h) + strokeVBoxes l (xa,y',(y''-h)) hunk ./Graphics/PDF/Typesetting/Vertical.hs 269 - return () - - recurseStrokeVBoxes nb (a:l) y = do - let h = boxHeight a - strokeBox a xa y - if y - h >= y' - then - recurseStrokeVBoxes (nb+1) l (y - h) - else - return () - + return () + + hunk ./Graphics/PDF/Typesetting/Vertical.hs 282 + paragraphStyle :: a -> Maybe (Rectangle -> Draw b -> Draw ()) + paragraphStyle _ = Nothing hunk ./Graphics/PDF/Typesetting/Vertical.hs 293 + paragraphStyle (AnyParagraphStyle a) = paragraphStyle a hunk ./Graphics/PDF/Typesetting.hs 32 - , penalty + , addPenalty hunk ./Graphics/PDF/Typesetting.hs 85 -endParagraphBoxes :: [Letter] -endParagraphBoxes = [glueBox Nothing 0 10000.0 0,penalty (-infinity)] - --- | End the current paragraph -endParagraph :: a -> Para a +--endParagraphBoxes :: [Letter] +--endParagraphBoxes = [glueBox Nothing 0 10000.0 0,penalty (-infinity)] + +-- | Add a penalty +addPenalty :: Int -> Para() +addPenalty f = tell $ [penalty f] + +-- | End the current paragraph with our without using the shame style +endParagraph :: Bool -- ^ True if we use the same style to end a paragraph. false for an invisible styl + -> Para () hunk ./Graphics/PDF/Typesetting.hs 96 - tell endParagraphBoxes - return r + if r + then + glue 0 10000.0 0 + else + tell $ [glueBox Nothing 0 10000.0 0] + addPenalty (-infinity) hunk ./Graphics/PDF/Typesetting.hs 169 - -- | Set style of text + -- Set style of text hunk ./Graphics/PDF/Typesetting.hs 172 - -- | Get current text style + -- Get current text style hunk ./Graphics/PDF/Typesetting.hs 175 - -- | Add a box to the stream in vertical mode + -- Add a box to the stream in vertical mode hunk ./Graphics/PDF/Typesetting.hs 180 - -- | Add a glue + -- Add a glue hunk ./Graphics/PDF/Typesetting.hs 186 - -- | Add a glue + -- Add a glue hunk ./Graphics/PDF/Typesetting.hs 192 - -- | Set style of text + -- Set style of text hunk ./Graphics/PDF/Typesetting.hs 195 - -- | Get current text style + -- Get current text style hunk ./Graphics/PDF/Typesetting.hs 198 - -- | Add a box to the stream in horizontal mode + -- Add a box to the stream in horizontal mode hunk ./Graphics/PDF/Typesetting.hs 203 - -- | Add a glue + -- Add a glue hunk ./Graphics/PDF/Typesetting.hs 208 - -- | Add a glue + -- Add a glue hunk ./Graphics/PDF/Typesetting.hs 216 - let (a, s', boxes) = (runRWS . unPara $ (m >>= endParagraph) ) settings f + let (a, s', boxes) = (runRWS . unPara $ closedPara ) settings f hunk ./Graphics/PDF/Typesetting.hs 221 + where + closedPara = do + x <- m + endParagraph False + return x hunk ./Test/test.hs 200 - lineWidths (BluePara a) w nb = if nb > 3 then w else w-a - linePositions (BluePara a) _ nb = if nb > 3 then 0.0 else a + lineWidths (BluePara a) w nb = (if nb > 3 then w else w-a) - 20.0 + linePositions (BluePara a) _ nb = (if nb > 3 then 0.0 else a) + 10.0 hunk ./Test/test.hs 227 - + paragraphStyle _ = Just $ \(Rectangle xa ya xb yb) b -> do + let f = Rectangle (xa-3) (ya-3) (xb+3) (yb+3) + fillColor $ Rgb 0.6 0.6 1 + fill f + b + strokeColor red + stroke f + return () + hunk ./Test/test.hs 317 + unstyledGlue 3 0 0 hunk ./Test/test.hs 325 + unstyledGlue 3 0 0 hunk ./Graphics/PDF/Image.hs 244 --- | Create a PDF XObject for a JPEG image +-- | Read a JPEG file and return an abstract description of its content or an error hunk ./Graphics/PDF/Image.hs 258 +-- | Use an abstract description of a Jpeg to return a PDFReference that can be used to manipulate the Jpeg in the context +-- of the PDF document hunk ./Graphics/PDF/Typesetting/Box.hs 34 --- | Make a drawing box +-- | Make a drawing box. A box object containing a Draw value hunk ./Graphics/PDF/Typesetting/Box.hs 38 --- | A box containing a drawing +-- | A box containing a Draw value hunk ./Graphics/PDF/Typesetting/Box.hs 55 +-- | Dimension of a box : width, height and descent hunk ./Graphics/PDF/Typesetting/Box.hs 76 --- | Style of text +-- | Style of text (sentences and words) hunk ./Graphics/PDF/Typesetting/Box.hs 80 - -> Maybe (Rectangle -> Draw b -> Draw ()) -- ^ Function receiving the bounding rectangle and the commands drawing the sentence + -> Maybe (Rectangle -> Draw b -> Draw ()) -- ^ Function receiving the bounding rectangle and the command for drawing the sentence hunk ./Graphics/PDF/Typesetting/Box.hs 101 +-- | Any sentence style hunk ./Graphics/PDF/Typesetting/Box.hs 115 --- | A box with dimensions +-- | A box is an object with dimensions and used in the typesetting process hunk ./Graphics/PDF/Typesetting/Box.hs 119 - -> PDFFloat -- ^ Width with adjustement + -> PDFFloat -- ^ Width of the box + hunk ./Graphics/PDF/Typesetting/Box.hs 123 - -- | Distance between box bottom and point where the base of the text line is + -- | Distance between box bottom and box baseline hunk ./Graphics/PDF/Typesetting/Box.hs 125 - -- | Distance between box top and point where the base of the text line is + -- | Distance between box top and box baseline hunk ./Graphics/PDF/Typesetting/Box.hs 136 - -- | Draw a bow + -- | Draw a box hunk ./Graphics/PDF/Typesetting/Breaking.hs 46 - -> Maybe AnyStyle + -> Maybe AnyStyle -- ^ Text style of the box (can use t) hunk ./Graphics/PDF/Typesetting/Vertical.hs 271 - +-- | Paragraph style hunk ./Graphics/PDF/Typesetting/Vertical.hs 273 - lineWidths :: a -> PDFFloat -> Int -> PDFFloat - linePositions :: a -> PDFFloat -> Int -> PDFFloat - paraStyleCode :: a -> Int - interline :: a -> Maybe (Rectangle -> Draw ()) + lineWidths :: a -> PDFFloat -> Int -> PDFFloat -- ^ Width of the line of the paragraph + linePositions :: a -> PDFFloat -> Int -> PDFFloat -- ^ Horizontal shift of the line position relatively to the left egde of the paragraph bounding box + paraStyleCode :: a -> Int -- ^ All paragraph styles used in a document must have different codes + interline :: a -> Maybe (Rectangle -> Draw ()) -- ^ How to style the interline glues added in a paragraph by the line breaking algorithm hunk ./Graphics/PDF/Typesetting/Vertical.hs 280 - paraChange :: a -> [Letter] -> (a,[Letter]) + paraChange :: a -> [Letter] -> (a,[Letter]) -- ^ Change the content of a paragraph before the line breaking algorithm is run. It may also change the style hunk ./Graphics/PDF/Typesetting/Vertical.hs 282 - paragraphStyle :: a -> Maybe (Rectangle -> Draw b -> Draw ()) + paragraphStyle :: a -> Maybe (Rectangle -> Draw b -> Draw ()) -- ^ Get the paragraph bounding box and the paragraph draw command to apply additional effects hunk ./Graphics/PDF/Typesetting/Vertical.hs 285 +-- | Any paragraph style hunk ./Graphics/PDF/Typesetting.hs 10 --- Typesetting --- Work in progress +-- Experimental typesetting. It is a work in progress hunk ./Graphics/PDF/Typesetting.hs 15 + -- ** Types hunk ./Graphics/PDF/Typesetting.hs 23 - , AnyParagraphStyle(..) + , AnyParagraphStyle + , MonadStyle(..) + , Letter(..) + , BoxDimension + -- * Functions + -- ** Text display hunk ./Graphics/PDF/Typesetting.hs 30 + -- ** Text construction operators + , endParagraph hunk ./Graphics/PDF/Typesetting.hs 34 --- , TM --- , Para - , MonadStyle(..) - , Letter(..) + -- * Paragraph construction operators hunk ./Graphics/PDF/Typesetting.hs 37 - , nullChar - , mkDrawBox +-- , nullChar hunk ./Graphics/PDF/Typesetting.hs 39 + -- * Misc + , mkDrawBox + -- * Settings (similar to TeX ones) + -- ** Line breaking settings hunk ./Graphics/PDF/Typesetting.hs 49 - , setBaseLineSkip - , setLineSkipLimit - , setLineSkip hunk ./Graphics/PDF/Typesetting.hs 55 + -- ** Vertical mode settings + , setBaseLineSkip + , setLineSkipLimit + , setLineSkip hunk ./Graphics/PDF/Typesetting.hs 62 + -- * Styles + -- ** Functions useful to change the paragraph style hunk ./Graphics/PDF/Typesetting.hs 66 - , endParagraph hunk ./Graphics/PDF/Typesetting.hs 78 --- | Display a formatted text at a given position with a given default style +-- | Display a formatted text in a given bounding rectangle with a given default paragraph style, a given default text style. No clipping +-- is taking place. Drawing stop when the last line is crossing the bounding rectangle in vertical direction hunk ./Graphics/PDF/Typesetting.hs 102 --- | End the current paragraph with our without using the shame style -endParagraph :: Bool -- ^ True if we use the same style to end a paragraph. false for an invisible styl +-- | End the current paragraph with or without using the same style +endParagraph :: Bool -- ^ True if we use the same style to end a paragraph. false for an invisible style hunk ./Graphics/PDF/Typesetting.hs 113 --- | Get the rectangle containing the text +-- | Get the bounding rectangle containing the text hunk ./Graphics/PDF/Typesetting.hs 158 - -- | Add a box using the current mode (horizontal or vertical) + -- | Add a box using the current mode (horizontal or vertical. The current style is always applied to the added box) hunk ./Graphics/PDF/Typesetting.hs 237 +-- | Get the current paragraph style hunk ./Graphics/PDF/Typesetting.hs 241 +-- | Change the current paragraph style hunk ./Graphics/PDF/Typesetting.hs 248 -addLetter l = tell [l] +addLetter l = Para . tell $ [l] hunk ./Graphics/PDF/Typesetting.hs 255 -nullChar :: Para () -nullChar = Para . tell $ [nullLetter] +--nullChar :: Para () +--nullChar = Para . tell $ [nullLetter] hunk ./Graphics/PDF/Typesetting.hs 265 --- | add a kern +-- | add a kern (space that can be dilated or compressed and on which no line breaking can occur) hunk ./HPDF.cabal 9 -homepage: http://www.alpheccar.org/en/posts/show/80 +tested-with: GHC==6.6 +homepage: http://www.alpheccar.org/en/posts/show/82 hunk ./HPDF.cabal 14 -description: A PDF library allowing to generate multipage PDF documents with outlines, links ... +description: A PDF library with support for several pages, page transitions, outlines, annotations, compression, colors, shapes, patterns, jpegs, fonts, typesetting ... hunk ./Graphics/PDF/Typesetting/Horizontal.hs 103 - + +-- | Change the style of the box +withNewStyle :: AnyStyle -> HBox -> HBox +withNewStyle _ a@(HBox _ _ _ _) = a +withNewStyle s (HGlue a b _) = HGlue a b (Just s) +withNewStyle s (Text _ a b) = Text s a b +withNewStyle s (SomeHBox d a _) = SomeHBox d a (Just s) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 157 - strokeBox a x y' - drawTextLine style l' (x + boxWidth a) y + strokeBox (withNewStyle style a) x y' + drawTextLine (updateStyle style) l' (x + boxWidth a) y hunk ./Graphics/PDF/Typesetting/Vertical.hs 105 - let delta = (linePositions style) w nb + let delta = (linePosition style) w nb hunk ./Graphics/PDF/Typesetting/Vertical.hs 122 - (formatList paraSettings (\nb -> (lineWidths style') (xb-xa) nb ) nl,Just style') + (formatList paraSettings (\nb -> (lineWidth style') (xb-xa) nb ) nl,Just style') hunk ./Graphics/PDF/Typesetting/Vertical.hs 273 - lineWidths :: a -> PDFFloat -> Int -> PDFFloat -- ^ Width of the line of the paragraph - linePositions :: a -> PDFFloat -> Int -> PDFFloat -- ^ Horizontal shift of the line position relatively to the left egde of the paragraph bounding box - paraStyleCode :: a -> Int -- ^ All paragraph styles used in a document must have different codes - interline :: a -> Maybe (Rectangle -> Draw ()) -- ^ How to style the interline glues added in a paragraph by the line breaking algorithm + -- | Width of the line of the paragraph + lineWidth :: a -- ^ The style + -> PDFFloat -- ^ Width of the text area used by the typesetting algorithm + -> Int -- ^ Line number + -> PDFFloat -- ^ Line width + + -- | Horizontal shift of the line position relatively to the left egde of the paragraph bounding box + linePosition :: a -- ^ The style + -> PDFFloat -- ^ Width of the text area used by the typesetting algorithm + -> Int -- ^ Line number + -> PDFFloat -- ^ Horizontal offset from the left edge of the text area + + -- | All paragraph styles used in a document must have different codes + paraStyleCode :: a -- ^ The style + -> Int -- ^ Code identifying the style + + -- | How to style the interline glues added in a paragraph by the line breaking algorithm + interline :: a -- ^ The style + -> Maybe (Rectangle -> Draw ()) -- ^ Function used to style interline glues hunk ./Graphics/PDF/Typesetting/Vertical.hs 293 - lineWidths _ w _ = w - linePositions _ _ = const 0.0 - paraChange :: a -> [Letter] -> (a,[Letter]) -- ^ Change the content of a paragraph before the line breaking algorithm is run. It may also change the style + lineWidth _ w _ = w + linePosition _ _ = const 0.0 + + -- | Change the content of a paragraph before the line breaking algorithm is run. It may also change the style + paraChange :: a -- ^ The style + -> [Letter] -- ^ List of letters in the paragraph + -> (a,[Letter]) -- ^ Update style and list of letters hunk ./Graphics/PDF/Typesetting/Vertical.hs 301 - paragraphStyle :: a -> Maybe (Rectangle -> Draw b -> Draw ()) -- ^ Get the paragraph bounding box and the paragraph draw command to apply additional effects + + -- | Get the paragraph bounding box and the paragraph draw command to apply additional effects + paragraphStyle :: a -- ^ The style + -> Maybe (Rectangle -> Draw b -> Draw ()) -- ^ Function used to style a paragraph hunk ./Graphics/PDF/Typesetting/Vertical.hs 311 - lineWidths (AnyParagraphStyle a) = lineWidths a - linePositions (AnyParagraphStyle a) = linePositions a + lineWidth (AnyParagraphStyle a) = lineWidth a + linePosition (AnyParagraphStyle a) = linePosition a hunk ./Test/Makefile 11 - ghc -o test --make test.hs + ghc -o test -fglasgow-exts -O2 --make test.hs hunk ./Test/test.hs 200 - lineWidths (BluePara a) w nb = (if nb > 3 then w else w-a) - 20.0 - linePositions (BluePara a) _ nb = (if nb > 3 then 0.0 else a) + 10.0 + lineWidth (BluePara a) w nb = (if nb > 3 then w else w-a) - 20.0 + linePosition (BluePara a) _ nb = (if nb > 3 then 0.0 else a) + 10.0 hunk ./Test/test.hs 237 - lineWidths _ _ nb = + lineWidth _ _ nb = hunk ./Test/test.hs 244 - linePositions a w nb = max 0 ((w - lineWidths a w nb) / 2.0) + linePosition a w nb = max 0 ((w - lineWidth a w nb) / 2.0) hunk ./Graphics/PDF/Typesetting/Box.hs 17 - , NullChar(..) - , Overfull(..) hunk ./Graphics/PDF/Typesetting/Box.hs 20 - , AnyStyle(..) hunk ./Graphics/PDF/Typesetting/Box.hs 74 -class Style a where +class Eq a => Style a where hunk ./Graphics/PDF/Typesetting/Box.hs 84 - -- | All styles used in a document must have different style codes - styleCode :: a -> Int hunk ./Graphics/PDF/Typesetting/Box.hs 95 - --- | Any sentence style -data AnyStyle = forall a. (Style a) => AnyStyle a - -instance Style AnyStyle where - sentenceStyle (AnyStyle a) = sentenceStyle a - wordStyle (AnyStyle a) = wordStyle a - textStyle (AnyStyle a) = textStyle a - styleCode (AnyStyle a) = styleCode a - updateStyle (AnyStyle a) = AnyStyle $ updateStyle a - styleHeight (AnyStyle a) = styleHeight a - styleDescent (AnyStyle a) = styleDescent a - - hunk ./Graphics/PDF/Typesetting/Box.hs 122 - -data NullChar = NullChar deriving(Show) -data Overfull = Overfull AnyStyle - -instance Box NullChar where - boxWidth _ = 0 - boxHeight _ = 0 - boxDescent _ = 0 - -instance DisplayableBox NullChar where - strokeBox _ _ _ = return () - -instance Box Overfull where - boxWidth _ = 0 - boxHeight (Overfull s) = getHeight (textFont . textStyle $ s) - boxDescent (Overfull s) = getDescent (textFont . textStyle $ s) - -instance DisplayableBox Overfull where - strokeBox a x y = do - stroke $ Line (x+2) (y - boxDescent a) (x+2) (y - boxDescent a + boxHeight a) hunk ./Graphics/PDF/Typesetting/Breaking.hs 23 - , nullLetter hunk ./Graphics/PDF/Typesetting/Breaking.hs 39 --- | Create a null box -nullLetter :: Letter -nullLetter = mkLetter (0,0,0) Nothing NullChar hunk ./Graphics/PDF/Typesetting/Breaking.hs 42 - -> Maybe AnyStyle -- ^ Text style of the box (can use t) + -> Maybe s -- ^ Text style of the box (can use t) hunk ./Graphics/PDF/Typesetting/Breaking.hs 44 - -> Letter + -> Letter s hunk ./Graphics/PDF/Typesetting/Breaking.hs 49 -data Letter = Letter BoxDimension !AnyBox !(Maybe AnyStyle) -- ^ Any box as a letter - | Glue !PDFFloat !PDFFloat !PDFFloat !(Maybe AnyStyle) -- ^ A glue with style to know if it is part of the same sentence - | FlaggedPenalty !PDFFloat !Int !AnyStyle -- ^ Hyphen point - | Penalty !Int -- ^ Penalty - | AChar !AnyStyle !Char !PDFFloat -- ^ A char - | Kern !PDFFloat !(Maybe AnyStyle) -- ^ A kern : non dilatable and non breakable glue +data Letter s = Letter BoxDimension !AnyBox !(Maybe s) -- ^ Any box as a letter + | Glue !PDFFloat !PDFFloat !PDFFloat !(Maybe s) -- ^ A glue with style to know if it is part of the same sentence + | FlaggedPenalty !PDFFloat !Int !s -- ^ Hyphen point + | Penalty !Int -- ^ Penalty + | AChar !s !Char !PDFFloat -- ^ A char + | Kern !PDFFloat !(Maybe s) -- ^ A kern : non dilatable and non breakable glue hunk ./Graphics/PDF/Typesetting/Breaking.hs 59 -instance MaybeGlue Letter where +instance MaybeGlue (Letter s) where hunk ./Graphics/PDF/Typesetting/Breaking.hs 71 -letterWidth :: Letter -- ^ letter +letterWidth :: Letter s -- ^ letter hunk ./Graphics/PDF/Typesetting/Breaking.hs 81 -instance Show Letter where +instance Show (Letter s) where hunk ./Graphics/PDF/Typesetting/Breaking.hs 92 -class PointedBox a where +class PointedBox s a | a -> s where hunk ./Graphics/PDF/Typesetting/Breaking.hs 96 - letter :: a -> Letter + letter :: a -> Letter s hunk ./Graphics/PDF/Typesetting/Breaking.hs 103 -instance PointedBox (PDFFloat,PDFFloat,PDFFloat,Int,Letter) where +instance PointedBox s (PDFFloat,PDFFloat,PDFFloat,Int,Letter s) where hunk ./Graphics/PDF/Typesetting/Breaking.hs 122 -instance PointedBox ZList where +instance PointedBox s (ZList s) where hunk ./Graphics/PDF/Typesetting/Breaking.hs 134 -penaltyWidth :: Letter -> PDFFloat +penaltyWidth :: Letter s -> PDFFloat hunk ./Graphics/PDF/Typesetting/Breaking.hs 151 - -> ZList + -> ZList s hunk ./Graphics/PDF/Typesetting/Breaking.hs 203 - -> ZList -- ^ Flag for current + -> ZList s -- ^ Flag for current hunk ./Graphics/PDF/Typesetting/Breaking.hs 232 -data ZList = ZList (MaybeCB Letter) (PDFFloat,PDFFloat,PDFFloat,Int,Letter) [Letter] deriving(Show) +data ZList s = ZList (MaybeCB (Letter s)) (PDFFloat,PDFFloat,PDFFloat,Int,Letter s) [Letter s] deriving(Show) hunk ./Graphics/PDF/Typesetting/Breaking.hs 235 -createZList :: [Letter] -> ZList +createZList :: [Letter s] -> ZList s hunk ./Graphics/PDF/Typesetting/Breaking.hs 239 -theEnd :: ZList -> Bool +theEnd :: ZList s -> Bool hunk ./Graphics/PDF/Typesetting/Breaking.hs 245 -createBreaknode :: Maybe (Int,Int,Int,BreakNode) -> ZList -> BreakNode +createBreaknode :: Maybe (Int,Int,Int,BreakNode) -> ZList s -> BreakNode hunk ./Graphics/PDF/Typesetting/Breaking.hs 259 - -> AnyStyle -- ^ Style of future hyphen + -> s -- ^ Style of future hyphen hunk ./Graphics/PDF/Typesetting/Breaking.hs 261 - -> Letter + -> Letter s hunk ./Graphics/PDF/Typesetting/Breaking.hs 264 -moveRight :: ZList -> ZList +moveRight :: ZList s -> ZList s hunk ./Graphics/PDF/Typesetting/Breaking.hs 278 - -> ZList -- ^ Current analyzed box + -> ZList s -- ^ Current analyzed box hunk ./Graphics/PDF/Typesetting/Breaking.hs 305 - -> ZList -- ^ Current + -> ZList s -- ^ Current hunk ./Graphics/PDF/Typesetting/Breaking.hs 326 -getNewActiveBreakpoints :: BRState -> Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList -> (PossibleBreak,ActiveNodes) +getNewActiveBreakpoints :: BRState -> Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList s -> (PossibleBreak,ActiveNodes) hunk ./Graphics/PDF/Typesetting/Breaking.hs 361 -analyzeBoxes :: BRState -> Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList -> [(PDFFloat,Int,Bool)] +analyzeBoxes :: BRState -> Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList s -> [(PDFFloat,Int,Bool)] hunk ./Graphics/PDF/Typesetting/Breaking.hs 413 -hyphenBox :: AnyStyle -> Letter +hyphenBox :: Style s => s -> Letter s hunk ./Graphics/PDF/Typesetting/Breaking.hs 417 -cutList :: [Letter] -> Int -> [(PDFFloat,Int,Bool)] -> [(PDFFloat,[Letter])] +cutList :: Style s => [Letter s] -> Int -> [(PDFFloat,Int,Bool)] -> [(PDFFloat,[Letter s])] hunk ./Graphics/PDF/Typesetting/Breaking.hs 446 -formatList :: BRState -> (Int -> PDFFloat) -> [Letter] -> [(PDFFloat,[Letter])] +formatList :: Style s => BRState -> (Int -> PDFFloat) -> [Letter s] -> [(PDFFloat,[Letter s])] hunk ./Graphics/PDF/Typesetting/Breaking.hs 461 -glueBox :: Maybe AnyStyle +glueBox :: Maybe s hunk ./Graphics/PDF/Typesetting/Breaking.hs 465 - -> Letter + -> Letter s hunk ./Graphics/PDF/Typesetting/Breaking.hs 469 -spaceGlueBox :: AnyStyle -- ^ The style - -> Letter +spaceGlueBox :: Style s => s -- ^ The style + -> Letter s hunk ./Graphics/PDF/Typesetting/Breaking.hs 480 -punctuationGlue :: AnyStyle -- ^ The style - -> Letter +punctuationGlue :: Style s => s -- ^ The style + -> Letter s hunk ./Graphics/PDF/Typesetting/Breaking.hs 492 - -> Letter + -> Letter s hunk ./Graphics/PDF/Typesetting/Breaking.hs 496 -createChar :: AnyStyle -- ^ Char style +createChar :: s -- ^ Char style hunk ./Graphics/PDF/Typesetting/Breaking.hs 499 - -> Letter + -> Letter s hunk ./Graphics/PDF/Typesetting/Breaking.hs 504 -createLetterBoxes :: BRState - -> AnyStyle -- ^ Letter style +createLetterBoxes :: Style s => BRState + -> s -- ^ Letter style hunk ./Graphics/PDF/Typesetting/Breaking.hs 507 - -> [Letter] -- ^ Boxes + -> [Letter s] -- ^ Boxes hunk ./Graphics/PDF/Typesetting/Breaking.hs 518 -splitText :: BRState -> AnyStyle -> PDFString -> [Letter] +splitText :: Style s => BRState -> s -> PDFString -> [Letter s] hunk ./Graphics/PDF/Typesetting/Breaking.hs 521 -kernBox :: AnyStyle -> PDFFloat -> Letter +kernBox :: s -> PDFFloat -> Letter s hunk ./Graphics/PDF/Typesetting/Horizontal.hs 41 -createWords :: PDFFloat -- ^ Adjustement ratio - -> Maybe (AnyStyle,String, PDFFloat) -- ^ Current word - -> [Letter] -- ^ List of letters - -> [HBox] -- ^ List of words or sentences +createWords :: Eq s => PDFFloat -- ^ Adjustement ratio + -> Maybe (s,String, PDFFloat) -- ^ Current word + -> [Letter s] -- ^ List of letters + -> [HBox s] -- ^ List of words or sentences hunk ./Graphics/PDF/Typesetting/Horizontal.hs 53 -createWords r (Just (s,t,w)) ((AChar s' t' w'):l) | styleCode s == styleCode s' = createWords r (Just (s,t':t,w+w')) l +createWords r (Just (s,t,w)) ((AChar s' t' w'):l) | s == s' = createWords r (Just (s,t':t,w+w')) l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 75 -simplify :: PDFFloat -- ^ Adjustement ratio - -> [Letter] -- ^ List of letters - -> [HBox] -- ^ List of words or sentence +simplify :: Eq s => PDFFloat -- ^ Adjustement ratio + -> [Letter s] -- ^ List of letters + -> [HBox s] -- ^ List of words or sentence hunk ./Graphics/PDF/Typesetting/Horizontal.hs 84 -horizontalPostProcess :: [(PDFFloat,[Letter])] -- ^ adjust ratio, hyphen style, list of letters or boxes - -> [HBox] -- ^ List of lines +horizontalPostProcess :: (Style s) => [(PDFFloat,[Letter s])] -- ^ adjust ratio, hyphen style, list of letters or boxes + -> [HBox s] -- ^ List of lines hunk ./Graphics/PDF/Typesetting/Horizontal.hs 99 -data HBox = HBox !PDFFloat !PDFFloat !PDFFloat ![HBox] - | HGlue !PDFFloat !(Maybe (PDFFloat,PDFFloat)) !(Maybe AnyStyle) - | Text !AnyStyle !PDFString !PDFFloat - | SomeHBox !BoxDimension !AnyBox !(Maybe AnyStyle) +data HBox s = HBox !PDFFloat !PDFFloat !PDFFloat ![HBox s] + | HGlue !PDFFloat !(Maybe (PDFFloat,PDFFloat)) !(Maybe s) + | Text !s !PDFString !PDFFloat + | SomeHBox !BoxDimension !AnyBox !(Maybe s) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 105 -withNewStyle :: AnyStyle -> HBox -> HBox +withNewStyle :: s -> HBox s -> HBox s hunk ./Graphics/PDF/Typesetting/Horizontal.hs 114 -mkHboxWithRatio :: PDFFloat -- ^ Adjustement ratio - -> [HBox] - -> HBox -mkHboxWithRatio _ [] = SomeHBox (0,0,0) (AnyBox NullChar) Nothing +mkHboxWithRatio :: Style s => PDFFloat -- ^ Adjustement ratio + -> [HBox s] + -> HBox s +mkHboxWithRatio _ [] = error "Cannot create an empty horizontal box" hunk ./Graphics/PDF/Typesetting/Horizontal.hs 131 -instance MaybeGlue HBox where +instance Style s => MaybeGlue (HBox s) where hunk ./Graphics/PDF/Typesetting/Horizontal.hs 137 -createText :: Style s => s -- ^ Style +createText :: s -- ^ Style hunk ./Graphics/PDF/Typesetting/Horizontal.hs 140 - -> HBox -createText s t w = Text (AnyStyle s) t w + -> HBox s +createText s t w = Text s t w hunk ./Graphics/PDF/Typesetting/Horizontal.hs 144 -instance Show HBox where +instance Show (HBox s) where hunk ./Graphics/PDF/Typesetting/Horizontal.hs 151 -drawTextLine :: AnyStyle -> [HBox] -> PDFFloat -> PDFFloat -> Draw () +drawTextLine :: (Style s) => s -> [HBox s] -> PDFFloat -> PDFFloat -> Draw () hunk ./Graphics/PDF/Typesetting/Horizontal.hs 162 -drawWords :: AnyStyle -> [HBox] -> PDFFloat -> PDFFloat -> Draw () +drawWords :: (Style s) => s -> [HBox s] -> PDFFloat -> PDFFloat -> Draw () hunk ./Graphics/PDF/Typesetting/Horizontal.hs 188 -drawPureWords :: AnyStyle -> [HBox] -> PDFFloat -> PDFFloat -> PDFText ([HBox],PDFFloat) +drawPureWords :: Style s => s -> [HBox s] -> PDFFloat -> PDFFloat -> PDFText ([HBox s],PDFFloat) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 209 -startDrawingNewLineOfText :: PDFFloat -> PDFFloat -> [HBox] -> PDFFloat -> PDFFloat -> AnyStyle -> Draw () +startDrawingNewLineOfText :: (Style s) => PDFFloat -> PDFFloat -> [HBox s] -> PDFFloat -> PDFFloat -> s -> Draw () hunk ./Graphics/PDF/Typesetting/Horizontal.hs 224 -drawLineOfHboxes :: PDFFloat -- ^ Height of the total line first time this function is called +drawLineOfHboxes :: (Style s) => PDFFloat -- ^ Height of the total line first time this function is called hunk ./Graphics/PDF/Typesetting/Horizontal.hs 226 - -> [HBox] -- ^ Remaining box to display + -> [HBox s] -- ^ Remaining box to display hunk ./Graphics/PDF/Typesetting/Horizontal.hs 243 -instance Box HBox where +instance Style s => Box (HBox s) where hunk ./Graphics/PDF/Typesetting/Horizontal.hs 305 -instance DisplayableBox HBox where +instance (Style s) => DisplayableBox (HBox s) where hunk ./Graphics/PDF/Typesetting/Horizontal.hs 339 -isSameStyle :: Style s => s - -> HBox +isSameStyle :: (Style s) => s + -> HBox s hunk ./Graphics/PDF/Typesetting/Horizontal.hs 342 -isSameStyle s (Text style _ _) = styleCode s == styleCode style -isSameStyle s (HGlue _ _ (Just style)) = styleCode s == styleCode style -isSameStyle s (SomeHBox _ _ (Just style)) = styleCode s == styleCode style +isSameStyle s (Text style _ _) = s == style +isSameStyle s (HGlue _ _ (Just style)) = s == style +isSameStyle s (SomeHBox _ _ (Just style)) = s == style hunk ./Graphics/PDF/Typesetting/Vertical.hs 22 - , AnyParagraphStyle(..) hunk ./Graphics/PDF/Typesetting/Vertical.hs 33 -data VerState = VerState { baselineskip :: !(PDFFloat,PDFFloat,PDFFloat) -- ^ Default value (12,0.17,0.0) - , lineskip :: !(PDFFloat,PDFFloat,PDFFloat) -- ^ Default value (3.0,0.33,0.0) - , lineskiplimit :: !PDFFloat -- ^ Default value 2 - , paraStyle :: !AnyParagraphStyle - } +data VerState s = VerState { baselineskip :: !(PDFFloat,PDFFloat,PDFFloat) -- ^ Default value (12,0.17,0.0) + , lineskip :: !(PDFFloat,PDFFloat,PDFFloat) -- ^ Default value (3.0,0.33,0.0) + , lineskiplimit :: !PDFFloat -- ^ Default value 2 + , currentParagraphStyle :: !s + } hunk ./Graphics/PDF/Typesetting/Vertical.hs 39 -defaultVerState :: ParagraphStyle s => s -> VerState +defaultVerState :: s -> VerState s hunk ./Graphics/PDF/Typesetting/Vertical.hs 43 - , paraStyle = AnyParagraphStyle s + , currentParagraphStyle = s hunk ./Graphics/PDF/Typesetting/Vertical.hs 49 -data VBox = Paragraph [Letter] !(Maybe AnyParagraphStyle) !BRState - | VBox !PDFFloat !PDFFloat !PDFFloat ![VBox] !(Maybe AnyParagraphStyle) - | VGlue !PDFFloat !PDFFloat !PDFFloat !(Maybe (PDFFloat,PDFFloat)) !(Maybe AnyParagraphStyle) - | SomeVBox !PDFFloat !BoxDimension !AnyBox !(Maybe AnyParagraphStyle) +data VBox ps s = Paragraph [Letter s] !(Maybe ps) !BRState + | VBox !PDFFloat !PDFFloat !PDFFloat ![VBox ps s] !(Maybe ps) + | VGlue !PDFFloat !PDFFloat !PDFFloat !(Maybe (PDFFloat,PDFFloat)) !(Maybe ps) + | SomeVBox !PDFFloat !BoxDimension !AnyBox !(Maybe ps) hunk ./Graphics/PDF/Typesetting/Vertical.hs 54 -vglue :: Maybe AnyParagraphStyle +vglue :: Maybe ps hunk ./Graphics/PDF/Typesetting/Vertical.hs 60 - -> VBox + -> VBox ps s hunk ./Graphics/PDF/Typesetting/Vertical.hs 63 -instance Show VBox where +instance Show (VBox ps s) where hunk ./Graphics/PDF/Typesetting/Vertical.hs 73 - -> [VBox] - -> VBox -mkVboxWithRatio _ [] = SomeVBox 0.0 (0,0,0) (AnyBox NullChar) Nothing + -> [VBox ps s] + -> VBox ps s +mkVboxWithRatio _ [] = error "Cannot make an empty vbox" hunk ./Graphics/PDF/Typesetting/Vertical.hs 87 -instance MaybeGlue VBox where +instance MaybeGlue (VBox ps s) where hunk ./Graphics/PDF/Typesetting/Vertical.hs 93 -toVBoxes :: Maybe AnyParagraphStyle +toVBoxes :: (ParagraphStyle ps s) => Maybe ps hunk ./Graphics/PDF/Typesetting/Vertical.hs 95 - -> [HBox] -- ^ List of lines - -> [VBox] -- ^ List of VBoxes + -> [HBox s] -- ^ List of lines + -> [VBox ps s] -- ^ List of VBoxes hunk ./Graphics/PDF/Typesetting/Vertical.hs 110 -verticalPostProcess :: VerState +verticalPostProcess :: (ParagraphStyle ps s) => VerState ps hunk ./Graphics/PDF/Typesetting/Vertical.hs 113 - -> [VBox] -- ^ List of VBox with paragraphs - -> [VBox] -- ^ List of VBox where paragraphs have been line broken + -> [VBox ps s] -- ^ List of VBox with paragraphs + -> [VBox ps s] -- ^ List of VBox where paragraphs have been line broken hunk ./Graphics/PDF/Typesetting/Vertical.hs 119 - Just aStyle -> let (style',nl) = paraChange aStyle l + Just aStyle -> let (style',nl) = paragraphChange aStyle l hunk ./Graphics/PDF/Typesetting/Vertical.hs 127 -notGlue :: VBox -> Bool +notGlue :: VBox ps s -> Bool hunk ./Graphics/PDF/Typesetting/Vertical.hs 133 -getInterlineStyle :: VBox -> VBox -> Maybe AnyParagraphStyle -getInterlineStyle (VBox _ _ _ _ (Just s)) (SomeVBox _ _ _ (Just s')) | paraStyleCode s == paraStyleCode s' = Just s +getInterlineStyle :: Eq ps => VBox ps s -> VBox ps s -> Maybe ps +getInterlineStyle (VBox _ _ _ _ (Just s)) (SomeVBox _ _ _ (Just s')) | s == s' = Just s hunk ./Graphics/PDF/Typesetting/Vertical.hs 137 -getInterlineStyle (VBox _ _ _ _ (Just s)) (VBox _ _ _ _ (Just s')) | paraStyleCode s == paraStyleCode s' = Just s +getInterlineStyle (VBox _ _ _ _ (Just s)) (VBox _ _ _ _ (Just s')) | s == s' = Just s hunk ./Graphics/PDF/Typesetting/Vertical.hs 140 -getInterlineStyle (SomeVBox _ _ _ (Just s)) (SomeVBox _ _ _ (Just s')) | paraStyleCode s == paraStyleCode s' = Just s +getInterlineStyle (SomeVBox _ _ _ (Just s)) (SomeVBox _ _ _ (Just s')) | s == s' = Just s hunk ./Graphics/PDF/Typesetting/Vertical.hs 143 -getInterlineStyle (SomeVBox _ _ _ (Just s)) (VBox _ _ _ _ (Just s')) | paraStyleCode s == paraStyleCode s' = Just s +getInterlineStyle (SomeVBox _ _ _ (Just s)) (VBox _ _ _ _ (Just s')) | s == s' = Just s hunk ./Graphics/PDF/Typesetting/Vertical.hs 149 -getBoxDelta :: VBox -> PDFFloat +getBoxDelta :: VBox ps s -> PDFFloat hunk ./Graphics/PDF/Typesetting/Vertical.hs 155 -addInterlineGlue :: VerState -> [VBox] -> [VBox] +addInterlineGlue :: Eq ps => VerState ps -> [VBox ps s] -> [VBox ps s] hunk ./Graphics/PDF/Typesetting/Vertical.hs 179 -instance Box VBox where +instance Box (VBox ps s) where hunk ./Graphics/PDF/Typesetting/Vertical.hs 195 -instance DisplayableBox VBox where +instance (ParagraphStyle ps s) => DisplayableBox (VBox ps s) where hunk ./Graphics/PDF/Typesetting/Vertical.hs 210 -isSameParaStyle :: AnyParagraphStyle -> VBox -> Bool -isSameParaStyle s (Paragraph _ (Just s') _) = paraStyleCode s == paraStyleCode s' -isSameParaStyle s (VBox _ _ _ _ (Just s')) = paraStyleCode s == paraStyleCode s' -isSameParaStyle s (VGlue _ _ _ _ (Just s')) = paraStyleCode s == paraStyleCode s' -isSameParaStyle s (SomeVBox _ _ _ (Just s')) = paraStyleCode s == paraStyleCode s' +isSameParaStyle :: Eq ps => ps -> VBox ps s -> Bool +isSameParaStyle s (Paragraph _ (Just s') _) = s == s' +isSameParaStyle s (VBox _ _ _ _ (Just s')) = s == s' +isSameParaStyle s (VGlue _ _ _ _ (Just s')) = s == s' +isSameParaStyle s (SomeVBox _ _ _ (Just s')) = s == s' hunk ./Graphics/PDF/Typesetting/Vertical.hs 217 -recurseStrokeVBoxes :: Int -> [VBox] -> (PDFFloat,PDFFloat,PDFFloat) -> Draw () +recurseStrokeVBoxes :: (ParagraphStyle ps s) => Int -> [VBox ps s] -> (PDFFloat,PDFFloat,PDFFloat) -> Draw () hunk ./Graphics/PDF/Typesetting/Vertical.hs 238 -drawWithParaStyle :: AnyParagraphStyle -> [VBox] -> (PDFFloat,PDFFloat,PDFFloat) -> Draw () +drawWithParaStyle :: (ParagraphStyle ps s) => ps -> [VBox ps s] -> (PDFFloat,PDFFloat,PDFFloat) -> Draw () hunk ./Graphics/PDF/Typesetting/Vertical.hs 252 -strokeVBoxes :: [VBox] -- ^ List of boxes +strokeVBoxes :: (ParagraphStyle ps s) => [VBox ps s] -- ^ List of boxes hunk ./Graphics/PDF/Typesetting/Vertical.hs 271 -class ParagraphStyle a where +class (Style s, Eq a) => ParagraphStyle a s | a -> s where hunk ./Graphics/PDF/Typesetting/Vertical.hs 284 - -- | All paragraph styles used in a document must have different codes - paraStyleCode :: a -- ^ The style - -> Int -- ^ Code identifying the style - hunk ./Graphics/PDF/Typesetting/Vertical.hs 292 - paraChange :: a -- ^ The style - -> [Letter] -- ^ List of letters in the paragraph - -> (a,[Letter]) -- ^ Update style and list of letters - paraChange a l = (a,l) + paragraphChange :: a -- ^ The style + -> [Letter s] -- ^ List of letters in the paragraph + -> (a,[Letter s]) -- ^ Update style and list of letters + paragraphChange a l = (a,l) hunk ./Graphics/PDF/Typesetting/Vertical.hs 302 --- | Any paragraph style -data AnyParagraphStyle = forall a . ParagraphStyle a => AnyParagraphStyle a hunk ./Graphics/PDF/Typesetting/Vertical.hs 303 -instance ParagraphStyle AnyParagraphStyle where - lineWidth (AnyParagraphStyle a) = lineWidth a - linePosition (AnyParagraphStyle a) = linePosition a - paraStyleCode (AnyParagraphStyle a) = paraStyleCode a - interline (AnyParagraphStyle a) = interline a - paraChange (AnyParagraphStyle a) l = let (a',l') = paraChange a l in (AnyParagraphStyle a',l') - paragraphStyle (AnyParagraphStyle a) = paragraphStyle a hunk ./Graphics/PDF/Typesetting.hs 21 - , AnyStyle hunk ./Graphics/PDF/Typesetting.hs 22 - , AnyParagraphStyle hunk ./Graphics/PDF/Typesetting.hs 25 + , Para + , TM hunk ./Graphics/PDF/Typesetting.hs 80 -displayFormattedText :: (Style s, ParagraphStyle s') => Rectangle -- ^ Text area - -> s' -- ^ default vertical style +displayFormattedText :: (ParagraphStyle ps s) => Rectangle -- ^ Text area + -> ps -- ^ default vertical style hunk ./Graphics/PDF/Typesetting.hs 83 - -> TM a -- ^ Typesetting monad + -> TM ps s a -- ^ Typesetting monad hunk ./Graphics/PDF/Typesetting.hs 99 -addPenalty :: Int -> Para() +addPenalty :: Int -> Para s () hunk ./Graphics/PDF/Typesetting.hs 103 -endParagraph :: Bool -- ^ True if we use the same style to end a paragraph. false for an invisible style - -> Para () +endParagraph :: Style s => Bool -- ^ True if we use the same style to end a paragraph. false for an invisible style + -> Para s () hunk ./Graphics/PDF/Typesetting.hs 114 -getTextArea :: TM Rectangle +getTextArea :: TM ps s Rectangle hunk ./Graphics/PDF/Typesetting.hs 117 -defaultTmState :: (Style s, ParagraphStyle s') => s' -> s -> TMState -defaultTmState s' s = TMState { tmStyle = AnyStyle s +defaultTmState :: (ParagraphStyle ps s) => ps -> s -> TMState ps s +defaultTmState s' s = TMState { tmStyle = s hunk ./Graphics/PDF/Typesetting.hs 123 -data TMState = TMState { tmStyle :: !AnyStyle - , paraSettings :: !BRState - , pageSettings :: !VerState - } +data TMState ps s = TMState { tmStyle :: !s + , paraSettings :: !BRState + , pageSettings :: !(VerState ps) + } hunk ./Graphics/PDF/Typesetting.hs 128 -newtype TM a = TM { unTM :: RWS Rectangle [VBox] TMState a} +newtype TM ps s a = TM { unTM :: RWS Rectangle [VBox ps s] (TMState ps s) a} hunk ./Graphics/PDF/Typesetting.hs 130 - deriving(Monad,MonadWriter [VBox], MonadState TMState, MonadReader Rectangle, Functor) + deriving(Monad,MonadWriter [VBox ps s], MonadState (TMState ps s), MonadReader Rectangle, Functor) hunk ./Graphics/PDF/Typesetting.hs 133 -instance MonadWriter [VBox] TM -instance MonadState TMState TM +instance MonadWriter [VBox ps s] TM +instance MonadState (TMState ps s) TM hunk ./Graphics/PDF/Typesetting.hs 139 -newtype Para a = Para { unPara :: RWS BRState [Letter] AnyStyle a} +newtype Para s a = Para { unPara :: RWS BRState [Letter s] s a} hunk ./Graphics/PDF/Typesetting.hs 141 - deriving(Monad,MonadWriter [Letter], MonadReader BRState, MonadState AnyStyle, Functor) + deriving(Monad,MonadWriter [Letter s], MonadReader BRState, MonadState s, Functor) hunk ./Graphics/PDF/Typesetting.hs 144 -instance MonadWriter [Letter] Para -instance MonadState AnyStyle Para +instance MonadWriter [Letter s] Para +instance MonadState s Para hunk ./Graphics/PDF/Typesetting.hs 151 -class Monad m => MonadStyle m where +class (Style s, Monad m) => MonadStyle s m | m -> s where hunk ./Graphics/PDF/Typesetting.hs 153 - setStyle :: Style a => a -> m () + setStyle :: s -> m () hunk ./Graphics/PDF/Typesetting.hs 156 - currentStyle :: m AnyStyle + currentStyle :: m s hunk ./Graphics/PDF/Typesetting.hs 178 -instance MonadStyle TM where +instance Style s => MonadStyle s (TM ps s) where hunk ./Graphics/PDF/Typesetting.hs 180 - setStyle f = modifyStrict $ \s -> s {tmStyle = AnyStyle f} + setStyle f = modifyStrict $ \s -> s {tmStyle = f} hunk ./Graphics/PDF/Typesetting.hs 201 -instance MonadStyle Para where +instance Style s => MonadStyle s (Para s) where hunk ./Graphics/PDF/Typesetting.hs 203 - setStyle f = put $! AnyStyle f + setStyle f = put $! f hunk ./Graphics/PDF/Typesetting.hs 223 -runPara :: Para a -> TM a +runPara :: Style s => Para s a -> TM ps s a hunk ./Graphics/PDF/Typesetting.hs 238 -getParaStyle :: TM AnyParagraphStyle -getParaStyle = gets pageSettings >>= TM . return . paraStyle +getParaStyle :: TM ps s ps +getParaStyle = gets pageSettings >>= TM . return . currentParagraphStyle hunk ./Graphics/PDF/Typesetting.hs 242 -setParaStyle :: ParagraphStyle s => s -> TM () +setParaStyle :: ParagraphStyle ps s => ps -> TM ps s () hunk ./Graphics/PDF/Typesetting.hs 244 - modifyStrict $ \s -> s {pageSettings = (pageSettings s){paraStyle = AnyParagraphStyle style}} + modifyStrict $ \s -> s {pageSettings = (pageSettings s){currentParagraphStyle = style}} hunk ./Graphics/PDF/Typesetting.hs 247 -addLetter :: Letter -> Para () +addLetter :: Letter s -> Para s () hunk ./Graphics/PDF/Typesetting.hs 251 -paragraph :: Para a -> TM a +paragraph :: Style s => Para s a -> TM ps s a hunk ./Graphics/PDF/Typesetting.hs 259 -txt :: String -> Para () +txt :: Style s => String -> Para s () hunk ./Graphics/PDF/Typesetting.hs 266 -kern :: PDFFloat -> Para() +kern :: Style s => PDFFloat -> Para s () hunk ./Graphics/PDF/Typesetting.hs 271 -setBaseLineSkip :: PDFFloat -> PDFFloat -> PDFFloat -> TM () +setBaseLineSkip :: PDFFloat -> PDFFloat -> PDFFloat -> TM ps s () hunk ./Graphics/PDF/Typesetting.hs 274 -getBaseLineSkip :: TM (PDFFloat,PDFFloat,PDFFloat) +getBaseLineSkip :: TM ps s (PDFFloat,PDFFloat,PDFFloat) hunk ./Graphics/PDF/Typesetting.hs 279 -setLineSkipLimit :: PDFFloat -> TM () +setLineSkipLimit :: PDFFloat -> TM ps s () hunk ./Graphics/PDF/Typesetting.hs 282 -getLineSkipLimit :: TM PDFFloat +getLineSkipLimit :: TM ps s PDFFloat hunk ./Graphics/PDF/Typesetting.hs 285 -setLineSkip :: PDFFloat -> PDFFloat -> PDFFloat -> TM () +setLineSkip :: PDFFloat -> PDFFloat -> PDFFloat -> TM ps s () hunk ./Graphics/PDF/Typesetting.hs 288 -getLineSkip :: TM (PDFFloat,PDFFloat,PDFFloat) +getLineSkip :: TM ps s (PDFFloat,PDFFloat,PDFFloat) hunk ./Graphics/PDF/Typesetting.hs 291 -setFirstPassTolerance :: PDFFloat -> TM () +setFirstPassTolerance :: PDFFloat -> TM ps s () hunk ./Graphics/PDF/Typesetting.hs 294 -getFirstPassTolerance :: TM PDFFloat +getFirstPassTolerance :: TM ps s PDFFloat hunk ./Graphics/PDF/Typesetting.hs 297 -setSecondPassTolerance :: PDFFloat -> TM () +setSecondPassTolerance :: PDFFloat -> TM ps s () hunk ./Graphics/PDF/Typesetting.hs 300 -getSecondPassTolerance :: TM PDFFloat +getSecondPassTolerance :: TM ps s PDFFloat hunk ./Graphics/PDF/Typesetting.hs 303 -setHyphenPenaltyValue :: Int -> TM () +setHyphenPenaltyValue :: Int -> TM ps s () hunk ./Graphics/PDF/Typesetting.hs 306 -getHyphenPenaltyValue :: TM Int +getHyphenPenaltyValue :: TM ps s Int hunk ./Graphics/PDF/Typesetting.hs 309 -setFitnessDemerit :: PDFFloat -> TM () +setFitnessDemerit :: PDFFloat -> TM ps s () hunk ./Graphics/PDF/Typesetting.hs 312 -getFitnessDemerit :: TM PDFFloat +getFitnessDemerit :: TM ps s PDFFloat hunk ./Graphics/PDF/Typesetting.hs 315 -setHyphenDemerit :: PDFFloat -> TM () +setHyphenDemerit :: PDFFloat -> TM ps s () hunk ./Graphics/PDF/Typesetting.hs 318 -getHyphenDemerit :: TM PDFFloat +getHyphenDemerit :: TM ps s PDFFloat hunk ./Graphics/PDF/Typesetting.hs 321 -setLinePenalty :: PDFFloat -> TM () +setLinePenalty :: PDFFloat -> TM ps s () hunk ./Graphics/PDF/Typesetting.hs 324 -getLinePenalty :: TM PDFFloat +getLinePenalty :: TM ps s PDFFloat hunk ./HPDF.cabal 2 -Version: 1.1 +Version: 1.2 hunk ./Test/test.hs 106 -data Normal = Normal deriving(Eq) -data Bold = Bold deriving(Eq) -data Crazy = Crazy deriving(Eq) -data SuperCrazy = SuperCrazy !([Int],[PDFFloat]) deriving(Eq) -data DebugStyle = DebugStyle deriving(Eq) -data RedRectStyle = RedRectStyle deriving(Eq) -data BlueStyle = BlueStyle deriving(Eq) hunk ./Test/test.hs 107 -instance Style Normal where - textStyle _ = TextStyle (PDFFont Times_Roman 10) black black FillText 1.0 1.0 1.0 1.0 - styleCode _ = 1 +data MyParaStyles = Normal + | Bold + | Crazy + | SuperCrazy [Int] [PDFFloat] + | DebugStyle + | RedRectStyle + | BlueStyle + deriving(Eq) + +instance Style MyParaStyles where + textStyle Normal = TextStyle (PDFFont Times_Roman 10) black black FillText 1.0 1.0 1.0 1.0 + textStyle Bold = TextStyle (PDFFont Times_Bold 12) black black FillText 1.0 1.0 1.0 1.0 + textStyle RedRectStyle = TextStyle (PDFFont Times_Roman 10) black black FillText 1.0 1.0 1.0 1.0 + textStyle DebugStyle = TextStyle (PDFFont Times_Roman 10) black black FillText 1.0 1.0 1.0 1.0 + textStyle Crazy = TextStyle (PDFFont Times_Roman 10) red red FillText 1.0 1.0 1.0 1.0 + textStyle (SuperCrazy _ _) = TextStyle (PDFFont Times_Roman 12) black black FillText 1.0 2.0 0.5 0.5 + textStyle BlueStyle = TextStyle (PDFFont Times_Roman 10) black black FillText 1.0 1.0 1.0 1.0 hunk ./Test/test.hs 125 -instance Style Bold where - textStyle _ = TextStyle (PDFFont Times_Bold 12) black black FillText 1.0 1.0 1.0 1.0 - styleCode _ = 2 + sentenceStyle BlueStyle = Just $ \r d -> do + fillColor $ Rgb 0.6 0.6 1 + strokeColor $ Rgb 0.6 0.6 1 + fillAndStroke r + d + return() hunk ./Test/test.hs 132 -instance Style RedRectStyle where - sentenceStyle _ = Just $ \r d -> do + sentenceStyle RedRectStyle = Just $ \r d -> do hunk ./Test/test.hs 137 - textStyle _ = TextStyle (PDFFont Times_Roman 10) black black FillText 1.0 1.0 1.0 1.0 - styleCode _ = 5 - -instance Style DebugStyle where - wordStyle _ = Just $ \r m d -> + sentenceStyle Crazy = Just $ \r d -> do + d + strokeColor blue + stroke r + sentenceStyle _ = Nothing + + wordStyle DebugStyle = Just $ \r m d -> hunk ./Test/test.hs 147 - textStyle _ = TextStyle (PDFFont Times_Roman 10) black black FillText 1.0 1.0 1.0 1.0 - styleCode _ = 5 - -crazyWord :: Rectangle -> StyleFunction -> Draw a -> Draw () -crazyWord r@(Rectangle xa ya xb yb) DrawWord d = do - fillColor $ Rgb 0.6 1 0.6 - fill r - d - strokeColor $ Rgb 0 0 1 - let m = (ya+yb)/2.0 - stroke $ Line xa m xb m -crazyWord (Rectangle xa ya xb yb) DrawGlue _ = do - fillColor $ Rgb 0 0 1 - fill (Circle ((xa+xb)/2.0) ((ya+yb)/2.0) ((xb-xa)/2.0)) - -instance Style Crazy where - sentenceStyle _ = Just $ \r d -> do - d - strokeColor blue - stroke r - wordStyle _ = Just crazyWord - textStyle _ = TextStyle (PDFFont Times_Roman 10) red red FillText 1.0 1.0 1.0 1.0 - styleCode _ = 3 - - -superCrazy :: SuperCrazy -superCrazy = SuperCrazy (randomRs (0,32) (mkStdGen 0),randomRs (-10.0,10.0) (mkStdGen 10000)) - -instance Style SuperCrazy where - styleCode _ = 4 - updateStyle (SuperCrazy (a,b)) = SuperCrazy $ (drop 8 a,tail b) - textStyle _ = TextStyle (PDFFont Times_Roman 12) black black FillText 1.0 2.0 0.5 0.5 - styleHeight r = (getHeight . textFont . textStyle $ r) + 4.0 - styleDescent r = (getDescent . textFont . textStyle $ r) + 2 - - wordStyle (SuperCrazy (l,_)) = Just ws + wordStyle Crazy = Just crazyWord + wordStyle (SuperCrazy l _) = Just ws hunk ./Test/test.hs 169 -instance ParagraphStyle Normal where - paraStyleCode _ = 1 + wordStyle _ = Nothing + + updateStyle (SuperCrazy a b) = SuperCrazy (drop 8 a) (tail b) + updateStyle a = a + + styleHeight r@(SuperCrazy _ _) = (getHeight . textFont . textStyle $ r) + 4.0 + styleHeight r = getHeight . textFont . textStyle $ r + + styleDescent r@(SuperCrazy _ _) = (getDescent . textFont . textStyle $ r) + 2 + styleDescent r = getDescent . textFont . textStyle $ r hunk ./Test/test.hs 180 -data CirclePara = CirclePara deriving(Eq) -data BluePara = BluePara PDFFloat deriving(Eq) hunk ./Test/test.hs 181 -instance ParagraphStyle BluePara where - paraStyleCode _ = 3 + +crazyWord :: Rectangle -> StyleFunction -> Draw a -> Draw () +crazyWord r@(Rectangle xa ya xb yb) DrawWord d = do + fillColor $ Rgb 0.6 1 0.6 + fill r + d + strokeColor $ Rgb 0 0 1 + let m = (ya+yb)/2.0 + stroke $ Line xa m xb m +crazyWord (Rectangle xa ya xb yb) DrawGlue _ = do + fillColor $ Rgb 0 0 1 + fill (Circle ((xa+xb)/2.0) ((ya+yb)/2.0) ((xb-xa)/2.0)) + + + +superCrazy :: MyParaStyles +superCrazy = SuperCrazy (randomRs (0,32) (mkStdGen 0)) (randomRs (-10.0,10.0) (mkStdGen 10000)) + +data MyVertStyles = NormalPara + | CirclePara + | BluePara !PDFFloat + deriving(Eq) + + +instance ParagraphStyle MyVertStyles MyParaStyles where hunk ./Test/test.hs 207 + lineWidth CirclePara _ nb = + let nbLines = 15.0 + r = nbLines * (getHeight . textFont . textStyle $ Normal) + pasin x' = if x' >= 1.0 then pi/2 else if x' <= -1.0 then (-pi/2) else asin x' + angle l = pasin $ (nbLines - (fromIntegral l) ) / nbLines + in + abs(2*r*cos (angle nb)) + lineWidth _ w _ = w + hunk ./Test/test.hs 217 - interline _ = Just $ \r -> do + linePosition a@(CirclePara) w nb = max 0 ((w - lineWidth a w nb) / 2.0) + linePosition _ _ _ = 0.0 + + interline (BluePara _) = Just $ \r -> do hunk ./Test/test.hs 224 - paraChange s [] = (s,[]) - paraChange _ (AChar st c _:l) = + interline _ = Nothing + + paragraphChange (BluePara _) (AChar st c _:l) = hunk ./Test/test.hs 245 - paraChange s l = (s,l) - paragraphStyle _ = Just $ \(Rectangle xa ya xb yb) b -> do + + paragraphChange s l = (s,l) + + paragraphStyle (BluePara _) = Just $ \(Rectangle xa ya xb yb) b -> do hunk ./Test/test.hs 256 - -instance ParagraphStyle CirclePara where - lineWidth _ _ nb = - let nbLines = 15.0 - r = nbLines * (getHeight . textFont . textStyle $ Normal) - pasin x' = if x' >= 1.0 then pi/2 else if x' <= -1.0 then (-pi/2) else asin x' - angle l = pasin $ (nbLines - (fromIntegral l) ) / nbLines - in - abs(2*r*cos (angle nb)) - linePosition a w nb = max 0 ((w - lineWidth a w nb) / 2.0) - paraStyleCode _ = 2 - -instance Style BlueStyle where - sentenceStyle _ = Just $ \r d -> do - fillColor $ Rgb 0.6 0.6 1 - strokeColor $ Rgb 0.6 0.6 1 - fillAndStroke r - d - return() - textStyle _ = TextStyle (PDFFont Times_Roman 10) black black FillText 1.0 1.0 1.0 1.0 - styleCode _ = 7 + paragraphStyle _ = Nothing hunk ./Test/test.hs 260 - let --symbol = mkDrawBox $ do - -- applyMatrix $ translate 0 (-4) - -- strokeColor red - -- fillColor red - -- fillAndStroke $ Polygon [ (0,0) - -- , (5,5) - -- , (10,0) - -- , (0,0) - -- ] - -- strokeColor blue - -- fillColor blue - -- fillAndStroke $ Polygon [ (0,0) - -- , (5,-5) - -- , (10,0) - -- , (0,0) - -- ] + let simpleText = do + paragraph $ do + txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor " + txt $ "incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud " + txt $ "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute " + txt $ "irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla " + txt $ "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia " + txt $ "deserunt mollit anim id est laborum." hunk ./Test/test.hs 292 + par :: Para MyParaStyles () hunk ./Test/test.hs 298 + normalPar :: Para MyParaStyles () hunk ./Test/test.hs 310 - setFirstPassTolerance 5000 - setSecondPassTolerance 10000 + setFirstPassTolerance 500 + --setSecondPassTolerance 10000 hunk ./Test/test.hs 315 - txt $ "Ut enim ad minim veniam, quis nostrud exercitation ullamco " + txt $ "Ut enim ad minim veniam, quis nostrud exercitation ullamco" hunk ./Test/test.hs 324 - setParaStyle Normal + setParaStyle NormalPara hunk ./Test/test.hs 338 + 0 -> do + strokeColor red + stroke $ Line 10 300 (10+maxw) 300 + displayFormattedText (Rectangle 10 0 (10+maxw) 300) NormalPara Normal simpleText hunk ./Test/test.hs 345 - displayFormattedText (Rectangle 10 0 (10+maxw) 300) Normal Normal myText + displayFormattedText (Rectangle 10 0 (10+maxw) 300) NormalPara Normal myText hunk ./Test/test.hs 349 - displayFormattedText (Rectangle 10 0 (10+maxw) 300) Normal Normal debugText + displayFormattedText (Rectangle 10 0 (10+maxw) 300) NormalPara Normal debugText hunk ./Test/test.hs 365 - _ -> displayFormattedText ((Rectangle 0 300 (10+maxw) 300)) Normal Normal myText + _ -> displayFormattedText ((Rectangle 0 300 (10+maxw) 300)) NormalPara Normal myText hunk ./Graphics/PDF/Typesetting/Box.hs 22 + , ComparableStyle(..) hunk ./Graphics/PDF/Typesetting/Box.hs 72 - deriving(Eq) + deriving(Eq) + +-- | Used to compare two style without taking into account the style state +class ComparableStyle a where + isSameStyleAs :: a -> a -> Bool hunk ./Graphics/PDF/Typesetting/Box.hs 79 -class Eq a => Style a where +class ComparableStyle a => Style a where hunk ./Graphics/PDF/Typesetting/Horizontal.hs 41 -createWords :: Eq s => PDFFloat -- ^ Adjustement ratio +createWords :: ComparableStyle s => PDFFloat -- ^ Adjustement ratio hunk ./Graphics/PDF/Typesetting/Horizontal.hs 53 -createWords r (Just (s,t,w)) ((AChar s' t' w'):l) | s == s' = createWords r (Just (s,t':t,w+w')) l +createWords r (Just (s,t,w)) ((AChar s' t' w'):l) | s `isSameStyleAs` s' = createWords r (Just (s,t':t,w+w')) l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 75 -simplify :: Eq s => PDFFloat -- ^ Adjustement ratio +simplify :: ComparableStyle s => PDFFloat -- ^ Adjustement ratio hunk ./Graphics/PDF/Typesetting/Horizontal.hs 342 -isSameStyle s (Text style _ _) = s == style -isSameStyle s (HGlue _ _ (Just style)) = s == style -isSameStyle s (SomeHBox _ _ (Just style)) = s == style +isSameStyle s (Text style _ _) = s `isSameStyleAs` style +isSameStyle s (HGlue _ _ (Just style)) = s `isSameStyleAs` style +isSameStyle s (SomeHBox _ _ (Just style)) = s `isSameStyleAs` style hunk ./Graphics/PDF/Typesetting/Vertical.hs 133 -getInterlineStyle :: Eq ps => VBox ps s -> VBox ps s -> Maybe ps -getInterlineStyle (VBox _ _ _ _ (Just s)) (SomeVBox _ _ _ (Just s')) | s == s' = Just s +getInterlineStyle :: ComparableStyle ps => VBox ps s -> VBox ps s -> Maybe ps +getInterlineStyle (VBox _ _ _ _ (Just s)) (SomeVBox _ _ _ (Just s')) | s `isSameStyleAs` s' = Just s hunk ./Graphics/PDF/Typesetting/Vertical.hs 137 -getInterlineStyle (VBox _ _ _ _ (Just s)) (VBox _ _ _ _ (Just s')) | s == s' = Just s +getInterlineStyle (VBox _ _ _ _ (Just s)) (VBox _ _ _ _ (Just s')) | s `isSameStyleAs` s' = Just s hunk ./Graphics/PDF/Typesetting/Vertical.hs 140 -getInterlineStyle (SomeVBox _ _ _ (Just s)) (SomeVBox _ _ _ (Just s')) | s == s' = Just s +getInterlineStyle (SomeVBox _ _ _ (Just s)) (SomeVBox _ _ _ (Just s')) | s `isSameStyleAs` s' = Just s hunk ./Graphics/PDF/Typesetting/Vertical.hs 143 -getInterlineStyle (SomeVBox _ _ _ (Just s)) (VBox _ _ _ _ (Just s')) | s == s' = Just s +getInterlineStyle (SomeVBox _ _ _ (Just s)) (VBox _ _ _ _ (Just s')) | s `isSameStyleAs` s' = Just s hunk ./Graphics/PDF/Typesetting/Vertical.hs 155 -addInterlineGlue :: Eq ps => VerState ps -> [VBox ps s] -> [VBox ps s] +addInterlineGlue :: ComparableStyle ps => VerState ps -> [VBox ps s] -> [VBox ps s] hunk ./Graphics/PDF/Typesetting/Vertical.hs 210 -isSameParaStyle :: Eq ps => ps -> VBox ps s -> Bool -isSameParaStyle s (Paragraph _ (Just s') _) = s == s' -isSameParaStyle s (VBox _ _ _ _ (Just s')) = s == s' -isSameParaStyle s (VGlue _ _ _ _ (Just s')) = s == s' -isSameParaStyle s (SomeVBox _ _ _ (Just s')) = s == s' +isSameParaStyle :: ComparableStyle ps => ps -> VBox ps s -> Bool +isSameParaStyle s (Paragraph _ (Just s') _) = s `isSameStyleAs` s' +isSameParaStyle s (VBox _ _ _ _ (Just s')) = s `isSameStyleAs` s' +isSameParaStyle s (VGlue _ _ _ _ (Just s')) = s `isSameStyleAs` s' +isSameParaStyle s (SomeVBox _ _ _ (Just s')) = s `isSameStyleAs` s' hunk ./Graphics/PDF/Typesetting/Vertical.hs 271 -class (Style s, Eq a) => ParagraphStyle a s | a -> s where +class (ComparableStyle a, Style s) => ParagraphStyle a s | a -> s where hunk ./Graphics/PDF/Typesetting.hs 27 + , ComparableStyle(..) hunk ./Test/test.hs 114 - deriving(Eq) + +instance ComparableStyle MyParaStyles where + isSameStyleAs Normal Normal = True + isSameStyleAs Bold Bold = True + isSameStyleAs Crazy Crazy = True + isSameStyleAs (SuperCrazy _ _) (SuperCrazy _ _) = True + isSameStyleAs DebugStyle DebugStyle = True + isSameStyleAs RedRectStyle RedRectStyle = True + isSameStyleAs BlueStyle BlueStyle = True + isSameStyleAs _ _ = False + hunk ./Test/test.hs 212 - deriving(Eq) - hunk ./Test/test.hs 213 +instance ComparableStyle MyVertStyles where + isSameStyleAs NormalPara NormalPara = True + isSameStyleAs CirclePara CirclePara = True + isSameStyleAs (BluePara _) (BluePara _) = True + isSameStyleAs _ _ = False + + hunk ./Graphics/PDF/Typesetting.hs 56 + , setCentered hunk ./Graphics/PDF/Typesetting.hs 69 + , module Graphics.PDF.Typesetting.StandardStyle hunk ./Graphics/PDF/Typesetting.hs 80 +import Graphics.PDF.Typesetting.StandardStyle hunk ./Graphics/PDF/Typesetting.hs 230 - let (a, s', boxes) = (runRWS . unPara $ closedPara ) settings f + let (a, s', boxes) = (runRWS . unPara $ closedPara settings) settings f hunk ./Graphics/PDF/Typesetting.hs 236 - closedPara = do + closedPara s = do + styleStart <- currentStyle + let w = spaceWidth styleStart + when (centered s) $ do + addLetter (kernBox (styleStart) 0) + addLetter (glueBox (Just styleStart) 0 (centeredDilatationFactor*w) 0) hunk ./Graphics/PDF/Typesetting.hs 243 - endParagraph False + if centered s + then do + addLetter (glueBox (Just styleStart) 0 (centeredDilatationFactor*w) 0) + addLetter (penalty (-infinity)) + else do + endParagraph False hunk ./Graphics/PDF/Typesetting.hs 341 +setCentered :: Bool -- ^ Centered or fully justified + -> TM ps s () +setCentered j = modifyStrict $ \s -> s {paraSettings = (paraSettings s){centered = j}} hunk ./Graphics/PDF/Typesetting/Box.hs 23 - ,mkDrawBox + , mkDrawBox hunk ./Graphics/PDF/Typesetting/Box.hs 78 --- | Style of text (sentences and words) +-- | Style of text (sentences and words). Minimum definition textStyle hunk ./Graphics/PDF/Typesetting/Breaking.hs 30 + , spaceWidth + , centeredDilatationFactor hunk ./Graphics/PDF/Typesetting/Breaking.hs 41 +--import Debug.Trace hunk ./Graphics/PDF/Typesetting/Breaking.hs 195 + , centered :: !Bool -- ^ Default value false hunk ./Graphics/PDF/Typesetting/Breaking.hs 199 -defaultBreakingSettings = BRState 100 200 50 10000 10000 10 +defaultBreakingSettings = BRState 100 200 50 10000 10000 10 False hunk ./Graphics/PDF/Typesetting/Breaking.hs 238 +--currentLetter :: ZList s -> [Letter s] +--currentLetter (ZList (OneCB (_,_,_,_,s)) (_,_,_,_,a) _) = [s,a] +--currentLetter (ZList _ (_,_,_,_,a) _) = [a] hunk ./Graphics/PDF/Typesetting/Breaking.hs 258 -createBreaknode prev (ZList _ (w,y,z,_,Penalty p) _) | p <= infinity = BreakNode w y z 0.0 False 0 0.0 prev +--createBreaknode prev (ZList _ (w,y,z,_,Penalty p) _) | p <= infinity = BreakNode w y z 0.0 False 0 0.0 prev hunk ./Graphics/PDF/Typesetting/Breaking.hs 283 + hunk ./Graphics/PDF/Typesetting/Breaking.hs 332 - f r newmap + f r newmap + +--debug b z = "(" ++ +-- show (cumulatedW z - totalWidth b + penaltyWidth (letter z)) ++ " " ++ +-- show (cumulatedY z - totalDilatation b) ++ " " ++ +-- show (cumulatedZ z - totalCompression b) ++ ")" +-- +--breakTrace b z r' p = trace (debug b z ++ " " ++ show r' ++ " " ++ show (currentLetter z) ++ " " ++ show (position z) ++ " -> " ++ show p) hunk ./Graphics/PDF/Typesetting/Breaking.hs 483 +-- | Return the standard space width +spaceWidth :: Style s => s -- ^ The style + -> PDFFloat +spaceWidth s = + let ws = (textWidth (textFont . textStyle $ s) (toPDFString " ") ) + h = scaleSpace . textStyle $ s + in + ws * h + +-- | How much dilatation is allowed compred to the space width +centeredDilatationFactor :: PDFFloat +centeredDilatationFactor = 10.0 + hunk ./Graphics/PDF/Typesetting/Breaking.hs 497 -spaceGlueBox :: Style s => s -- ^ The style - -> Letter s -spaceGlueBox s = +spaceGlueBox :: Style s => BRState -- ^ Paragraph settings + -> s -- ^ The style + -> [Letter s] +spaceGlueBox settings s = hunk ./Graphics/PDF/Typesetting/Breaking.hs 505 + normalW = ws * h hunk ./Graphics/PDF/Typesetting/Breaking.hs 507 - Glue (ws*h) (h*sy*ws/2.0) (h*sz*ws/3.0) (Just s) + case (centered settings) of + False -> [Glue (ws*h) (h*sy*ws/2.0) (h*sz*ws/3.0) (Just s)] + True -> [ Glue 0 (centeredDilatationFactor*normalW) 0 (Just s) + , Penalty 0 + , Glue normalW (-2*centeredDilatationFactor*normalW) 0 (Just s) + , Kern 0 (Just s) + , Penalty infinity + , Glue 0 (centeredDilatationFactor*normalW) 0 (Just s) + ] hunk ./Graphics/PDF/Typesetting/Breaking.hs 518 -punctuationGlue :: Style s => s -- ^ The style - -> Letter s -punctuationGlue s = +punctuationGlue :: Style s => BRState -- ^ Paragraph settings + -> s -- ^ The style + -> [Letter s] +punctuationGlue settings s = hunk ./Graphics/PDF/Typesetting/Breaking.hs 526 + normalW = ws * h hunk ./Graphics/PDF/Typesetting/Breaking.hs 528 - Glue (ws*h) (h*sy*ws) (h*sz*ws/3.0) (Just s) - + case (centered settings) of + False -> [Glue (ws*h) (h*sy*ws) (h*sz*ws/3.0) (Just s)] + True -> [ Glue 0 (centeredDilatationFactor*normalW) 0 (Just s) + , Penalty 0 + , Glue normalW (-2*centeredDilatationFactor*normalW) 0 (Just s) + , Kern 0 (Just s) + , Penalty infinity + , Glue 0 (centeredDilatationFactor*normalW) 0 (Just s) + ] hunk ./Graphics/PDF/Typesetting/Breaking.hs 556 -createLetterBoxes settings s ((wa,'.'):b@(_,bc):l') | bc /= ' ' = (createChar s wa '.'): punctuationGlue s : createLetterBoxes settings s (b:l') - | otherwise = (createChar s wa '.') : punctuationGlue s : createLetterBoxes settings s l' +createLetterBoxes settings s ((wa,'.'):b@(_,bc):l') | bc /= ' ' = (createChar s wa '.'): (punctuationGlue settings s ++ createLetterBoxes settings s (b:l') ) + | otherwise = (createChar s wa '.') : (punctuationGlue settings s ++ createLetterBoxes settings s l') hunk ./Graphics/PDF/Typesetting/Breaking.hs 559 -createLetterBoxes settings s ((_,' '):l) = (spaceGlueBox s) : createLetterBoxes settings s l +createLetterBoxes settings s ((_,' '):l) = (spaceGlueBox settings s) ++ createLetterBoxes settings s l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 275 + setWidth (penWidth . textStyle $ style) addfile ./Graphics/PDF/Typesetting/Layout.hs hunk ./Graphics/PDF/Typesetting/Layout.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2006 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Box +--------------------------------------------------------- +-- #hide +module Graphics.PDF.Typesetting.Layout ( + + ) where + +import Graphics.PDF.LowLevel.Types +import Graphics.PDF.Draw addfile ./Graphics/PDF/Typesetting/StandardStyle.hs hunk ./Graphics/PDF/Typesetting/StandardStyle.hs 1 - +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2007 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Standard styles for typesettings +--------------------------------------------------------- +-- #hide +module Graphics.PDF.Typesetting.StandardStyle( + -- * Styles + StandardStyle(..) + , StandardParagraphStyle(..) + ) where + +import Graphics.PDF.Colors +import Graphics.PDF.Text +import Graphics.PDF.Typesetting.Vertical +import Graphics.PDF.Typesetting.Box + +-- | Standard styles for sentences +data StandardStyle = Font PDFFont Color Color + +-- | Standard styles for paragraphs +data StandardParagraphStyle = NormalParagraph + + +instance ComparableStyle StandardStyle where + isSameStyleAs (Font a sca fca) (Font b scb fcb) = a == b && sca == scb && fca == fcb + isSameStyleAs _ _ = False + +instance ComparableStyle StandardParagraphStyle where + isSameStyleAs NormalParagraph NormalParagraph = True + +instance Style StandardStyle where + textStyle (Font a sc fc) = TextStyle a sc fc FillText 1.0 1.0 1.0 1.0 + +instance ParagraphStyle StandardParagraphStyle StandardStyle hunk ./HPDF.cabal 57 + Graphics.PDF.Typesetting.Layout hunk ./HPDF.cabal 59 + Graphics.PDF.Typesetting.StandardStyle hunk ./Test/test.hs 273 +standardStyleTest :: TM StandardParagraphStyle StandardStyle () +standardStyleTest = do + paragraph $ do + txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut " + txt $ "labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris " + setStyle $ Font (PDFFont Times_Bold 10) black black + txt $ "nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate " + txt $ "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " + txt $ "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + +testText :: TM StandardParagraphStyle StandardStyle () +testText = do + paragraph $ do + txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor " + txt $ "incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud " + txt $ "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute " + txt $ "irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla " + txt $ "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia " + txt $ "deserunt mollit anim id est laborum." + hunk ./Test/test.hs 400 + 4 -> displayFormattedText ((Rectangle 10 0 (10+maxw) 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) standardStyleTest + 5 -> do + strokeColor red + stroke $ Rectangle 10 0 (10+maxw) 300 + displayFormattedText ((Rectangle 10 0 (10+maxw) 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + setCentered True + testText hunk ./Test/test.hs 412 - page1 <- addPage Nothing - newSection (toPDFString "Typesetting") Nothing Nothing $ do - newSection (toPDFString "Normal text") Nothing Nothing $ do - typesetTest 1 page1 - - page2 <- addPage Nothing - newSection (toPDFString "Debug text") Nothing Nothing $ do - typesetTest 2 page2 - - page3 <- addPage Nothing - newSection (toPDFString "Circle text") Nothing Nothing $ do - typesetTest 3 page3 + --page1 <- addPage Nothing + --newSection (toPDFString "Typesetting") Nothing Nothing $ do + -- newSection (toPDFString "Normal text") Nothing Nothing $ do + -- typesetTest 1 page1 + -- + -- page2 <- addPage Nothing + -- newSection (toPDFString "Debug text") Nothing Nothing $ do + -- typesetTest 2 page2 + -- + -- page3 <- addPage Nothing + -- newSection (toPDFString "Circle text") Nothing Nothing $ do + -- typesetTest 3 page3 + -- + -- page3a <- addPage Nothing + -- newSection (toPDFString "Standard styles") Nothing Nothing $ do + -- typesetTest 4 page3a + -- + page3b <- addPage Nothing + newSection (toPDFString "Centered style") Nothing Nothing $ do + typesetTest 5 page3b hunk ./Test/test.hs 484 - runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = True}) rect $ do + runPdf "demo.pdf" (standardDocInfo { author=toPDFString "alpheccar", compressed = False}) rect $ do hunk ./Graphics/PDF/Typesetting/Breaking.hs 28 - , glueWidth + , glueSize hunk ./Graphics/PDF/Typesetting/Breaking.hs 32 + , dilatationRatio + , badness + , bigAdjustRatio hunk ./Graphics/PDF/Typesetting/Breaking.hs 63 - boxWidthWithRatio :: a -> PDFFloat -> PDFFloat + glueSizeWithRatio :: a -> PDFFloat -> PDFFloat hunk ./Graphics/PDF/Typesetting/Breaking.hs 66 - boxWidthWithRatio = letterWidth + glueSizeWithRatio = letterWidth hunk ./Graphics/PDF/Typesetting/Breaking.hs 69 -glueWidth :: PDFFloat -> PDFFloat -> PDFFloat -> PDFFloat -> PDFFloat -glueWidth w y z r = +glueSize :: PDFFloat -> PDFFloat -> PDFFloat -> PDFFloat -> PDFFloat +glueSize w y z r = hunk ./Graphics/PDF/Typesetting/Breaking.hs 82 -letterWidth (Glue w yi zi _) r = glueWidth w yi zi r +letterWidth (Glue w yi zi _) r = glueSize w yi zi r hunk ./Graphics/PDF/Typesetting/Breaking.hs 156 + +dilatationRatio :: PDFFloat -- ^ Maxw + -> PDFFloat -- ^ Current w + -> PDFFloat -- ^ y + -> PDFFloat -- ^ z + -> PDFFloat -- ^ Dilatation ratio +dilatationRatio maxw w y z = + if w == maxw + then 0.0 + else if w < maxw + then + if y > 0.0 then ((maxw - w) / y) else bigAdjustRatio + else + if z > 0.0 then ((maxw - w) / z) else bigAdjustRatio + + hunk ./Graphics/PDF/Typesetting/Breaking.hs 181 - if w == maxw - then 0.0 - else if w < maxw - then - if y > 0.0 then ((maxw - w) / y) else bigAdjustRatio - else - if z > 0.0 then ((maxw - w) / z) else bigAdjustRatio + dilatationRatio maxw w y z hunk ./Graphics/PDF/Typesetting/Breaking.hs 269 -createBreaknode prev (ZList _ (w,y,z,_,a) []) = BreakNode (w + boxWidthWithRatio a 0.0) (y) (z) 0.0 False 0 0.0 prev +createBreaknode prev (ZList _ (w,y,z,_,a) []) = BreakNode (w + glueSizeWithRatio a 0.0) (y) (z) 0.0 False 0 0.0 prev hunk ./Graphics/PDF/Typesetting/Breaking.hs 292 - let w' = boxWidthWithRatio a 0.0 + let w' = glueSizeWithRatio a 0.0 hunk ./Graphics/PDF/Typesetting/Breaking.hs 445 -cutList :: Style s => [Letter s] -> Int -> [(PDFFloat,Int,Bool)] -> [(PDFFloat,[Letter s])] +cutList :: Style s => [Letter s] -> Int -> [(PDFFloat,Int,Bool)] -> [(PDFFloat,[Letter s],[Letter s])] hunk ./Graphics/PDF/Typesetting/Breaking.hs 447 -cutList t _ [] = [(0.0,t)] +cutList t _ [] = [(0.0,[],t)] hunk ./Graphics/PDF/Typesetting/Breaking.hs 457 - [(ra,theLine)] + [(ra,theLine,t')] hunk ./Graphics/PDF/Typesetting/Breaking.hs 464 - (ra,theLine ++ [hyphenBox s]) : cutList t' ba l + (ra,theLine ++ [hyphenBox s],t') : cutList t' ba l hunk ./Graphics/PDF/Typesetting/Breaking.hs 469 - (ra,theLine) : cutList t' ba l + (ra,theLine,t') : cutList t' ba l hunk ./Graphics/PDF/Typesetting/Breaking.hs 474 -formatList :: Style s => BRState -> (Int -> PDFFloat) -> [Letter s] -> [(PDFFloat,[Letter s])] +formatList :: Style s => BRState -> (Int -> PDFFloat) -> [Letter s] -> [(PDFFloat,[Letter s],[Letter s])] hunk ./Graphics/PDF/Typesetting/Horizontal.hs 84 -horizontalPostProcess :: (Style s) => [(PDFFloat,[Letter s])] -- ^ adjust ratio, hyphen style, list of letters or boxes - -> [HBox s] -- ^ List of lines +horizontalPostProcess :: (Style s) => [(PDFFloat,[Letter s],[Letter s])] -- ^ adjust ratio, hyphen style, list of letters or boxes + -> [(HBox s,[Letter s])] -- ^ List of lines hunk ./Graphics/PDF/Typesetting/Horizontal.hs 87 -horizontalPostProcess ((r,l'):l) = let l'' = simplify r l' in +horizontalPostProcess ((r,l',r'):l) = let l'' = simplify r l' in hunk ./Graphics/PDF/Typesetting/Horizontal.hs 92 - (mkHboxWithRatio r l''):horizontalPostProcess l + ((mkHboxWithRatio r l''),r'):horizontalPostProcess l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 119 - let w = foldl' (\x y -> x + boxWidthWithRatio y r) 0.0 l + let w = foldl' (\x y -> x + glueSizeWithRatio y r) 0.0 l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 124 - addBox (HGlue gw (Just(y,z)) s) (HBox w' h' d' l') = HBox w' h' d' (HGlue (glueWidth gw y z r) Nothing s:l') + addBox (HGlue gw (Just(y,z)) s) (HBox w' h' d' l') = HBox w' h' d' (HGlue (glueSize gw y z r) Nothing s:l') hunk ./Graphics/PDF/Typesetting/Horizontal.hs 132 - boxWidthWithRatio (HGlue w (Just(y,z)) _) r = glueWidth w y z r - boxWidthWithRatio a _ = boxWidth a + glueSizeWithRatio (HGlue w (Just(y,z)) _) r = glueSize w y z r + glueSizeWithRatio a _ = boxWidth a hunk ./Graphics/PDF/Typesetting/Layout.hs 15 + Container(..) + , Width + , Height + , VBox(..) + , ParagraphStyle(..) + , VerState(..) + , vglue + , addTo + , isOverfull + , containerWidth + , containerCurrentHeight + , mkContainer + , strokeVBoxes + , containerX + , containerY hunk ./Graphics/PDF/Typesetting/Layout.hs 31 - + hunk ./Graphics/PDF/Typesetting/Layout.hs 33 +import Graphics.PDF.Typesetting.Breaking hunk ./Graphics/PDF/Typesetting/Layout.hs 35 +import Graphics.PDF.Shapes(Rectangle(..)) +import Graphics.PDF.Typesetting.Box +import Data.List(foldl') +import Data.Maybe(isJust,fromJust) + + +data VerState s = VerState { baselineskip :: !(PDFFloat,PDFFloat,PDFFloat) -- ^ Default value (12,0.17,0.0) + , lineskip :: !(PDFFloat,PDFFloat,PDFFloat) -- ^ Default value (3.0,0.33,0.0) + , lineskiplimit :: !PDFFloat -- ^ Default value 2 + , currentParagraphStyle :: !s + } + +data VBox ps s = Paragraph Int [Letter s] !(Maybe ps) !BRState + | VBox !PDFFloat !PDFFloat !PDFFloat ![VBox ps s] !(Maybe ps) + | VGlue !PDFFloat !PDFFloat !PDFFloat !(Maybe (PDFFloat,PDFFloat)) !(Maybe ps) + | SomeVBox !PDFFloat !BoxDimension !AnyBox !(Maybe ps) + +notGlue :: VBox ps s -> Bool +notGlue (VGlue _ _ _ _ _) = False +notGlue (Paragraph _ _ _ _) = False +notGlue _ = True + +vglue :: Maybe ps + -> PDFFloat -- ^ Glue height + -> PDFFloat -- ^ Glue dilatation factor + -> PDFFloat -- ^ Glue compression factor + -> PDFFloat -- ^ Glue width + -> PDFFloat -- ^ Glue delta + -> VBox ps s +vglue s h y z width delta = VGlue h width delta (Just(y,z)) s + +instance Show (VBox ps s) where + show (VBox _ a _ l _) = "(VBox " ++ show a ++ " " ++ show l ++ ")" + show (VGlue a _ _ _ _) = "(VGlue " ++ show a ++ ")" + show (Paragraph _ _ _ _) = "(Paragraph)" + show (SomeVBox _ d t _) = "(SomeVBox " ++ show (boxHeight d) ++ " " ++ show t ++ ")" + +instance MaybeGlue (VBox ps s) where + glueSizeWithRatio (VGlue w _ _ (Just(y,z)) _) r = glueSize w y z r + glueSizeWithRatio a _ = boxHeight a + +instance Box (VBox ps s) where + boxWidth (Paragraph _ _ _ _) = 0 + boxWidth (VBox w _ _ _ _) = w + boxWidth (SomeVBox _ d _ _) = boxWidth d + boxWidth (VGlue _ w _ _ _) = w + + boxHeight (Paragraph _ _ _ _) = 0 + boxHeight (VBox _ h _ _ _) = h + boxHeight (SomeVBox _ d _ _) = boxHeight d + boxHeight (VGlue h _ _ _ _) = h + + boxDescent (Paragraph _ _ _ _) = 0 + boxDescent (VBox _ _ d _ _) = d + boxDescent (SomeVBox _ d _ _) = boxDescent d + boxDescent (VGlue _ _ _ _ _) = 0 + +instance (ParagraphStyle ps s) => DisplayableBox (VBox ps s) where + strokeBox (Paragraph _ _ _ _) _ _ = return () + strokeBox b@(VBox _ _ _ l _) x y'' = strokeVBoxes l x y' + where + y' = y'' - boxHeight b + strokeBox (VGlue h w delta _ (Just style)) x y = + if (isJust . interline $ style) + then + (fromJust . interline $ style) $ Rectangle (x+delta) (y-h) (x+w+delta) y + else + return() + strokeBox (VGlue _ _ _ _ _) _ _ = return () + + strokeBox (SomeVBox delta _ a _) x y = strokeBox a (x+delta) y + +type Width = PDFFloat +type Height = PDFFloat + +-- | Container for vboxes (x,y,width,maxheight,height,currenty,current z) +data Container ps s = Container PDFFloat PDFFloat Width PDFFloat PDFFloat PDFFloat PDFFloat [VBox ps s] + +-- | Create a container +mkContainer :: PDFFloat -- ^ x + -> PDFFloat -- ^ y + -> PDFFloat -- ^ width + -> PDFFloat -- ^ height + -> Container ps s +mkContainer x y width height = Container x y width height 0 0 0 [] + +containerWidth :: Container ps s -> PDFFloat +containerWidth (Container _ _ w _ _ _ _ _) = w + +containerCurrentHeight :: Container ps s -> PDFFloat +containerCurrentHeight (Container _ _ _ _ ch _ _ _) = ch + +containerX :: Container ps s -> PDFFloat +containerX (Container x _ _ _ _ _ _ _) = x + +containerY :: Container ps s -> PDFFloat +containerY (Container _ y _ _ _ _ _ _) = y + + +-- | Get the required style for the interline glue +getInterlineStyle :: ComparableStyle ps => VBox ps s -> VBox ps s -> Maybe ps +getInterlineStyle (VBox _ _ _ _ (Just s)) (SomeVBox _ _ _ (Just s')) | s `isSameStyleAs` s' = Just s + | otherwise = Nothing + +getInterlineStyle (VBox _ _ _ _ (Just s)) (VBox _ _ _ _ (Just s')) | s `isSameStyleAs` s' = Just s + | otherwise = Nothing + +getInterlineStyle (SomeVBox _ _ _ (Just s)) (SomeVBox _ _ _ (Just s')) | s `isSameStyleAs` s' = Just s + | otherwise = Nothing + +getInterlineStyle (SomeVBox _ _ _ (Just s)) (VBox _ _ _ _ (Just s')) | s `isSameStyleAs` s' = Just s + | otherwise = Nothing + +getInterlineStyle _ _ = Nothing + +-- | Interline glue required +interlineGlue :: ComparableStyle ps => VerState ps -> VBox ps s -> VBox ps s -> Maybe (VBox ps s, PDFFloat, PDFFloat) +interlineGlue settings a b | notGlue a && notGlue b = + let p = boxDescent a + h = boxHeight b - boxDescent b + (ba,by,bz) = baselineskip settings + (lw,ly,lz) = lineskip settings + li = lineskiplimit settings + istyle = getInterlineStyle a b + theWidth = boxWidth a + theDelta = getBoxDelta a + in + if p <= -1000 + then + Nothing + else + if ba - p - h >= li + then + Just $ (vglue istyle (ba-p-h) by bz theWidth theDelta,by,bz) + else + Just $ (vglue istyle lw ly lz theWidth theDelta,ly,lz) + | otherwise = Nothing + +addTo :: ComparableStyle ps => VerState ps -> VBox ps s -> Container ps s -> Container ps s +addTo _ line (Container px py w maxh h y z []) = Container px py w maxh ((boxHeight line)+h) y z [line] +addTo settings line (Container px py w maxh h y z l@(a:_)) = + case interlineGlue settings a line of + Nothing -> + let h' = boxHeight line + h in + Container px py w maxh h' y z (line:l) + Just (v,ny,nz) -> + let h' = boxHeight line + h + boxHeight v + y' = y + ny + z' = z + nz + in + Container px py w maxh h' y' z' (line:v:l) + +isOverfull :: Container ps s -> Bool +isOverfull (Container _ _ _ maxh h y z _) = let r = dilatationRatio maxh h y z + in + if r >= bigAdjustRatio then h > maxh else r <= -1 + + + +-- | Paragraph style +class (ComparableStyle a, Style s) => ParagraphStyle a s | a -> s where + -- | Width of the line of the paragraph + lineWidth :: a -- ^ The style + -> PDFFloat -- ^ Width of the text area used by the typesetting algorithm + -> Int -- ^ Line number + -> PDFFloat -- ^ Line width + + -- | Horizontal shift of the line position relatively to the left egde of the paragraph bounding box + linePosition :: a -- ^ The style + -> PDFFloat -- ^ Width of the text area used by the typesetting algorithm + -> Int -- ^ Line number + -> PDFFloat -- ^ Horizontal offset from the left edge of the text area + + -- | How to style the interline glues added in a paragraph by the line breaking algorithm + interline :: a -- ^ The style + -> Maybe (Rectangle -> Draw ()) -- ^ Function used to style interline glues + interline _ = Nothing + lineWidth _ w _ = w + linePosition _ _ = const 0.0 + + -- | Change the content of a paragraph before the line breaking algorithm is run. It may also change the style + paragraphChange :: a -- ^ The style + -> [Letter s] -- ^ List of letters in the paragraph + -> (a,[Letter s]) -- ^ Update style and list of letters + paragraphChange a l = (a,l) + + -- | Get the paragraph bounding box and the paragraph draw command to apply additional effects + paragraphStyle :: a -- ^ The style + -> Maybe (Rectangle -> Draw b -> Draw ()) -- ^ Function used to style a paragraph + paragraphStyle _ = Nothing + +-- | Get the delta used to position a box with non rectangular shapes +getBoxDelta :: VBox ps s -> PDFFloat +getBoxDelta (Paragraph _ _ _ _) = 0.0 +getBoxDelta (VBox _ _ _ _ _) = 0.0 +getBoxDelta (VGlue _ _ delta _ _) = delta +getBoxDelta (SomeVBox delta _ _ _) = delta + + + + +isSameParaStyle :: ComparableStyle ps => ps -> VBox ps s -> Bool +isSameParaStyle s (Paragraph _ _ (Just s') _) = s `isSameStyleAs` s' +isSameParaStyle s (VBox _ _ _ _ (Just s')) = s `isSameStyleAs` s' +isSameParaStyle s (VGlue _ _ _ _ (Just s')) = s `isSameStyleAs` s' +isSameParaStyle s (SomeVBox _ _ _ (Just s')) = s `isSameStyleAs` s' +isSameParaStyle _ _ = False + +recurseStrokeVBoxes :: (ParagraphStyle ps s) => Int -> [VBox ps s] -> PDFFloat -> PDFFloat -> Draw () +recurseStrokeVBoxes _ [] _ _ = return () +recurseStrokeVBoxes _ (Paragraph _ _ _ _:_) _ _ = return () +recurseStrokeVBoxes nb (a@(VGlue _ _ _ _ _):l) xa y = do + let h = boxHeight a + strokeBox a xa y + recurseStrokeVBoxes nb l xa (y-h) + +recurseStrokeVBoxes nb (a:l) xa y = do + let h = boxHeight a + strokeBox a xa y + recurseStrokeVBoxes (nb+1) l xa (y-h) + +drawWithParaStyle :: (ParagraphStyle ps s) => ps -> [VBox ps s] -> PDFFloat -> PDFFloat -> Draw () +drawWithParaStyle style b xa y' = do + let (l',l'') = span (isSameParaStyle style) b + h' = foldl' (\x' ny -> x' + boxHeight ny) 0.0 l' + if (isJust . paragraphStyle $ style) + then do + let xleft = (minimum $ 100000:map getBoxDelta l' ) + xa + xright = (maximum $ 0:(map (\x -> boxWidth x + getBoxDelta x) l')) + xa + (fromJust . paragraphStyle $ style) (Rectangle xleft (y'- h') xright (y')) (recurseStrokeVBoxes 1 l' xa y') + else + recurseStrokeVBoxes 1 l' xa y' + strokeVBoxes l'' xa (y' - h') hunk ./Graphics/PDF/Typesetting/Layout.hs 269 +-- | Stroke the VBoxes +strokeVBoxes :: (ParagraphStyle ps s) => [VBox ps s] -- ^ List of boxes + -> PDFFloat -- ^ X pos + -> PDFFloat -- ^ Y pos + -> Draw () +strokeVBoxes [] _ _ = return () +strokeVBoxes b@((Paragraph _ _ (Just s') _):_) xa y = drawWithParaStyle s' b xa y +strokeVBoxes b@((VBox _ _ _ _ (Just s')):_) xa y = drawWithParaStyle s' b xa y +strokeVBoxes b@((VGlue _ _ _ _ (Just s')):_) xa y = drawWithParaStyle s' b xa y +strokeVBoxes b@((SomeVBox _ _ _ (Just s')):_) xa y = drawWithParaStyle s' b xa y +strokeVBoxes (a:l) xa y = + do + let h = boxHeight a + strokeBox a xa y + strokeVBoxes l xa (y-h) + hunk ./Graphics/PDF/Typesetting/Vertical.hs 14 - VBox(..) - , VerState(..) - , verticalPostProcess - , mkVboxWithRatio - , strokeVBoxes + mkVboxWithRatio hunk ./Graphics/PDF/Typesetting/Vertical.hs 18 + , VerState(..) + , fillContainer + , mkContainer + , VBox(..) hunk ./Graphics/PDF/Typesetting/Vertical.hs 32 +import Graphics.PDF.Typesetting.Layout hunk ./Graphics/PDF/Typesetting/Vertical.hs 34 -data VerState s = VerState { baselineskip :: !(PDFFloat,PDFFloat,PDFFloat) -- ^ Default value (12,0.17,0.0) - , lineskip :: !(PDFFloat,PDFFloat,PDFFloat) -- ^ Default value (3.0,0.33,0.0) - , lineskiplimit :: !PDFFloat -- ^ Default value 2 - , currentParagraphStyle :: !s - } hunk ./Graphics/PDF/Typesetting/Vertical.hs 45 -data VBox ps s = Paragraph [Letter s] !(Maybe ps) !BRState - | VBox !PDFFloat !PDFFloat !PDFFloat ![VBox ps s] !(Maybe ps) - | VGlue !PDFFloat !PDFFloat !PDFFloat !(Maybe (PDFFloat,PDFFloat)) !(Maybe ps) - | SomeVBox !PDFFloat !BoxDimension !AnyBox !(Maybe ps) + hunk ./Graphics/PDF/Typesetting/Vertical.hs 47 -vglue :: Maybe ps - -> PDFFloat -- ^ Glue height - -> PDFFloat -- ^ Glue dilatation factor - -> PDFFloat -- ^ Glue compression factor - -> PDFFloat -- ^ Glue width - -> PDFFloat -- ^ Glue delta - -> VBox ps s -vglue s h y z width delta = VGlue h width delta (Just(y,z)) s hunk ./Graphics/PDF/Typesetting/Vertical.hs 48 -instance Show (VBox ps s) where - show (VBox _ _ _ a _) = "(HBox " ++ show a ++ ")" - show (VGlue a _ _ _ _) = "(HGlue " ++ show a ++ ")" - show (Paragraph _ _ _) = "(Paragraph)" - show (SomeVBox _ _ t _) = "(SomeHBox " ++ show t ++ ")" hunk ./Graphics/PDF/Typesetting/Vertical.hs 57 - let w = foldl' (\x y -> x + boxWidthWithRatio y r) 0.0 l + let w = foldl' (\x y -> x + glueSizeWithRatio y r) 0.0 l hunk ./Graphics/PDF/Typesetting/Vertical.hs 60 - addBox (VGlue gw gh gdelta (Just(y,z)) s) (VBox w' h' d' l' s') = VBox w' h' d' (VGlue (glueWidth gw y z r) gh gdelta Nothing s:l') s' + addBox (VGlue gw gh gdelta (Just(y,z)) s) (VBox w' h' d' l' s') = VBox w' h' d' (VGlue (glueSize gw y z r) gh gdelta Nothing s:l') s' hunk ./Graphics/PDF/Typesetting/Vertical.hs 67 -instance MaybeGlue (VBox ps s) where - boxWidthWithRatio (VGlue w _ _ (Just(y,z)) _) r = glueWidth w y z r - boxWidthWithRatio a _ = boxWidth a - - --- | Convert pure lines to VBoxes -toVBoxes :: (ParagraphStyle ps s) => Maybe ps - -> PDFFloat -- ^ Max width - -> [HBox s] -- ^ List of lines - -> [VBox ps s] -- ^ List of VBoxes -toVBoxes Nothing _ l = map createVBox l - where - createVBox a = SomeVBox 0.0 (boxWidth a,boxHeight a,boxDescent a) (AnyBox a) Nothing - -toVBoxes s@(Just style) w l = map createVBoxAndAddKern $ zip [1..] (l ) - where - createVBoxAndAddKern (nb,a) = - let delta = (linePosition style) w nb - in - SomeVBox delta (boxWidth a,boxHeight a,boxDescent a) (AnyBox a) s hunk ./Graphics/PDF/Typesetting/Vertical.hs 68 --- | Create VBoxes. Paragraphs are analyzed and cut into VBoxes. The pragraph style is updated and used --- to transform the list of letters -verticalPostProcess :: (ParagraphStyle ps s) => VerState ps - -> Int -- ^ Line offset for the text area - -> Rectangle -- ^ Text area - -> [VBox ps s] -- ^ List of VBox with paragraphs - -> [VBox ps s] -- ^ List of VBox where paragraphs have been line broken -verticalPostProcess _ _ _ [] = [] -verticalPostProcess pageSettings o rect@(Rectangle xa _ xb _) ((Paragraph l style paraSettings):l') = - let (fl,newStyle) = case style of - Nothing -> (formatList paraSettings (const $ xb-xa) l,Nothing) - Just aStyle -> let (style',nl) = paragraphChange aStyle l - in - (formatList paraSettings (\nb -> (lineWidth style') (xb-xa) nb ) nl,Just style') - in - (addInterlineGlue pageSettings . toVBoxes newStyle (xb - xa) . horizontalPostProcess $ fl) ++ verticalPostProcess pageSettings (o + length fl) rect l' -verticalPostProcess pageSettings o rect (a:l') = a:verticalPostProcess pageSettings (o+1) rect l' hunk ./Graphics/PDF/Typesetting/Vertical.hs 70 -notGlue :: VBox ps s -> Bool -notGlue (VGlue _ _ _ _ _) = False -notGlue (Paragraph _ _ _) = False -notGlue _ = True hunk ./Graphics/PDF/Typesetting/Vertical.hs 71 --- | Get the required style for the interline glue -getInterlineStyle :: ComparableStyle ps => VBox ps s -> VBox ps s -> Maybe ps -getInterlineStyle (VBox _ _ _ _ (Just s)) (SomeVBox _ _ _ (Just s')) | s `isSameStyleAs` s' = Just s - | otherwise = Nothing hunk ./Graphics/PDF/Typesetting/Vertical.hs 72 -getInterlineStyle (VBox _ _ _ _ (Just s)) (VBox _ _ _ _ (Just s')) | s `isSameStyleAs` s' = Just s - | otherwise = Nothing hunk ./Graphics/PDF/Typesetting/Vertical.hs 73 -getInterlineStyle (SomeVBox _ _ _ (Just s)) (SomeVBox _ _ _ (Just s')) | s `isSameStyleAs` s' = Just s - | otherwise = Nothing - -getInterlineStyle (SomeVBox _ _ _ (Just s)) (VBox _ _ _ _ (Just s')) | s `isSameStyleAs` s' = Just s - | otherwise = Nothing + +dilateVboxes :: PDFFloat -> VBox ps s -> VBox ps s +dilateVboxes r g@(VGlue h w l (Just(_,_)) s) = + let h' = glueSizeWithRatio g r + in + VGlue h' w l Nothing s +dilateVboxes _ g@(VGlue _ _ _ Nothing _) = g +dilateVboxes _ a = a hunk ./Graphics/PDF/Typesetting/Vertical.hs 82 -getInterlineStyle _ _ = Nothing +drawContainer :: ParagraphStyle ps s => Container ps s -- ^ Container + -> Draw () +drawContainer (Container px py w maxh h y z oldl) = + let l' = reverse oldl + r = dilatationRatio maxh h y z + l'' = map (dilateVboxes r) l' + in + strokeVBoxes l'' px py + +-- | Create a new paragraph from the remaining letters +createPara :: Int + -> Maybe ps + -> BRState + -> [Letter s] + -> [VBox ps s] +createPara _ _ _ [] = [] +createPara lineOffset style paraSettings l = [Paragraph lineOffset l style paraSettings] hunk ./Graphics/PDF/Typesetting/Vertical.hs 100 --- | Get the delta used to position a box with non rectangular shapes -getBoxDelta :: VBox ps s -> PDFFloat -getBoxDelta (Paragraph _ _ _) = 0.0 -getBoxDelta (VBox _ _ _ _ _) = 0.0 -getBoxDelta (VGlue _ _ delta _ _) = delta -getBoxDelta (SomeVBox delta _ _ _) = delta - -addInterlineGlue :: ComparableStyle ps => VerState ps -> [VBox ps s] -> [VBox ps s] -addInterlineGlue _ [] = [] -addInterlineGlue _ [a] = [a] -addInterlineGlue settings (a:b:l) | notGlue a && notGlue b = - let p = boxDescent a - h = boxHeight b - boxDescent b - (ba,by,bz) = baselineskip settings - (lw,ly,lz) = lineskip settings - li = lineskiplimit settings - istyle = getInterlineStyle a b - theWidth = boxWidth a - theDelta = getBoxDelta a +-- | Add paragraph lines to a container +addParaLine :: (ParagraphStyle ps s, ComparableStyle ps) => VerState ps + -> Maybe ps + -> BRState + -> Container ps s -- ^ Container + -> [((HBox s,[Letter s]),Int)] + -> Either (Draw (),[VBox ps s]) (Container ps s) +addParaLine _ _ _ c [] = Right c +addParaLine verstate style paraSettings c (((line,remainingPar),lineNb):l) = + let c' = addTo verstate (toVBoxes style (containerWidth c) line lineNb) c + he (Container _ _ _ _ _ _ _ la) = foldl' (\x y -> x + boxHeight y) 0.0 la hunk ./Graphics/PDF/Typesetting/Vertical.hs 112 - if p <= -1000 + if isOverfull c' hunk ./Graphics/PDF/Typesetting/Vertical.hs 114 - a:addInterlineGlue settings (b:l) + Left (drawContainer c,createPara lineNb style paraSettings remainingPar) hunk ./Graphics/PDF/Typesetting/Vertical.hs 116 - if ba - p - h >= li - then - a:(vglue istyle (ba-p-h) by bz theWidth theDelta):addInterlineGlue settings (b:l) - else - a:(vglue istyle lw ly lz theWidth theDelta):addInterlineGlue settings (b:l) - | otherwise = a:addInterlineGlue settings (b:l) + addParaLine verstate style paraSettings c' l hunk ./Graphics/PDF/Typesetting/Vertical.hs 118 -instance Box (VBox ps s) where - boxWidth (Paragraph _ _ _) = 0 - boxWidth (VBox w _ _ _ _) = w - boxWidth (SomeVBox _ d _ _) = boxWidth d - boxWidth (VGlue _ w _ _ _) = w - - boxHeight (Paragraph _ _ _) = 0 - boxHeight (VBox _ h _ _ _) = h - boxHeight (SomeVBox _ d _ _) = boxHeight d - boxHeight (VGlue h _ _ _ _) = h +-- | Fill a container with lines +fillContainer :: (ParagraphStyle ps s, ComparableStyle ps) => VerState ps + -> Container ps s -- ^ Container + -> [VBox ps s] -- ^ VBox to add + -> (Draw(),[VBox ps s]) -- ^ Component and remaining VBoxes +fillContainer verstate c [] = (drawContainer c,[]) +fillContainer verstate c oldl@(Paragraph lineOffset l style paraSettings:l') = + let (fl,newStyle) = case style of + Nothing -> (formatList paraSettings (const $ containerWidth c) l,Nothing) + Just aStyle -> let (style',nl) = paragraphChange aStyle l + in + (formatList paraSettings (\nb -> (lineWidth style') (containerWidth c) (nb+lineOffset) ) nl,Just style') + newLines = horizontalPostProcess fl + r = addParaLine verstate style paraSettings c (zip newLines [1..]) + in + case r of + Left (d,remPara) -> (d,remPara ++ l') + Right c' -> fillContainer verstate c' l' hunk ./Graphics/PDF/Typesetting/Vertical.hs 137 - boxDescent (Paragraph _ _ _) = 0 - boxDescent (VBox _ _ d _ _) = d - boxDescent (SomeVBox _ d _ _) = boxDescent d - boxDescent (VGlue _ _ _ _ _) = 0 - -instance (ParagraphStyle ps s) => DisplayableBox (VBox ps s) where - strokeBox (Paragraph _ _ _) _ _ = return () - strokeBox b@(VBox _ _ _ l _) x y'' = strokeVBoxes l (x,y',y'') - where - y' = y'' - boxHeight b - strokeBox (VGlue h w delta _ (Just style)) x y = - if (isJust . interline $ style) - then - (fromJust . interline $ style) $ Rectangle (x+delta) (y-h) (x+w+delta) y - else - return() - strokeBox (VGlue _ _ _ _ _) _ _ = return () - - strokeBox (SomeVBox delta _ a _) x y = strokeBox a (x+delta) y - -isSameParaStyle :: ComparableStyle ps => ps -> VBox ps s -> Bool -isSameParaStyle s (Paragraph _ (Just s') _) = s `isSameStyleAs` s' -isSameParaStyle s (VBox _ _ _ _ (Just s')) = s `isSameStyleAs` s' -isSameParaStyle s (VGlue _ _ _ _ (Just s')) = s `isSameStyleAs` s' -isSameParaStyle s (SomeVBox _ _ _ (Just s')) = s `isSameStyleAs` s' -isSameParaStyle _ _ = False - -recurseStrokeVBoxes :: (ParagraphStyle ps s) => Int -> [VBox ps s] -> (PDFFloat,PDFFloat,PDFFloat) -> Draw () -recurseStrokeVBoxes _ [] _ = return () -recurseStrokeVBoxes _ (Paragraph _ _ _:_) _ = return () -recurseStrokeVBoxes nb (a@(VGlue _ _ _ _ _):l) (xa,y',y) = do - let h = boxHeight a - strokeBox a xa y - if y - h >= y' +fillContainer verstate c oldl@(a:l) = + let c' = addTo verstate a c + in + if isOverfull c' hunk ./Graphics/PDF/Typesetting/Vertical.hs 142 - recurseStrokeVBoxes nb l (xa,y',(y-h)) - else - return () - -recurseStrokeVBoxes nb (a:l) (xa,y',y) = do - let h = boxHeight a - strokeBox a xa y - if y - h >= y' - then - recurseStrokeVBoxes (nb+1) l (xa,y',(y-h)) - else - return () - -drawWithParaStyle :: (ParagraphStyle ps s) => ps -> [VBox ps s] -> (PDFFloat,PDFFloat,PDFFloat) -> Draw () -drawWithParaStyle style b (xa,y',y'') = do - let (l',l'') = span (isSameParaStyle style) b - h' = foldl' (\x' ny -> x' + boxHeight ny) 0.0 l' - if (isJust . paragraphStyle $ style) - then do - let xleft = (minimum $ 100000:map getBoxDelta l' ) + xa - xright = (maximum $ 0:(map (\x -> boxWidth x + getBoxDelta x) l')) + xa - (fromJust . paragraphStyle $ style) (Rectangle xleft (y''- h') xright (y'')) (recurseStrokeVBoxes 1 l' (xa,y',y'')) + (drawContainer c,oldl) hunk ./Graphics/PDF/Typesetting/Vertical.hs 144 - recurseStrokeVBoxes 1 l' (xa,y',y'') - strokeVBoxes l'' (xa,y',y''-h') - --- | Stroke the VBoxes -strokeVBoxes :: (ParagraphStyle ps s) => [VBox ps s] -- ^ List of boxes - -> (PDFFloat,PDFFloat,PDFFloat) - -> Draw () -strokeVBoxes [] (_,_,_) = return () -strokeVBoxes b@((Paragraph _ (Just s') _):_) (xa,y',y'') = drawWithParaStyle s' b (xa,y',y'') -strokeVBoxes b@((VBox _ _ _ _ (Just s')):_) (xa,y',y'') = drawWithParaStyle s' b (xa,y',y'') -strokeVBoxes b@((VGlue _ _ _ _ (Just s')):_) (xa,y',y'') = drawWithParaStyle s' b (xa,y',y'') -strokeVBoxes b@((SomeVBox _ _ _ (Just s')):_) (xa,y',y'') = drawWithParaStyle s' b (xa,y',y'') -strokeVBoxes (a:l) (xa,y',y'') = - do - let h = boxHeight a - strokeBox a xa y'' - if y'' - h >= y' - then - strokeVBoxes l (xa,y',(y''-h)) - else - return () + fillContainer verstate c' l + +-- | Convert pure lines to VBoxes +toVBoxes :: (ParagraphStyle ps s) => Maybe ps + -> PDFFloat -- ^ Max width + -> HBox s -- ^ List of lines + -> Int -- ^ Line number + -> VBox ps s -- ^ List of VBoxes +toVBoxes Nothing _ a _ = SomeVBox 0.0 (boxWidth a,boxHeight a,boxDescent a) (AnyBox a) Nothing +toVBoxes s@(Just style) w a nb = + let delta = (linePosition style) w nb in + SomeVBox delta (boxWidth a,boxHeight a,boxDescent a) (AnyBox a) s hunk ./Graphics/PDF/Typesetting/Vertical.hs 157 --- | Paragraph style -class (ComparableStyle a, Style s) => ParagraphStyle a s | a -> s where - -- | Width of the line of the paragraph - lineWidth :: a -- ^ The style - -> PDFFloat -- ^ Width of the text area used by the typesetting algorithm - -> Int -- ^ Line number - -> PDFFloat -- ^ Line width - - -- | Horizontal shift of the line position relatively to the left egde of the paragraph bounding box - linePosition :: a -- ^ The style - -> PDFFloat -- ^ Width of the text area used by the typesetting algorithm - -> Int -- ^ Line number - -> PDFFloat -- ^ Horizontal offset from the left edge of the text area - - -- | How to style the interline glues added in a paragraph by the line breaking algorithm - interline :: a -- ^ The style - -> Maybe (Rectangle -> Draw ()) -- ^ Function used to style interline glues - interline _ = Nothing - lineWidth _ w _ = w - linePosition _ _ = const 0.0 - - -- | Change the content of a paragraph before the line breaking algorithm is run. It may also change the style - paragraphChange :: a -- ^ The style - -> [Letter s] -- ^ List of letters in the paragraph - -> (a,[Letter s]) -- ^ Update style and list of letters - paragraphChange a l = (a,l) - - -- | Get the paragraph bounding box and the paragraph draw command to apply additional effects - paragraphStyle :: a -- ^ The style - -> Maybe (Rectangle -> Draw b -> Draw ()) -- ^ Function used to style a paragraph - paragraphStyle _ = Nothing - hunk ./Graphics/PDF/Typesetting.hs 89 -displayFormattedText area@(Rectangle xa y' _ y'') defaultVStyle defaultHStyle t = +displayFormattedText area@(Rectangle xa ya xb yb) defaultVStyle defaultHStyle t = hunk ./Graphics/PDF/Typesetting.hs 96 - strokeVBoxes (verticalPostProcess (pageSettings s') 0 area boxes) (xa,y',y'') + c = mkContainer xa yb (xb-xa) (yb-ya) + (d,_) = fillContainer (pageSettings s') c boxes + d hunk ./Graphics/PDF/Typesetting.hs 235 - tell $ [Paragraph boxes (Just style) settings] + tell $ [Paragraph 0 boxes (Just style) settings] hunk ./Test/test.hs 391 - setLineSkip 0 0 0 - setBaseLineSkip 0 0 0 - setLineSkipLimit 0 + --setLineSkip 0 0 0 + --setBaseLineSkip 0 0 0 + --setLineSkipLimit 0 hunk ./Test/test.hs 412 - --page1 <- addPage Nothing - --newSection (toPDFString "Typesetting") Nothing Nothing $ do - -- newSection (toPDFString "Normal text") Nothing Nothing $ do - -- typesetTest 1 page1 - -- - -- page2 <- addPage Nothing - -- newSection (toPDFString "Debug text") Nothing Nothing $ do - -- typesetTest 2 page2 - -- - -- page3 <- addPage Nothing - -- newSection (toPDFString "Circle text") Nothing Nothing $ do - -- typesetTest 3 page3 - -- - -- page3a <- addPage Nothing - -- newSection (toPDFString "Standard styles") Nothing Nothing $ do - -- typesetTest 4 page3a - -- - page3b <- addPage Nothing - newSection (toPDFString "Centered style") Nothing Nothing $ do - typesetTest 5 page3b + page1 <- addPage Nothing + newSection (toPDFString "Typesetting") Nothing Nothing $ do + --newSection (toPDFString "Normal text") Nothing Nothing $ do + -- typesetTest 1 page1 + -- + --page2 <- addPage Nothing + --newSection (toPDFString "Debug text") Nothing Nothing $ do + -- typesetTest 2 page2 + + page3 <- addPage Nothing + newSection (toPDFString "Circle text") Nothing Nothing $ do + typesetTest 3 page3 + + --page3a <- addPage Nothing + --newSection (toPDFString "Standard styles") Nothing Nothing $ do + -- typesetTest 4 page3a + -- + --page3b <- addPage Nothing + --newSection (toPDFString "Centered style") Nothing Nothing $ do + -- typesetTest 5 page3b hunk ./Graphics/PDF/Typesetting/Breaking.hs 63 + glueY :: a -> PDFFloat + glueZ :: a -> PDFFloat hunk ./Graphics/PDF/Typesetting/Breaking.hs 69 + glueY (Glue _ y _ _) = y + glueY _ = 0 + glueZ (Glue _ _ z _) = z + glueZ _ = 0 + hunk ./Graphics/PDF/Typesetting/Horizontal.hs 134 - - + glueY (HGlue _ (Just(y,z)) _) = y + glueY _ = 0 + glueZ (HGlue _ (Just(y,z)) _) = z + glueZ _ = 0 + hunk ./Graphics/PDF/Typesetting/Layout.hs 75 + + glueY (VGlue w _ _ (Just(y,z)) _) = y + glueY _ = 0 + glueZ (VGlue w _ _ (Just(y,z)) _) = z + glueZ _ = 0 hunk ./Graphics/PDF/Typesetting/Layout.hs 183 - let h' = boxHeight line + h in - Container px py w maxh h' y z (line:l) + let h' = boxHeight line + h + y' = y + glueY line + z' = z + glueZ line + in + Container px py w maxh h' y' z' (line:l) hunk ./Graphics/PDF/Typesetting/Layout.hs 190 - y' = y + ny - z' = z + nz + y' = y + ny + glueY line + z' = z + nz + glueZ line hunk ./Graphics/PDF/Typesetting/Vertical.hs 33 - hunk ./Graphics/PDF/Typesetting/Vertical.hs 85 - r = dilatationRatio maxh h y z + r = min (dilatationRatio maxh h y z) 2.0 hunk ./Graphics/PDF/Typesetting/Vertical.hs 130 - r = addParaLine verstate style paraSettings c (zip newLines [1..]) + r = addParaLine verstate newStyle paraSettings c (zip newLines [1..]) hunk ./Test/test.hs 342 - glue 3 0 0 + glue 6 0.33 0 hunk ./Test/test.hs 347 - unstyledGlue 3 0 0 + unstyledGlue 6 0.33 0 hunk ./Test/test.hs 355 - unstyledGlue 3 0 0 + unstyledGlue 6 0.33 0 hunk ./Test/test.hs 360 - glue 3 0 0 + glue 6 0.33 0 hunk ./Test/test.hs 362 - glue 3 0 0 + glue 6 0.33 0 hunk ./Test/test.hs 379 - stroke $ Line 10 300 (10+maxw) 300 - displayFormattedText (Rectangle 10 0 (10+maxw) 300) NormalPara Normal myText + stroke $ Line 10 400 (10+maxw) 400 + displayFormattedText (Rectangle 10 0 (10+maxw) 400) NormalPara Normal myText hunk ./Test/test.hs 414 - --newSection (toPDFString "Normal text") Nothing Nothing $ do - -- typesetTest 1 page1 - -- + newSection (toPDFString "Normal text") Nothing Nothing $ do + typesetTest 1 page1 + hunk ./Test/test.hs 421 - page3 <- addPage Nothing - newSection (toPDFString "Circle text") Nothing Nothing $ do - typesetTest 3 page3 + --page3 <- addPage Nothing + --newSection (toPDFString "Circle text") Nothing Nothing $ do + -- typesetTest 3 page3 hunk ./Graphics/PDF/Shading.hs 17 + , applyShading hunk ./Graphics/PDF/Shading.hs 28 --- | Set alpha value for transparency +-- | Fill clipping region with a shading hunk ./Graphics/PDF/Typesetting/Horizontal.hs 134 - glueY (HGlue _ (Just(y,z)) _) = y + glueY (HGlue _ (Just(y,_)) _) = y hunk ./Graphics/PDF/Typesetting/Horizontal.hs 136 - glueZ (HGlue _ (Just(y,z)) _) = z + glueZ (HGlue _ (Just(_,z)) _) = z hunk ./Graphics/PDF/Typesetting/Layout.hs 24 - , containerWidth - , containerCurrentHeight hunk ./Graphics/PDF/Typesetting/Layout.hs 28 + , containerWidth + , containerHeight + , containerCurrentHeight + , containerTextHeight hunk ./Graphics/PDF/Typesetting/Layout.hs 78 - glueY (VGlue w _ _ (Just(y,z)) _) = y + glueY (VGlue _ _ _ (Just(y,_)) _) = y hunk ./Graphics/PDF/Typesetting/Layout.hs 80 - glueZ (VGlue w _ _ (Just(y,z)) _) = z + glueZ (VGlue _ _ _ (Just(_,z)) _) = z hunk ./Graphics/PDF/Typesetting/Layout.hs 120 --- | Create a container +-- | Create a empty container to constraint the amount of line that can be displayed hunk ./Graphics/PDF/Typesetting/Layout.hs 125 - -> Container ps s + -> Container ps s -- ^ New container hunk ./Graphics/PDF/Typesetting/Layout.hs 131 +containerHeight :: Container ps s -> PDFFloat +containerHeight (Container _ _ _ h _ _ _ _) = h + hunk ./Graphics/PDF/Typesetting/Layout.hs 137 +containerTextHeight :: Container ps s -> PDFFloat +containerTextHeight (Container _ _ _ maxh h y z _) = let r = min (dilatationRatio maxh h y z) 2.0 in + glueSize h y z r + hunk ./Graphics/PDF/Typesetting/Vertical.hs 28 -import Graphics.PDF.Shapes(Rectangle(..)) hunk ./Graphics/PDF/Typesetting/Vertical.hs 30 -import Data.Maybe(isJust,fromJust) hunk ./Graphics/PDF/Typesetting/Vertical.hs 72 -dilateVboxes r g@(VGlue h w l (Just(_,_)) s) = +dilateVboxes r g@(VGlue _ w l (Just(_,_)) s) = hunk ./Graphics/PDF/Typesetting/Vertical.hs 81 -drawContainer (Container px py w maxh h y z oldl) = +drawContainer (Container px py _ maxh h y z oldl) = hunk ./Graphics/PDF/Typesetting/Vertical.hs 107 - he (Container _ _ _ _ _ _ _ la) = foldl' (\x y -> x + boxHeight y) 0.0 la hunk ./Graphics/PDF/Typesetting/Vertical.hs 115 -fillContainer :: (ParagraphStyle ps s, ComparableStyle ps) => VerState ps +fillContainer :: (ParagraphStyle ps s, ComparableStyle ps) => VerState ps -- ^ Vertical style for interline glues hunk ./Graphics/PDF/Typesetting/Vertical.hs 118 - -> (Draw(),[VBox ps s]) -- ^ Component and remaining VBoxes -fillContainer verstate c [] = (drawContainer c,[]) -fillContainer verstate c oldl@(Paragraph lineOffset l style paraSettings:l') = + -> (Draw(),[VBox ps s]) -- ^ Component to draw and remaining VBoxes due to overfull container +fillContainer _ c [] = (drawContainer c,[]) +fillContainer verstate c (Paragraph lineOffset l style paraSettings:l') = hunk ./Graphics/PDF/Typesetting.hs 69 + -- * Container + , mkContainer + , fillContainer + , containerX + , containerY + , containerWidth + , containerHeight + , containerCurrentHeight + , containerTextHeight hunk ./Graphics/PDF/Typesetting.hs 88 +import Graphics.PDF.Typesetting.Layout hunk ./Graphics/PDF/Typesetting/Layout.hs 30 + , containerContentHeight + , containerContentRightBorder + , containerContentLeftBorder hunk ./Graphics/PDF/Typesetting/Layout.hs 34 - , containerTextHeight hunk ./Graphics/PDF/Typesetting/Layout.hs 130 +-- | Get the width of the container hunk ./Graphics/PDF/Typesetting/Layout.hs 134 +-- | Get the height of the container hunk ./Graphics/PDF/Typesetting/Layout.hs 138 +-- | Get the current height of the container without glue dilatation hunk ./Graphics/PDF/Typesetting/Layout.hs 142 -containerTextHeight :: Container ps s -> PDFFloat -containerTextHeight (Container _ _ _ maxh h y z _) = let r = min (dilatationRatio maxh h y z) 2.0 in +-- | Get the content height of the container with glue dilatation +containerContentHeight :: Container ps s -> PDFFloat +containerContentHeight (Container _ _ _ maxh h y z _) = let r = min (dilatationRatio maxh h y z) 2.0 in hunk ./Graphics/PDF/Typesetting/Layout.hs 146 + +-- | Get the minimum left border of the container content +containerContentLeftBorder :: Container ps s -> PDFFloat +containerContentLeftBorder (Container _ _ _ _ _ _ _ []) = 0.0 +containerContentLeftBorder (Container _ _ _ _ _ _ _ l) = minimum . map getBoxDelta $ l + +-- | Get the maximum right border of the container content (maybe bigger than container width due to overfull lines) +containerContentRightBorder :: Container ps s -> PDFFloat +containerContentRightBorder (Container _ _ _ _ _ _ _ []) = 0.0 +containerContentRightBorder (Container _ _ _ _ _ _ _ l) = + let xmax = maximum . map rightBorder $ l + rightBorder x = getBoxDelta x + boxWidth x + in + xmax hunk ./Graphics/PDF/Typesetting/Layout.hs 161 +-- | Container horizontal position hunk ./Graphics/PDF/Typesetting/Layout.hs 165 +-- | Container vertical position hunk ./Graphics/PDF/Typesetting/Vertical.hs 103 - -> Either (Draw (),[VBox ps s]) (Container ps s) + -> Either (Draw (),Container ps s,[VBox ps s]) (Container ps s) hunk ./Graphics/PDF/Typesetting/Vertical.hs 110 - Left (drawContainer c,createPara lineNb style paraSettings remainingPar) + Left (drawContainer c,c,createPara lineNb style paraSettings remainingPar) hunk ./Graphics/PDF/Typesetting/Vertical.hs 118 - -> (Draw(),[VBox ps s]) -- ^ Component to draw and remaining VBoxes due to overfull container -fillContainer _ c [] = (drawContainer c,[]) + -> (Draw(),Container ps s,[VBox ps s]) -- ^ Component to draw, new container and remaining VBoxes due to overfull container +fillContainer _ c [] = (drawContainer c,c,[]) hunk ./Graphics/PDF/Typesetting/Vertical.hs 130 - Left (d,remPara) -> (d,remPara ++ l') + Left (d,c',remPara) -> (d,c',remPara ++ l') hunk ./Graphics/PDF/Typesetting/Vertical.hs 138 - (drawContainer c,oldl) + (drawContainer c,c,oldl) hunk ./Graphics/PDF/Typesetting.hs 28 + , VBox + , VerState(..) hunk ./Graphics/PDF/Typesetting.hs 37 + , getBoxes hunk ./Graphics/PDF/Typesetting.hs 71 - , getTextArea hunk ./Graphics/PDF/Typesetting.hs 78 + , containerContentHeight + , containerContentRightBorder + , containerContentLeftBorder hunk ./Graphics/PDF/Typesetting.hs 82 - , containerTextHeight hunk ./Graphics/PDF/Typesetting.hs 103 -displayFormattedText area@(Rectangle xa ya xb yb) defaultVStyle defaultHStyle t = +displayFormattedText (Rectangle xa ya xb yb) defaultVStyle defaultHStyle t = hunk ./Graphics/PDF/Typesetting.hs 109 - let (a, s', boxes) = (runRWS . unTM $ t >>= \x' -> do {return x'} ) area (defaultTmState defaultVStyle defaultHStyle) + let (a, s', boxes) = (runRWS . unTM $ t >>= \x' -> do {return x'} ) () (defaultTmState defaultVStyle defaultHStyle) hunk ./Graphics/PDF/Typesetting.hs 111 - (d,_) = fillContainer (pageSettings s') c boxes + (d,_,_) = fillContainer (pageSettings s') c boxes hunk ./Graphics/PDF/Typesetting.hs 115 ---endParagraphBoxes :: [Letter] ---endParagraphBoxes = [glueBox Nothing 0 10000.0 0,penalty (-infinity)] +-- | Return the list of Vboxes for a text +getBoxes :: (ParagraphStyle ps s) => ps -- ^ default vertical style + -> s -- ^ Default horizontal style + -> TM ps s a -- ^ Typesetting monad + -> [VBox ps s] -- ^ List of boxes +getBoxes defaultVStyle defaultHStyle t = + let (_, _ , boxes) = (runRWS . unTM $ t >>= \x' -> do {return x'} ) () (defaultTmState defaultVStyle defaultHStyle) + in boxes hunk ./Graphics/PDF/Typesetting.hs 139 --- | Get the bounding rectangle containing the text -getTextArea :: TM ps s Rectangle -getTextArea = ask - hunk ./Graphics/PDF/Typesetting.hs 150 -newtype TM ps s a = TM { unTM :: RWS Rectangle [VBox ps s] (TMState ps s) a} +newtype TM ps s a = TM { unTM :: RWS () [VBox ps s] (TMState ps s) a} hunk ./Graphics/PDF/Typesetting.hs 152 - deriving(Monad,MonadWriter [VBox ps s], MonadState (TMState ps s), MonadReader Rectangle, Functor) + deriving(Monad,MonadWriter [VBox ps s], MonadState (TMState ps s), Functor) hunk ./Graphics/PDF/Typesetting.hs 158 -instance MonadReader Rectangle TM hunk ./Graphics/PDF/Typesetting.hs 214 - Rectangle xa _ xb _ <- getTextArea - tell $ [vglue (Just style) h y z (xb-xa) 0] + tell $ [vglue (Just style) h y z 0 0] hunk ./Graphics/PDF/Typesetting.hs 218 - Rectangle xa _ xb _ <- getTextArea - tell $ [vglue Nothing h y z (xb-xa) 0] + tell $ [vglue Nothing h y z 0 0] hunk ./Test/test.hs 417 - --page2 <- addPage Nothing - --newSection (toPDFString "Debug text") Nothing Nothing $ do - -- typesetTest 2 page2 + page2 <- addPage Nothing + newSection (toPDFString "Debug text") Nothing Nothing $ do + typesetTest 2 page2 + + page3 <- addPage Nothing + newSection (toPDFString "Circle text") Nothing Nothing $ do + typesetTest 3 page3 + + page3a <- addPage Nothing + newSection (toPDFString "Standard styles") Nothing Nothing $ do + typesetTest 4 page3a hunk ./Test/test.hs 429 - --page3 <- addPage Nothing - --newSection (toPDFString "Circle text") Nothing Nothing $ do - -- typesetTest 3 page3 - - --page3a <- addPage Nothing - --newSection (toPDFString "Standard styles") Nothing Nothing $ do - -- typesetTest 4 page3a - -- - --page3b <- addPage Nothing - --newSection (toPDFString "Centered style") Nothing Nothing $ do - -- typesetTest 5 page3b + page3b <- addPage Nothing + newSection (toPDFString "Centered style") Nothing Nothing $ do + typesetTest 5 page3b hunk ./Graphics/PDF/Typesetting/Breaking.hs 32 + , leftDilatationFactor + , rightDilatationFactor hunk ./Graphics/PDF/Typesetting/Breaking.hs 37 + , Justification(..) hunk ./Graphics/PDF/Typesetting/Breaking.hs 49 +data Justification = FullJustification + | Centered + | LeftJustification + | RightJustification + deriving(Eq) + hunk ./Graphics/PDF/Typesetting/Breaking.hs 224 - , centered :: !Bool -- ^ Default value false + , centered :: !Justification -- ^ Default value false hunk ./Graphics/PDF/Typesetting/Breaking.hs 228 -defaultBreakingSettings = BRState 100 200 50 10000 10000 10 False +defaultBreakingSettings = BRState 100 200 50 10000 10000 10 FullJustification hunk ./Graphics/PDF/Typesetting/Breaking.hs 525 +-- | How much dilatation is allowed compared to the space width +leftDilatationFactor :: PDFFloat +leftDilatationFactor = 1000.0 + +-- | How much dilatation is allowed compared to the space width +rightDilatationFactor :: PDFFloat +rightDilatationFactor = 1000.0 + hunk ./Graphics/PDF/Typesetting/Breaking.hs 545 - False -> [Glue (ws*h) (h*sy*ws/2.0) (h*sz*ws/3.0) (Just s)] - True -> [ Glue 0 (centeredDilatationFactor*normalW) 0 (Just s) - , Penalty 0 - , Glue normalW (-2*centeredDilatationFactor*normalW) 0 (Just s) - , Kern 0 (Just s) - , Penalty infinity - , Glue 0 (centeredDilatationFactor*normalW) 0 (Just s) - ] + FullJustification -> [Glue (ws*h) (h*sy*ws/2.0) (h*sz*ws/3.0) (Just s)] + Centered -> [ Glue 0 (centeredDilatationFactor*normalW) 0 (Just s) + , Penalty 0 + , Glue normalW (-2*centeredDilatationFactor*normalW) 0 (Just s) + , Kern 0 (Just s) + , Penalty infinity + , Glue 0 (centeredDilatationFactor*normalW) 0 (Just s) + ] + LeftJustification -> [ Glue 0 (leftDilatationFactor*normalW) 0 (Just s) + , Penalty 0 + , Glue normalW (-leftDilatationFactor*normalW) 0 (Just s) + ] + RightJustification -> [ Glue normalW (-rightDilatationFactor*normalW) 0 (Just s) + , Kern 0 (Just s) + , Penalty infinity + , Glue 0 (rightDilatationFactor*normalW) 0 (Just s) + ] hunk ./Graphics/PDF/Typesetting/Breaking.hs 575 - False -> [Glue (ws*h) (h*sy*ws) (h*sz*ws/3.0) (Just s)] - True -> [ Glue 0 (centeredDilatationFactor*normalW) 0 (Just s) - , Penalty 0 - , Glue normalW (-2*centeredDilatationFactor*normalW) 0 (Just s) - , Kern 0 (Just s) - , Penalty infinity - , Glue 0 (centeredDilatationFactor*normalW) 0 (Just s) - ] + FullJustification -> [Glue (ws*h) (h*sy*ws) (h*sz*ws/3.0) (Just s)] + Centered -> [ Glue 0 (centeredDilatationFactor*normalW) 0 (Just s) + , Penalty 0 + , Glue normalW (-2*centeredDilatationFactor*normalW) 0 (Just s) + , Kern 0 (Just s) + , Penalty infinity + , Glue 0 (centeredDilatationFactor*normalW) 0 (Just s) + ] + LeftJustification -> [ Glue 0 (leftDilatationFactor*normalW) 0 (Just s) + , Penalty 0 + , Glue normalW (-leftDilatationFactor*normalW) 0 (Just s) + ] + RightJustification -> [ Glue normalW (-rightDilatationFactor*normalW) 0 (Just s) + , Kern 0 (Just s) + , Penalty infinity + , Glue 0 (rightDilatationFactor*normalW) 0 (Just s) + ] + hunk ./Graphics/PDF/Typesetting/Layout.hs 34 + , containerContentRectangle hunk ./Graphics/PDF/Typesetting/Layout.hs 170 +-- | Return the rectangle containing the text after formatting and glue dilatation +containerContentRectangle :: Container ps s -> Rectangle +containerContentRectangle c = Rectangle (x+l) (y-th) (x+r) y + where + x = containerX c + y = containerY c + th = containerContentHeight c + l = containerContentLeftBorder c + r = containerContentRightBorder c + hunk ./Graphics/PDF/Typesetting/Vertical.hs 32 +-- | Default vertical state hunk ./Graphics/PDF/Typesetting.hs 30 + , Container + , Justification(..) hunk ./Graphics/PDF/Typesetting.hs 39 - , getBoxes hunk ./Graphics/PDF/Typesetting.hs 60 - , setCentered + , setJustification hunk ./Graphics/PDF/Typesetting.hs 75 + , defaultVerState + , getBoxes hunk ./Graphics/PDF/Typesetting.hs 85 + , containerContentRectangle hunk ./Graphics/PDF/Typesetting.hs 258 - when (centered s) $ do + -- Add something before the paragraph + case (centered s) of + Centered -> do hunk ./Graphics/PDF/Typesetting.hs 263 + RightJustification -> do + addLetter (kernBox (styleStart) 0) + addLetter (glueBox (Just styleStart) 0 (rightDilatationFactor*w) 0) + _ -> return () hunk ./Graphics/PDF/Typesetting.hs 268 - if centered s - then do + -- Add something after the paragraph + case centered s of + Centered -> do hunk ./Graphics/PDF/Typesetting.hs 273 - else do - endParagraph False + RightJustification -> addPenalty (-infinity) + _ -> endParagraph False hunk ./Graphics/PDF/Typesetting.hs 367 -setCentered :: Bool -- ^ Centered or fully justified +setJustification :: Justification -- ^ Centered, left or fully justified hunk ./Graphics/PDF/Typesetting.hs 369 -setCentered j = modifyStrict $ \s -> s {paraSettings = (paraSettings s){centered = j}} +setJustification j = modifyStrict $ \s -> s {paraSettings = (paraSettings s){centered = j}} hunk ./Test/test.hs 273 +containerTest :: PDFReference PDFPage -> PDF () +containerTest p = + let c = mkContainer 10 300 200 300 + (d,c',_) = fillContainer (defaultVerState NormalParagraph) c . getBoxes NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ testText + in drawWithPage p $ do + d + let x = containerX c' + y = containerY c' + w = containerWidth c' + h = containerHeight c' + strokeColor red + stroke $ Rectangle x y (x+w) (y-h) + strokeColor blue + stroke $ containerContentRectangle c' + + hunk ./Test/test.hs 419 - stroke $ Rectangle 10 0 (10+maxw) 300 - displayFormattedText ((Rectangle 10 0 (10+maxw) 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do - setCentered True + stroke $ Rectangle 10 200 (10+maxw) 300 + displayFormattedText ((Rectangle 10 200 (10+maxw) 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + setJustification Centered + testText + + strokeColor red + stroke $ Rectangle 10 100 (10+maxw) 200 + displayFormattedText ((Rectangle 10 100 (10+maxw) 200)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + setJustification LeftJustification + testText + + strokeColor red + stroke $ Rectangle 10 0 (10+maxw) 100 + displayFormattedText ((Rectangle 10 0 (10+maxw) 100)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + setJustification RightJustification hunk ./Test/test.hs 458 - newSection (toPDFString "Centered style") Nothing Nothing $ do + newSection (toPDFString "Justifications") Nothing Nothing $ do hunk ./Test/test.hs 460 + + page3c <- addPage Nothing + newSection (toPDFString "Container") Nothing Nothing $ do + containerTest page3c hunk ./Graphics/PDF/Typesetting.hs 36 - , endParagraph + , forceNewLine hunk ./Graphics/PDF/Typesetting.hs 133 -endParagraph :: Style s => Bool -- ^ True if we use the same style to end a paragraph. false for an invisible style +endFullyJustified :: Style s => Bool -- ^ True if we use the same style to end a paragraph. false for an invisible style hunk ./Graphics/PDF/Typesetting.hs 135 -endParagraph r = do +endFullyJustified r = do hunk ./Graphics/PDF/Typesetting.hs 244 + +-- | For a newline and end the current paragraph +forceNewLine :: Style s => Para s () +forceNewLine = do + style <- ask + theStyle <- currentStyle + let w = spaceWidth theStyle + case centered style of + Centered -> do + addLetter (glueBox (Just theStyle) 0 (centeredDilatationFactor*w) 0) + addLetter (penalty (-infinity)) + RightJustification -> addPenalty (-infinity) + _ -> endFullyJustified False hunk ./Graphics/PDF/Typesetting.hs 281 - -- Add something after the paragraph - case centered s of - Centered -> do - addLetter (glueBox (Just styleStart) 0 (centeredDilatationFactor*w) 0) - addLetter (penalty (-infinity)) - RightJustification -> addPenalty (-infinity) - _ -> endParagraph False + forceNewLine hunk ./Test/test.hs 308 - + +testBreakText :: TM StandardParagraphStyle StandardStyle () +testBreakText = do + paragraph $ do + txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor " + txt $ "incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud " + txt $ "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute " + txt $ "irure dolor" + forceNewLine + txt $ " in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla " + txt $ "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia " + txt $ "deserunt mollit anim id est laborum." + hunk ./Test/test.hs 447 + 6 -> do + strokeColor red + stroke $ Rectangle 10 300 (10+maxw) 400 + displayFormattedText ((Rectangle 10 300 (10+maxw) 400)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + setJustification Centered + testBreakText + + strokeColor red + stroke $ Rectangle 10 200 (10+maxw) 300 + displayFormattedText ((Rectangle 10 200 (10+maxw) 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + setJustification LeftJustification + testBreakText + + strokeColor red + stroke $ Rectangle 10 100 (10+maxw) 200 + displayFormattedText ((Rectangle 10 100 (10+maxw) 200)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + setJustification RightJustification + testBreakText + + strokeColor red + stroke $ Rectangle 10 0 (10+maxw) 100 + displayFormattedText ((Rectangle 10 0 (10+maxw) 100)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + setJustification FullJustification + testBreakText hunk ./Test/test.hs 497 + page3d <- addPage Nothing + newSection (toPDFString "New lines") Nothing Nothing $ do + typesetTest 6 page3d + hunk ./Graphics/PDF/Typesetting.hs 248 + endPara + startPara + +endPara :: Style s => Para s () +endPara = do hunk ./Graphics/PDF/Typesetting.hs 262 - + +startPara :: Style s => Para s () +startPara = do + style <- ask + theStyle <- currentStyle + let w = spaceWidth theStyle + case (centered style) of + Centered -> do + addLetter (kernBox (theStyle) 0) + addLetter (glueBox (Just theStyle) 0 (centeredDilatationFactor*w) 0) + RightJustification -> do + addLetter (kernBox (theStyle) 0) + addLetter (glueBox (Just theStyle) 0 (rightDilatationFactor*w) 0) + _ -> return () + hunk ./Graphics/PDF/Typesetting.hs 281 - let (a, s', boxes) = (runRWS . unPara $ closedPara settings) settings f + let (a, s', boxes) = (runRWS . unPara $ closedPara) settings f hunk ./Graphics/PDF/Typesetting.hs 287 - closedPara s = do - styleStart <- currentStyle - let w = spaceWidth styleStart - -- Add something before the paragraph - case (centered s) of - Centered -> do - addLetter (kernBox (styleStart) 0) - addLetter (glueBox (Just styleStart) 0 (centeredDilatationFactor*w) 0) - RightJustification -> do - addLetter (kernBox (styleStart) 0) - addLetter (glueBox (Just styleStart) 0 (rightDilatationFactor*w) 0) - _ -> return () + closedPara = do + startPara hunk ./Graphics/PDF/Typesetting.hs 290 - forceNewLine + endPara hunk ./Graphics/PDF/Typesetting/Breaking.hs 527 -leftDilatationFactor = 1000.0 +leftDilatationFactor = 20.0 hunk ./Graphics/PDF/Typesetting/Breaking.hs 531 -rightDilatationFactor = 1000.0 +rightDilatationFactor = 20.0 hunk ./Test/test.hs 431 - stroke $ Rectangle 10 200 (10+maxw) 300 - displayFormattedText ((Rectangle 10 200 (10+maxw) 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + stroke $ Rectangle 10 300 (10+maxw) 400 + displayFormattedText ((Rectangle 10 300 (10+maxw) 400)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do hunk ./Test/test.hs 437 - stroke $ Rectangle 10 100 (10+maxw) 200 - displayFormattedText ((Rectangle 10 100 (10+maxw) 200)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + stroke $ Rectangle 10 200 (10+maxw) 300 + displayFormattedText ((Rectangle 10 200 (10+maxw) 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do hunk ./Test/test.hs 443 - stroke $ Rectangle 10 0 (10+maxw) 100 - displayFormattedText ((Rectangle 10 0 (10+maxw) 100)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + stroke $ Rectangle 10 100 (10+maxw) 200 + displayFormattedText ((Rectangle 10 100 (10+maxw) 200)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do hunk ./Test/test.hs 447 + strokeColor red + stroke $ Rectangle 10 0 (10+maxw) 100 + drawText $ text (PDFFont Helvetica_Bold 24) 10 100 (toPDFString "Lorem ipsum") + stroke $ Line 10 120 (10 + textWidth (PDFFont Helvetica_Bold 24) (toPDFString "Lorem ipsum") ) 120 + displayFormattedText ((Rectangle 10 0 (10+maxw) 100)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + setJustification LeftJustification + paragraph $ do + setStyle (Font (PDFFont Helvetica_Bold 24) black black) + txt $ "Lorem ipsum" hunk ./Graphics/PDF/Annotation.hs 29 +import Debug.Trace hunk ./Graphics/PDF/Annotation.hs 41 -data TextAnnotation = TextAnnotation PDFString [PDFFloat] TextIcon -data URLLink = URLLink PDFString [PDFFloat] String Bool -data PDFLink = PDFLink PDFString [PDFFloat] (PDFReference PDFPage) PDFFloat PDFFloat Bool +data TextAnnotation = TextAnnotation + PDFString -- Content + [PDFFloat] -- Rect + TextIcon +data URLLink = URLLink + PDFString -- Content + [PDFFloat] -- Rect + String -- URL + Bool -- Border +data PDFLink = PDFLink + PDFString -- Content + [PDFFloat] -- Rect + (PDFReference PDFPage) -- Page + PDFFloat -- x + PDFFloat -- y + Bool -- Border hunk ./Graphics/PDF/Annotation.hs 59 +det :: Matrix -> PDFFloat +det (Matrix a b c d _ _) = a*d - b*c + +inverse :: Matrix -> Matrix +inverse m@(Matrix a b c d e f) = (Matrix (d/de) (-b/de) (-c/de) (a/de) 0 0) * (Matrix 1 0 0 1 (-e) (-f)) + where + de = det m + +applyMatrixToRectangle :: Matrix -> [PDFFloat] -> [PDFFloat] +applyMatrixToRectangle m [xa,ya,xb,yb] = + let (xa',ya') = m `applyTo` (xa,ya) + (xa'',yb') = m `applyTo` (xa,yb) + (xb',ya'') = m `applyTo` (xb,ya) + (xb'',yb'') = m `applyTo` (xb,yb) + x1 = minimum [xa',xa'',xb',xb''] + x2 = maximum [xa',xa'',xb',xb''] + y1 = minimum [ya',ya'',yb',yb''] + y2 = maximum [ya',ya'',yb',yb''] + in + [x1,y1,x2,y2] + where + applyTo (Matrix a b c d e f) (x,y) = (a*x+b*y+e,c*x+d*y+f) + +applyMatrixToRectangle _ a = a + + + hunk ./Graphics/PDF/Annotation.hs 126 + annotationToGlobalCoordinates (TextAnnotation a r b) = do + m <- currentMatrix + let im = m + gr = im `applyMatrixToRectangle` r + return $ TextAnnotation a gr b hunk ./Graphics/PDF/Annotation.hs 144 - + annotationToGlobalCoordinates (URLLink a r b c) = do + m <- currentMatrix + let im = m + gr = im `applyMatrixToRectangle` r + return $ URLLink a gr b c + hunk ./Graphics/PDF/Annotation.hs 168 + annotationToGlobalCoordinates (PDFLink a r b c d e) = do + m <- currentMatrix + let im = m + gr = im `applyMatrixToRectangle` r + return $ PDFLink a gr b c d e hunk ./Graphics/PDF/Annotation.hs 177 - modifyStrict $ \s -> s {annots = (AnyAnnotation annot):(annots s)} + annot' <- annotationToGlobalCoordinates annot + trace (show (annotationRect annot) ++ " " ++ show (annotationRect annot')) $ modifyStrict $ \s -> s {annots = (AnyAnnotation annot'):(annots s)} hunk ./Graphics/PDF/Coordinates.hs 36 --- | A transformation matrix. An affine transformation a b c d e f --- --- @ --- a b e --- c d f --- 0 0 1 --- @ - -data Matrix = Matrix !PDFFloat !PDFFloat !PDFFloat !PDFFloat !PDFFloat !PDFFloat deriving (Eq) hunk ./Graphics/PDF/Coordinates.hs 37 --- | Identity matrix -identity :: Matrix -identity = Matrix 1.0 0 0 1.0 0 0 hunk ./Graphics/PDF/Coordinates.hs 38 -instance Show Matrix where - show (Matrix ma mb mc md me mf) = "Matrix " ++ (unwords [(show ma),(show mb),(show mc),(show md),(show me),(show mf)]) hunk ./Graphics/PDF/Coordinates.hs 39 -instance Num Matrix where - -- Matrix addition - (+) (Matrix ma mb mc md me mf ) (Matrix na nb nc nd ne nf) = - Matrix (ma+na) (mb+nb) (mc+nc) (md+nd) (me+ne) (mf+nf) - (*) (Matrix ma mb mc md me mf) (Matrix na nb nc nd ne nf) = - Matrix (ma*na+mb*nc) (ma*nb + mb*nd ) (mc*na+md*nc) (mc*nb +md*nd) (me*na+mf*nc+ne) (me*nb+mf*nd+nf) - negate (Matrix ma mb mc md me mf ) = - Matrix (-ma) (-mb) (-mc) (-md) (-me) (-mf) - abs m = m - signum _ = identity - fromInteger i = Matrix r 0 0 r 0 0 - where - r = fromInteger i hunk ./Graphics/PDF/Coordinates.hs 43 -applyMatrix (Matrix a b c d e f) = +applyMatrix m@(Matrix a b c d e f) = do + multiplyCurrentMatrixWith m hunk ./Graphics/PDF/Draw.hs 66 + , Matrix(..) + , identity + , currentMatrix + , multiplyCurrentMatrixWith hunk ./Graphics/PDF/Draw.hs 86 +-- | A transformation matrix. An affine transformation a b c d e f +-- +-- @ +-- a b e +-- c d f +-- 0 0 1 +-- @ + +data Matrix = Matrix !PDFFloat !PDFFloat !PDFFloat !PDFFloat !PDFFloat !PDFFloat deriving (Eq) + +-- | Identity matrix +identity :: Matrix +identity = Matrix 1.0 0 0 1.0 0 0 + +instance Show Matrix where + show (Matrix ma mb mc md me mf) = "Matrix " ++ (unwords [(show ma),(show mb),(show mc),(show md),(show me),(show mf)]) + +instance Num Matrix where + -- Matrix addition + (+) (Matrix ma mb mc md me mf ) (Matrix na nb nc nd ne nf) = + Matrix (ma+na) (mb+nb) (mc+nc) (md+nd) (me+ne) (mf+nf) + (*) (Matrix ma mb mc md me mf) (Matrix na nb nc nd ne nf) = + Matrix (ma*na+mb*nc) (ma*nb + mb*nd ) (mc*na+md*nc) (mc*nb +md*nd) (me*na+mf*nc+ne) (me*nb+mf*nd+nf) + negate (Matrix ma mb mc md me mf ) = + Matrix (-ma) (-mb) (-mc) (-md) (-me) (-mf) + abs m = m + signum _ = identity + fromInteger i = Matrix r 0 0 r 0 0 + where + r = fromInteger i + hunk ./Graphics/PDF/Draw.hs 124 + annotationToGlobalCoordinates :: a -> Draw a + annotationToGlobalCoordinates = return hunk ./Graphics/PDF/Draw.hs 158 + , matrix :: [Matrix] hunk ./Graphics/PDF/Draw.hs 219 - DrawState names emptyRsrc M.empty M.empty M.empty M.empty emptyDictionary [] M.empty M.empty M.empty + DrawState names emptyRsrc M.empty M.empty M.empty M.empty emptyDictionary [] M.empty M.empty M.empty [identity] hunk ./Graphics/PDF/Draw.hs 225 +pushMatrixStack :: Matrix -> Draw () +pushMatrixStack m = do + modifyStrict $ \s -> s {matrix = m : matrix s} + +popMatrixStack :: Draw () +popMatrixStack = do + modifyStrict $ \s -> s {matrix = tail (matrix s)} + +multiplyCurrentMatrixWith :: Matrix -> Draw () +multiplyCurrentMatrixWith m' = modifyStrict $ \s -> s {matrix = let (m:l) = matrix s in (m * m'):l + } + +currentMatrix :: Draw Matrix +currentMatrix = gets matrix >>= return . head hunk ./Graphics/PDF/Draw.hs 245 + pushMatrixStack identity hunk ./Graphics/PDF/Draw.hs 247 + popMatrixStack hunk ./Test/test.hs 78 -testAnnotation :: Draw () -testAnnotation = do - strokeColor red - newAnnotation (URLLink (toPDFString "Go to my blog") [0,0,100,100] "http://www.alpheccar.org" True) - drawText $ text (PDFFont Times_Roman 12) 10 30 (toPDFString "Go to my blog") - stroke $ Rectangle 0 0 100 100 - newAnnotation (TextAnnotation (toPDFString "Key annotation") [100,100,130,130] Key) +testAnnotation ::PDFReference PDFPage -> PDF () +testAnnotation p = do + drawWithPage p $ do + r + + p1 <- addPage Nothing + drawWithPage p1 $ do + withNewContext $ do + applyMatrix $ translate 50 0 + r + p2 <- addPage Nothing + drawWithPage p2 $ do + withNewContext $ do + applyMatrix $ rotate (Degree 45) + r + p3 <- addPage Nothing + drawWithPage p3 $ do + withNewContext $ do + applyMatrix $ scale 1 3 + r + where r = do + strokeColor red + newAnnotation (URLLink (toPDFString "Go to my blog") [0,0,200,100] "http://www.alpheccar.org" True) + drawText $ text (PDFFont Times_Roman 12) 10 30 (toPDFString "Go to my blog") + stroke $ Rectangle 0 0 200 100 + newAnnotation (TextAnnotation (toPDFString "Key annotation") [100,100,130,130] Key) hunk ./Test/test.hs 568 - drawWithPage page10 $ do - testAnnotation + testAnnotation page10 hunk ./Graphics/PDF/Annotation.hs 29 -import Debug.Trace +--import Debug.Trace hunk ./Graphics/PDF/Annotation.hs 59 -det :: Matrix -> PDFFloat -det (Matrix a b c d _ _) = a*d - b*c - -inverse :: Matrix -> Matrix -inverse m@(Matrix a b c d e f) = (Matrix (d/de) (-b/de) (-c/de) (a/de) 0 0) * (Matrix 1 0 0 1 (-e) (-f)) - where - de = det m +--det :: Matrix -> PDFFloat +--det (Matrix a b c d _ _) = a*d - b*c +-- +--inverse :: Matrix -> Matrix +--inverse m@(Matrix a b c d e f) = (Matrix (d/de) (-b/de) (-c/de) (a/de) 0 0) * (Matrix 1 0 0 1 (-e) (-f)) +-- where +-- de = det m hunk ./Graphics/PDF/Annotation.hs 80 - applyTo (Matrix a b c d e f) (x,y) = (a*x+b*y+e,c*x+d*y+f) + applyTo (Matrix a b c d e f) (x,y) = (a*x-b*y+e,-c*x+d*y+f) hunk ./Graphics/PDF/Annotation.hs 178 - trace (show (annotationRect annot) ++ " " ++ show (annotationRect annot')) $ modifyStrict $ \s -> s {annots = (AnyAnnotation annot'):(annots s)} + modifyStrict $ \s -> s {annots = (AnyAnnotation annot'):(annots s)} hunk ./Test/test.hs 96 - applyMatrix $ scale 1 3 + applyMatrix $ scale 3 1 hunk ./Graphics/PDF/Typesetting/Breaking.hs 612 -createLetterBoxes settings s ((wa,'.'):b@(_,bc):l') | bc /= ' ' = (createChar s wa '.'): (punctuationGlue settings s ++ createLetterBoxes settings s (b:l') ) - | otherwise = (createChar s wa '.') : (punctuationGlue settings s ++ createLetterBoxes settings s l') -createLetterBoxes settings s ((_,'/'):(w,'-'):l) = hyphenPenalty settings s w : createLetterBoxes settings s l +createLetterBoxes settings s ((wa,t):b@(_,bc):l') | t `elem` ".,;:!?" && bc /= ' ' = (createChar s wa t): (punctuationGlue settings s ++ createLetterBoxes settings s (b:l') ) + | t `elem` ".,;:!?" = (createChar s wa t) : (punctuationGlue settings s ++ createLetterBoxes settings s l') + | t == '/' && bc == '-' = hyphenPenalty settings s wa : createLetterBoxes settings s l' + | otherwise = (createChar s wa t) : createLetterBoxes settings s (b:l') hunk ./Graphics/PDF/Typesetting/Breaking.hs 617 +createLetterBoxes settings s ((w,'-'):l) = (createChar s w '-') : penalty 0 : createLetterBoxes settings s l hunk ./Graphics/PDF/Typesetting/Breaking.hs 619 - + hunk ./Graphics/PDF/Typesetting/Breaking.hs 536 + -> PDFFloat hunk ./Graphics/PDF/Typesetting/Breaking.hs 538 -spaceGlueBox settings s = +spaceGlueBox settings s f = hunk ./Graphics/PDF/Typesetting/Breaking.hs 546 - FullJustification -> [Glue (ws*h) (h*sy*ws/2.0) (h*sz*ws/3.0) (Just s)] + FullJustification -> [Glue (ws*h) (h*sy*ws/2.0*f) (h*sz*ws/3.0) (Just s)] hunk ./Graphics/PDF/Typesetting/Breaking.hs 562 - ] - --- | Add a glue to the stream -punctuationGlue :: Style s => BRState -- ^ Paragraph settings - -> s -- ^ The style - -> [Letter s] -punctuationGlue settings s = - let ws = (textWidth (textFont . textStyle $ s) (toPDFString " ") ) - h = scaleSpace . textStyle $ s - sy = scaleDilatation . textStyle $ s - sz = scaleCompression . textStyle $ s - normalW = ws * h - in - case (centered settings) of - FullJustification -> [Glue (ws*h) (h*sy*ws) (h*sz*ws/3.0) (Just s)] - Centered -> [ Glue 0 (centeredDilatationFactor*normalW) 0 (Just s) - , Penalty 0 - , Glue normalW (-2*centeredDilatationFactor*normalW) 0 (Just s) - , Kern 0 (Just s) - , Penalty infinity - , Glue 0 (centeredDilatationFactor*normalW) 0 (Just s) - ] - LeftJustification -> [ Glue 0 (leftDilatationFactor*normalW) 0 (Just s) - , Penalty 0 - , Glue normalW (-leftDilatationFactor*normalW) 0 (Just s) - ] - RightJustification -> [ Glue normalW (-rightDilatationFactor*normalW) 0 (Just s) - , Kern 0 (Just s) - , Penalty infinity - , Glue 0 (rightDilatationFactor*normalW) 0 (Just s) - ] + ] hunk ./Graphics/PDF/Typesetting/Breaking.hs 583 -createLetterBoxes settings s ((wa,t):b@(_,bc):l') | t `elem` ".,;:!?" && bc /= ' ' = (createChar s wa t): (punctuationGlue settings s ++ createLetterBoxes settings s (b:l') ) - | t `elem` ".,;:!?" = (createChar s wa t) : (punctuationGlue settings s ++ createLetterBoxes settings s l') - | t == '/' && bc == '-' = hyphenPenalty settings s wa : createLetterBoxes settings s l' - | otherwise = (createChar s wa t) : createLetterBoxes settings s (b:l') -createLetterBoxes settings s ((_,' '):l) = (spaceGlueBox settings s) ++ createLetterBoxes settings s l +createLetterBoxes settings s ((wa,'.'):b@(_,bc):l') | bc /= ' ' = (createChar s wa '.') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s (b:l') )) + | otherwise = (createChar s wa '.') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s l')) +createLetterBoxes settings s ((wa,','):b@(_,bc):l') | bc /= ' ' = (createChar s wa ',') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s (b:l') )) + | otherwise = (createChar s wa ',') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s l')) +createLetterBoxes settings s ((wa,';'):b@(_,bc):l') | bc /= ' ' = (createChar s wa ';') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s (b:l') )) + | otherwise = (createChar s wa ';') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s l')) +createLetterBoxes settings s ((wa,'!'):b@(_,bc):l') | bc /= ' ' = (createChar s wa '!') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s (b:l') )) + | otherwise = (createChar s wa '!') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s l')) +createLetterBoxes settings s ((wa,'?'):b@(_,bc):l') | bc /= ' ' = (createChar s wa '?') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s (b:l') )) + | otherwise = (createChar s wa '?') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s l')) +createLetterBoxes settings s ((wa,':'):b@(_,bc):l') | bc /= ' ' = (createChar s wa ':') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s (b:l') )) + | otherwise = (createChar s wa ':') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s l')) + +createLetterBoxes settings s ((_,'/'):(w,'-'):l) = hyphenPenalty settings s w : createLetterBoxes settings s l +createLetterBoxes settings s ((_,' '):l) = (spaceGlueBox settings s 1.0) ++ createLetterBoxes settings s l hunk ./Graphics/PDF/Typesetting/Breaking.hs 601 --- WARNING : must generate a list of LETTERS --- word are created with the analysis of style just above hunk ./Graphics/PDF/Typesetting/StandardStyle.hs 33 - isSameStyleAs _ _ = False + --isSameStyleAs _ _ = False hunk ./Graphics/PDF/Typesetting.hs 131 - --- | End the current paragraph with or without using the same style -endFullyJustified :: Style s => Bool -- ^ True if we use the same style to end a paragraph. false for an invisible style - -> Para s () -endFullyJustified r = do - if r - then - glue 0 10000.0 0 - else - tell $ [glueBox Nothing 0 10000.0 0] - addPenalty (-infinity) hunk ./Graphics/PDF/Typesetting.hs 239 + +-- | End the current paragraph with or without using the same style +endFullyJustified :: Style s => Bool -- ^ True if we use the same style to end a paragraph. false for an invisible style + -> Para s () +endFullyJustified r = do + if r + then + glue 0 10000.0 0 + else + tell $ [glueBox Nothing 0 10000.0 0] + addPenalty (-infinity) hunk ./Graphics/PDF/Typesetting.hs 271 + addLetter $ penalty infinity hunk ./Graphics/PDF/Typesetting.hs 275 + addLetter $ penalty infinity hunk ./Graphics/PDF/Typesetting/Breaking.hs 282 -createBreaknode prev (ZList _ (w,y,z,_,FlaggedPenalty _ _ _) []) = BreakNode (w) (y) (z) 0.0 True 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,Penalty _) []) = BreakNode w (y) (z) 0.0 False 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,Glue w' y' z' _) []) = BreakNode (w + w') (y+y') (z+z') 0.0 False 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,a) []) = BreakNode (w + glueSizeWithRatio a 0.0) (y) (z) 0.0 False 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,FlaggedPenalty _ p _) _) | p <= infinity = BreakNode w y z 0.0 True 0 0.0 prev ---createBreaknode prev (ZList _ (w,y,z,_,Penalty p) _) | p <= infinity = BreakNode w y z 0.0 False 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,Letter _ _ _) _) = BreakNode w y z 0.0 False 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,AChar _ _ _) _) = BreakNode w y z 0.0 False 0 0.0 prev -createBreaknode prev (ZList _ (w,y,z,_,Kern _ _) _) = BreakNode w y z 0.0 False 0 0.0 prev +createBreaknode prev a@(ZList _ (_,_,_,_,FlaggedPenalty _ _ _) []) = breakN prev True a +createBreaknode prev a@(ZList _ (_,_,_,_,Penalty _) []) = breakN prev False a +createBreaknode prev a@(ZList _ (_,_,_,_,Glue _ _ _ _) []) = breakN prev False a +createBreaknode prev a@(ZList _ (_,_,_,_,_) []) = breakN prev False a +createBreaknode prev a@(ZList _ (_,_,_,_,FlaggedPenalty _ p _) _) | p <= infinity = breakN prev True a +createBreaknode prev a@(ZList _ (_,_,_,_,Letter _ _ _) _) = breakN prev False a +createBreaknode prev a@(ZList _ (_,_,_,_,AChar _ _ _) _) = breakN prev False a +createBreaknode prev a@(ZList _ (_,_,_,_,Kern _ _) _) = breakN prev False a hunk ./Graphics/PDF/Typesetting/Breaking.hs 292 +breakN :: Maybe (Int,Int,Int,BreakNode) -> Bool -> ZList s -> BreakNode +breakN prev t a = let (w,y,z) = getDim a in BreakNode w y z 0.0 t 0 0.0 prev + +-- | Get cumulated dimension for following box +getDim :: ZList s -> (PDFFloat,PDFFloat,PDFFloat) +getDim (ZList _ (w,y,z,_,Letter _ _ _) _) = (w,y,z) +getDim (ZList _ (w,y,z,_,AChar _ _ _) _) = (w,y,z) +getDim (ZList _ (w,y,z,_,Kern _ _) _) = (w,y,z) +getDim (ZList _ (w,y,z,_,_) []) = (w,y,z) +getDim a = if theEnd a then error "Can't find end of paragraph" else getDim (moveRight a) + hunk ./Graphics/PDF/Typesetting/Breaking.hs 608 -createLetterBoxes settings s ((w,'-'):l) = (createChar s w '-') : penalty 0 : createLetterBoxes settings s l hunk ./Graphics/PDF/Typesetting/Breaking.hs 483 - [(ra,theLine,t')] + [(ra,theLine,t)] hunk ./Graphics/PDF/Typesetting/Breaking.hs 490 - (ra,theLine ++ [hyphenBox s],t') : cutList t' ba l + (ra,theLine ++ [hyphenBox s],t) : cutList t' ba l hunk ./Graphics/PDF/Typesetting/Breaking.hs 495 - (ra,theLine,t') : cutList t' ba l + (ra,theLine,t) : cutList t' ba l hunk ./Test/test.hs 294 - let c = mkContainer 10 300 200 300 - (d,c',_) = fillContainer (defaultVerState NormalParagraph) c . getBoxes NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ testText + let c = mkContainer 10 300 200 90 + (d,c',r) = fillContainer (defaultVerState NormalParagraph) c . getBoxes NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ testText + cb = mkContainer 10 210 200 210 + (d',c'',_) = fillContainer (defaultVerState NormalParagraph) cb r hunk ./Test/test.hs 300 + d' hunk ./Test/test.hs 309 + stroke $ containerContentRectangle c'' hunk ./Graphics/PDF/LowLevel/Types.hs 58 -newtype PDFFloat = PDFFloat Double deriving(Eq,Ord,Num,Fractional,Floating,RealFrac,Real,Random) +newtype PDFFloat = PDFFloat Double deriving(Eq,Ord,Num,Fractional,Floating,RealFrac,Real,Random,Read) hunk ./Graphics/PDF/Annotation.hs 29 +import Control.Monad.State(gets) hunk ./Graphics/PDF/Annotation.hs 81 - applyTo (Matrix a b c d e f) (x,y) = (a*x-b*y+e,-c*x+d*y+f) + applyTo (Matrix a b c d e f) (x,y) = (a*x+c*y+e,b*x+d*y+f) hunk ./Graphics/PDF/Annotation.hs 128 - m <- currentMatrix - let im = m - gr = im `applyMatrixToRectangle` r + gr <- transformAnnotRect r hunk ./Graphics/PDF/Annotation.hs 144 - m <- currentMatrix - let im = m - gr = im `applyMatrixToRectangle` r + gr <- transformAnnotRect r hunk ./Graphics/PDF/Annotation.hs 166 - m <- currentMatrix - let im = m - gr = im `applyMatrixToRectangle` r + gr <- transformAnnotRect r hunk ./Graphics/PDF/Annotation.hs 168 + +transformAnnotRect :: [PDFFloat] -> Draw [PDFFloat] +transformAnnotRect r = do + l <- gets matrix + let m = foldr (*) identity l + return $ m `applyMatrixToRectangle` r hunk ./Graphics/PDF/Draw.hs 89 --- a b e --- c d f --- 0 0 1 +-- a b 0 +-- c d 0 +-- e f 1 hunk ./Graphics/PDF/Draw.hs 95 - + hunk ./Graphics/PDF/Draw.hs 108 - Matrix (ma*na+mb*nc) (ma*nb + mb*nd ) (mc*na+md*nc) (mc*nb +md*nd) (me*na+mf*nc+ne) (me*nb+mf*nd+nf) + Matrix (ma*na+mb*nc) (ma*nb+mb*nd) (mc*na+md*nc) (mc*nb +md*nd) (me*na+mf*nc+ne) (me*nb+mf*nd+nf) hunk ./Graphics/PDF/Draw.hs 233 + hunk ./Graphics/PDF/Draw.hs 235 -multiplyCurrentMatrixWith m' = modifyStrict $ \s -> s {matrix = let (m:l) = matrix s in (m * m'):l - } +multiplyCurrentMatrixWith m' = modifyStrict $ \s -> s {matrix = let (m:l) = matrix s in (m' * m ):l} + hunk ./Graphics/PDF/LowLevel/Types.hs 58 -newtype PDFFloat = PDFFloat Double deriving(Eq,Ord,Num,Fractional,Floating,RealFrac,Real,Random,Read) +newtype PDFFloat = PDFFloat Double deriving(Eq,Ord,Num,Fractional,Floating,RealFrac,Real,Random) hunk ./Test/test.hs 90 + strokeColor red + stroke $ Line 0 0 100 0 + applyMatrix $ translate 100 0 + strokeColor green + stroke $ Line 0 0 100 0 hunk ./Test/test.hs 96 - applyMatrix $ rotate (Degree 45) - r + applyMatrix $ rotate (Degree (-20)) + strokeColor $ Rgb 1 1 0 + stroke $ Line 0 0 100 0 + applyMatrix $ translate 50 50 + strokeColor blue + stroke $ Line 0 0 100 0 + withNewContext $ do + applyMatrix $ rotate (Degree 45) + r + strokeColor black + stroke $ Line 0 0 100 0 hunk ./Graphics/PDF/Image.hs 245 +-- The read is not lazy. The whole image will be loaded into memory hunk ./Graphics/PDF/Image.hs 254 - img <- liftIO $ B.readFile f + h' <- liftIO $ openBinaryFile f ReadMode + nb <- liftIO $ hFileSize h' + img <- liftIO $ B.hGet h' (fromIntegral nb) + liftIO $ hClose h' hunk ./Test/test.hs 601 + --Right jpg <- readJpegFile "stardoll_vigo_550x410.jpg" hunk ./Graphics/PDF/Image.hs 37 +import Control.Exception as E hunk ./Graphics/PDF/Image.hs 244 - +withFile :: String -> (Handle -> IO c) -> IO c +withFile name = bracket (openBinaryFile name ReadMode) hClose + hunk ./Graphics/PDF/Image.hs 251 -readJpegFile f = do - h <- liftIO $ openBinaryFile f ReadMode - r <- runFA (analyzeJpeg h) - liftIO $ hClose h +readJpegFile f = catchJust ioErrors (do + r <- liftIO $ withFile f $ \h -> do + runFA (analyzeJpeg h) hunk ./Graphics/PDF/Image.hs 256 - h' <- liftIO $ openBinaryFile f ReadMode - nb <- liftIO $ hFileSize h' - img <- liftIO $ B.hGet h' (fromIntegral nb) - liftIO $ hClose h' - return (Right $ JpegFile bits_per_component width height color_space (fromLazyByteString img)) - Left s -> return $ Left s + img <- liftIO $ withFile f $ \h' -> do + nb <- hFileSize h' + B.hGet h' (fromIntegral nb) + return (Right $ JpegFile bits_per_component width height color_space (fromLazyByteString img)) + Left s -> return $ Left s) (\err -> return $ Left (show err)) hunk ./Test/test.hs 601 - --Right jpg <- readJpegFile "stardoll_vigo_550x410.jpg" hunk ./Graphics/PDF/Image.hs 21 + , jpegBounds hunk ./Graphics/PDF/Image.hs 263 - +-- | Get the JPEG bounds +jpegBounds :: JpegFile -> (PDFFloat,PDFFloat) +jpegBounds (JpegFile _ w h _ _) = (w,h) + hunk ./Graphics/PDF/Typesetting/Box.hs 94 + -- + -- > Default implementation + -- > styleHeight = getHeight . textFont . textStyle + -- hunk ./Graphics/PDF/Typesetting/Box.hs 101 + -- + -- > Default implementation + -- > styleDescent = getDescent . textFont . textStyle + -- hunk ./Graphics/PDF/Typesetting/Vertical.hs 33 +-- +-- > Default values +-- > baselineskip = (12,0.17,0.0) +-- > lineskip = (3.0,0.33,0.0) +-- > lineskiplimit = 2 +-- hunk ./Graphics/PDF/Typesetting.hs 14 - -- * Typesetting - -- ** Types + -- * Types + -- ** Boxes hunk ./Graphics/PDF/Typesetting.hs 18 + , Letter(..) + , BoxDimension + -- ** Styles hunk ./Graphics/PDF/Typesetting.hs 26 - , Letter(..) - , BoxDimension + , ComparableStyle(..) + -- ** Typesetting monads hunk ./Graphics/PDF/Typesetting.hs 30 - , ComparableStyle(..) + -- ** Containers hunk ./Graphics/PDF/Typesetting.hs 42 - -- * Paragraph construction operators + -- ** Paragraph construction operators hunk ./Graphics/PDF/Typesetting.hs 45 --- , nullChar hunk ./Graphics/PDF/Typesetting.hs 46 - -- * Misc hunk ./Graphics/PDF/Typesetting.hs 47 + -- ** Functions useful to change the paragraph style + , getParaStyle + , setParaStyle + -- ** Container + , mkContainer + , fillContainer + , defaultVerState + , getBoxes + , containerX + , containerY + , containerWidth + , containerHeight + , containerContentHeight + , containerContentRightBorder + , containerContentLeftBorder + , containerCurrentHeight + , containerContentRectangle hunk ./Graphics/PDF/Typesetting.hs 86 - -- * Styles - -- ** Functions useful to change the paragraph style - , getParaStyle - , setParaStyle - -- * Container - , mkContainer - , fillContainer - , defaultVerState - , getBoxes - , containerX - , containerY - , containerWidth - , containerHeight - , containerContentHeight - , containerContentRightBorder - , containerContentLeftBorder - , containerCurrentHeight - , containerContentRectangle hunk ./HPDF.cabal 10 -homepage: http://www.alpheccar.org/en/posts/show/82 +homepage: http://www.alpheccar.org/en/posts/show/84 hunk ./HPDF.cabal 11 -build-depends: base, haskell98,mtl,encoding >= 0.1 ,zlib >= 0.3, binary >= 0.3 +build-depends: base, haskell98,mtl,encoding >= 0.2 ,zlib >= 0.3, binary >= 0.3 addfile ./Graphics/PDF/Data/Trie.hs hunk ./Graphics/PDF/Data/Trie.hs 1 - +module Trie ( + MapString + , lookup + , insert + , fromList + ) + where + +import Prelude hiding(lookup) +import qualified Data.Map as M + +data MapString v = EmptyTrie + | Trie (Maybe v) (M.Map Char (MapString v)) + deriving(Eq,Show) + +fromList :: [(String,v)] -> MapString v +fromList = foldr addElem EmptyTrie + where + addElem (key,v) a = insert key v a + +lookup :: String + -> MapString v + -> [v] +lookup _ EmptyTrie = [] +lookup [] (Trie (Just a) b) = [a] +lookup [] (Trie Nothing b) = [] +lookup (c:s) (Trie Nothing tc) = (M.lookup c tc >>= lookup s) +lookup (c:s) (Trie (Just tn) tc) = tn:(M.lookup c tc >>= lookup s) + +insert :: String + -> v + -> MapString v + -> MapString v +insert [] v EmptyTrie = Trie (Just v) M.empty +insert (k:l) v EmptyTrie = Trie Nothing (M.singleton k (insert l v EmptyTrie)) + +insert [] v (Trie a b) = Trie (Just v) b +insert (k:s) v (Trie tn tc) = + case M.lookup k tc of + Nothing -> Trie tn (M.insert k (insert s v EmptyTrie) tc) + Just f -> Trie tn (M.insert k (insert s v f) tc) + addfile ./Graphics/PDF/Hyphenate.hs hunk ./Graphics/PDF/Hyphenate.hs 1 +module Hyphenate where + +import Data.Char(isAlpha,isDigit,toLower) +import qualified Trie as T +import Data.List(tails,unfoldr) + +exceptionPoints :: String -> [Int] +exceptionPoints s = 0 : map onlyHyphen s + where + onlyHyphen '-' = 1 + onlyHyphen _ = 0 + +removeHyphen :: String -> String +removeHyphen = filter ((/=) '-') + +exceptions = T.fromList . map createException $ exceptionList + where + createException x = (removeHyphen x,exceptionPoints x) + +exceptionList = [ + "as-so-ciate" + , "as-so-ciates" + , "dec-li-na-tion" + , "oblig-a-tory" + , "phil-an-thropic" + , "present" + , "presents" + , "project" + , "projects" + , "reci-procity" + , "re-cog-ni-zance" + , "ref-or-ma-tion" + , "ret-ri-bu-tion ta-ble" + ] + +isChar :: Char -> Bool +isChar = not . isDigit + +fromDigit :: Char -> Int +fromDigit c = fromEnum c - fromEnum '0' + +toNumber :: Char -> Int +toNumber x = if isChar x then 0 else fromDigit x + +simplify :: [Int] -> [Int] +simplify (a:b:c:l) | a /= 0 && b == 0 && c /= 0 = a:simplify (c:l) + | otherwise = a:simplify (b:c:l) +simplify a = a + +split :: (Char -> Bool) -> String -> [Int] +split f = simplify . map toNumber . unfoldr (split' f) + +split' :: (Char -> Bool) -> String -> Maybe (Char, String) +split' f l | null l = Nothing + | otherwise = if null h then Just (' ', drop 1 t) else Just (head h, t) + where (h, t) = span f l + +convertPattern :: String -> (String,[Int]) +convertPattern s = + let s' = filter isChar s + p = split isDigit s + in + (s',p) + +patterns = T.fromList . map convertPattern $ patternList + +patternList = +-- Knuth and Liang's original hyphenation patterns from classic TeX. +-- In the public domain. + [ + ".ach4", ".ad4der", ".af1t", ".al3t", ".am5at", ".an5c", ".ang4", ".ani5m", ".ant4", ".an3te", ".anti5s", ".ar5s", + ".ar4tie", ".ar4ty", ".as3c", ".as1p", ".as1s", ".aster5", ".atom5", ".au1d", ".av4i", ".awn4", ".ba4g", ".ba5na", + ".bas4e", ".ber4", ".be5ra", ".be3sm", ".be5sto", ".bri2", ".but4ti", ".cam4pe", ".can5c", ".capa5b", ".car5ol", + ".ca4t", ".ce4la", ".ch4", ".chill5i", ".ci2", ".cit5r", ".co3e", ".co4r", ".cor5ner", ".de4moi", ".de3o", ".de3ra", + ".de3ri", ".des4c", ".dictio5", ".do4t", ".du4c", ".dumb5", ".earth5", ".eas3i", ".eb4", ".eer4", ".eg2", ".el5d", + ".el3em", ".enam3", ".en3g", ".en3s", ".eq5ui5t", ".er4ri", ".es3", ".eu3", ".eye5", ".fes3", ".for5mer", ".ga2", + ".ge2", ".gen3t4", ".ge5og", ".gi5a", ".gi4b", ".go4r", ".hand5i", ".han5k", ".he2", ".hero5i", ".hes3", ".het3", + ".hi3b", ".hi3er", ".hon5ey", ".hon3o", ".hov5", ".id4l", ".idol3", ".im3m", ".im5pin", ".in1", ".in3ci", ".ine2", + ".in2k", ".in3s", ".ir5r", ".is4i", ".ju3r", ".la4cy", ".la4m", ".lat5er", ".lath5", ".le2", ".leg5e", ".len4", + ".lep5", ".lev1", ".li4g", ".lig5a", ".li2n", ".li3o", ".li4t", ".mag5a5", ".mal5o", ".man5a", ".mar5ti", ".me2", + ".mer3c", ".me5ter", ".mis1", ".mist5i", ".mon3e", ".mo3ro", ".mu5ta", ".muta5b", ".ni4c", ".od2", ".odd5", + ".of5te", ".or5ato", ".or3c", ".or1d", ".or3t", ".os3", ".os4tl", ".oth3", ".out3", ".ped5al", ".pe5te", ".pe5tit", + ".pi4e", ".pio5n", ".pi2t", ".pre3m", ".ra4c", ".ran4t", ".ratio5na", ".ree2", ".re5mit", ".res2", ".re5stat", + ".ri4g", ".rit5u", ".ro4q", ".ros5t", ".row5d", ".ru4d", ".sci3e", ".self5", ".sell5", ".se2n", ".se5rie", ".sh2", + ".si2", ".sing4", ".st4", ".sta5bl", ".sy2", ".ta4", ".te4", ".ten5an", ".th2", ".ti2", ".til4", ".tim5o5", ".ting4", + ".tin5k", ".ton4a", ".to4p", ".top5i", ".tou5s", ".trib5ut", ".un1a", ".un3ce", ".under5", ".un1e", ".un5k", + ".un5o", ".un3u", ".up3", ".ure3", ".us5a", ".ven4de", ".ve5ra", ".wil5i", ".ye4", "4ab.", "a5bal", "a5ban", "abe2", + "ab5erd", "abi5a", "ab5it5ab", "ab5lat", "ab5o5liz", "4abr", "ab5rog", "ab3ul", "a4car", "ac5ard", "ac5aro", + "a5ceou", "ac1er", "a5chet", "4a2ci", "a3cie", "ac1in", "a3cio", "ac5rob", "act5if", "ac3ul", "ac4um", "a2d", "ad4din", + "ad5er.", "2adi", "a3dia", "ad3ica", "adi4er", "a3dio", "a3dit", "a5diu", "ad4le", "ad3ow", "ad5ran", "ad4su", "4adu", + "a3duc", "ad5um", "ae4r", "aeri4e", "a2f", "aff4", "a4gab", "aga4n", "ag5ell", "age4o", "4ageu", "ag1i", "4ag4l", "ag1n", + "a2go", "3agog", "ag3oni", "a5guer", "ag5ul", "a4gy", "a3ha", "a3he", "ah4l", "a3ho", "ai2", "a5ia", "a3ic.", "ai5ly", + "a4i4n", "ain5in", "ain5o", "ait5en", "a1j", "ak1en", "al5ab", "al3ad", "a4lar", "4aldi", "2ale", "al3end", "a4lenti", + "a5le5o", "al1i", "al4ia.", "ali4e", "al5lev", "4allic", "4alm", "a5log.", "a4ly.", "4alys", "5a5lyst", "5alyt", + "3alyz", "4ama", "am5ab", "am3ag", "ama5ra", "am5asc", "a4matis", "a4m5ato", "am5era", "am3ic", "am5if", "am5ily", + "am1in", "ami4no", "a2mo", "a5mon", "amor5i", "amp5en", "a2n", "an3age", "3analy", "a3nar", "an3arc", "anar4i", + "a3nati", "4and", "ande4s", "an3dis", "an1dl", "an4dow", "a5nee", "a3nen", "an5est.", "a3neu", "2ang", "ang5ie", + "an1gl", "a4n1ic", "a3nies", "an3i3f", "an4ime", "a5nimi", "a5nine", "an3io", "a3nip", "an3ish", "an3it", "a3niu", + "an4kli", "5anniz", "ano4", "an5ot", "anoth5", "an2sa", "an4sco", "an4sn", "an2sp", "ans3po", "an4st", "an4sur", + "antal4", "an4tie", "4anto", "an2tr", "an4tw", "an3ua", "an3ul", "a5nur", "4ao", "apar4", "ap5at", "ap5ero", "a3pher", + "4aphi", "a4pilla", "ap5illar", "ap3in", "ap3ita", "a3pitu", "a2pl", "apoc5", "ap5ola", "apor5i", "apos3t", + "aps5es", "a3pu", "aque5", "2a2r", "ar3act", "a5rade", "ar5adis", "ar3al", "a5ramete", "aran4g", "ara3p", "ar4at", + "a5ratio", "ar5ativ", "a5rau", "ar5av4", "araw4", "arbal4", "ar4chan", "ar5dine", "ar4dr", "ar5eas", "a3ree", + "ar3ent", "a5ress", "ar4fi", "ar4fl", "ar1i", "ar5ial", "ar3ian", "a3riet", "ar4im", "ar5inat", "ar3io", "ar2iz", + "ar2mi", "ar5o5d", "a5roni", "a3roo", "ar2p", "ar3q", "arre4", "ar4sa", "ar2sh", "4as.", "as4ab", "as3ant", "ashi4", + "a5sia.", "a3sib", "a3sic", "5a5si4t", "ask3i", "as4l", "a4soc", "as5ph", "as4sh", "as3ten", "as1tr", "asur5a", "a2ta", + "at3abl", "at5ac", "at3alo", "at5ap", "ate5c", "at5ech", "at3ego", "at3en.", "at3era", "ater5n", "a5terna", + "at3est", "at5ev", "4ath", "ath5em", "a5then", "at4ho", "ath5om", "4ati.", "a5tia", "at5i5b", "at1ic", "at3if", + "ation5ar", "at3itu", "a4tog", "a2tom", "at5omiz", "a4top", "a4tos", "a1tr", "at5rop", "at4sk", "at4tag", "at5te", + "at4th", "a2tu", "at5ua", "at5ue", "at3ul", "at3ura", "a2ty", "au4b", "augh3", "au3gu", "au4l2", "aun5d", "au3r", + "au5sib", "aut5en", "au1th", "a2va", "av3ag", "a5van", "ave4no", "av3era", "av5ern", "av5ery", "av1i", "avi4er", + "av3ig", "av5oc", "a1vor", "3away", "aw3i", "aw4ly", "aws4", "ax4ic", "ax4id", "ay5al", "aye4", "ays4", "azi4er", "azz5i", + "5ba.", "bad5ger", "ba4ge", "bal1a", "ban5dag", "ban4e", "ban3i", "barbi5", "bari4a", "bas4si", "1bat", "ba4z", "2b1b", + "b2be", "b3ber", "bbi4na", "4b1d", "4be.", "beak4", "beat3", "4be2d", "be3da", "be3de", "be3di", "be3gi", "be5gu", "1bel", + "be1li", "be3lo", "4be5m", "be5nig", "be5nu", "4bes4", "be3sp", "be5str", "3bet", "bet5iz", "be5tr", "be3tw", "be3w", + "be5yo", "2bf", "4b3h", "bi2b", "bi4d", "3bie", "bi5en", "bi4er", "2b3if", "1bil", "bi3liz", "bina5r4", "bin4d", "bi5net", + "bi3ogr", "bi5ou", "bi2t", "3bi3tio", "bi3tr", "3bit5ua", "b5itz", "b1j", "bk4", "b2l2", "blath5", "b4le.", "blen4", + "5blesp", "b3lis", "b4lo", "blun4t", "4b1m", "4b3n", "bne5g", "3bod", "bod3i", "bo4e", "bol3ic", "bom4bi", "bon4a", + "bon5at", "3boo", "5bor.", "4b1ora", "bor5d", "5bore", "5bori", "5bos4", "b5ota", "both5", "bo4to", "bound3", "4bp", + "4brit", "broth3", "2b5s2", "bsor4", "2bt", "bt4l", "b4to", "b3tr", "buf4fer", "bu4ga", "bu3li", "bumi4", "bu4n", + "bunt4i", "bu3re", "bus5ie", "buss4e", "5bust", "4buta", "3butio", "b5uto", "b1v", "4b5w", "5by.", "bys4", "1ca", + "cab3in", "ca1bl", "cach4", "ca5den", "4cag4", "2c5ah", "ca3lat", "cal4la", "call5in", "4calo", "can5d", "can4e", + "can4ic", "can5is", "can3iz", "can4ty", "cany4", "ca5per", "car5om", "cast5er", "cas5tig", "4casy", "ca4th", + "4cativ", "cav5al", "c3c", "ccha5", "cci4a", "ccompa5", "ccon4", "ccou3t", "2ce.", "4ced.", "4ceden", "3cei", "5cel.", + "3cell", "1cen", "3cenc", "2cen4e", "4ceni", "3cent", "3cep", "ce5ram", "4cesa", "3cessi", "ces5si5b", "ces5t", "cet4", + "c5e4ta", "cew4", "2ch", "4ch.", "4ch3ab", "5chanic", "ch5a5nis", "che2", "cheap3", "4ched", "che5lo", "3chemi", + "ch5ene", "ch3er.", "ch3ers", "4ch1in", "5chine.", "ch5iness", "5chini", "5chio", "3chit", "chi2z", "3cho2", + "ch4ti", "1ci", "3cia", "ci2a5b", "cia5r", "ci5c", "4cier", "5cific.", "4cii", "ci4la", "3cili", "2cim", "2cin", "c4ina", + "3cinat", "cin3em", "c1ing", "c5ing.", "5cino", "cion4", "4cipe", "ci3ph", "4cipic", "4cista", "4cisti", "2c1it", + "cit3iz", "5ciz", "ck1", "ck3i", "1c4l4", "4clar", "c5laratio", "5clare", "cle4m", "4clic", "clim4", "cly4", "c5n", "1co", + "co5ag", "coe2", "2cog", "co4gr", "coi4", "co3inc", "col5i", "5colo", "col3or", "com5er", "con4a", "c4one", "con3g", + "con5t", "co3pa", "cop3ic", "co4pl", "4corb", "coro3n", "cos4e", "cov1", "cove4", "cow5a", "coz5e", "co5zi", "c1q", + "cras5t", "5crat.", "5cratic", "cre3at", "5cred", "4c3reta", "cre4v", "cri2", "cri5f", "c4rin", "cris4", "5criti", + "cro4pl", "crop5o", "cros4e", "cru4d", "4c3s2", "2c1t", "cta4b", "ct5ang", "c5tant", "c2te", "c3ter", "c4ticu", + "ctim3i", "ctu4r", "c4tw", "cud5", "c4uf", "c4ui", "cu5ity", "5culi", "cul4tis", "3cultu", "cu2ma", "c3ume", "cu4mi", + "3cun", "cu3pi", "cu5py", "cur5a4b", "cu5ria", "1cus", "cuss4i", "3c4ut", "cu4tie", "4c5utiv", "4cutr", "1cy", "cze4", + "1d2a", "5da.", "2d3a4b", "dach4", "4daf", "2dag", "da2m2", "dan3g", "dard5", "dark5", "4dary", "3dat", "4dativ", "4dato", + "5dav4", "dav5e", "5day", "d1b", "d5c", "d1d4", "2de.", "deaf5", "deb5it", "de4bon", "decan4", "de4cil", "de5com", + "2d1ed", "4dee.", "de5if", "deli4e", "del5i5q", "de5lo", "d4em", "5dem.", "3demic", "dem5ic.", "de5mil", "de4mons", + "demor5", "1den", "de4nar", "de3no", "denti5f", "de3nu", "de1p", "de3pa", "depi4", "de2pu", "d3eq", "d4erh", "5derm", + "dern5iz", "der5s", "des2", "d2es.", "de1sc", "de2s5o", "des3ti", "de3str", "de4su", "de1t", "de2to", "de1v", "dev3il", + "4dey", "4d1f", "d4ga", "d3ge4t", "dg1i", "d2gy", "d1h2", "5di.", "1d4i3a", "dia5b", "di4cam", "d4ice", "3dict", "3did", + "5di3en", "d1if", "di3ge", "di4lato", "d1in", "1dina", "3dine.", "5dini", "di5niz", "1dio", "dio5g", "di4pl", "dir2", + "di1re", "dirt5i", "dis1", "5disi", "d4is3t", "d2iti", "1di1v", "d1j", "d5k2", "4d5la", "3dle.", "3dled", "3dles.", + "4dless", "2d3lo", "4d5lu", "2dly", "d1m", "4d1n4", "1do", "3do.", "do5de", "5doe", "2d5of", "d4og", "do4la", "doli4", + "do5lor", "dom5iz", "do3nat", "doni4", "doo3d", "dop4p", "d4or", "3dos", "4d5out", "do4v", "3dox", "d1p", "1dr", + "drag5on", "4drai", "dre4", "drea5r", "5dren", "dri4b", "dril4", "dro4p", "4drow", "5drupli", "4dry", "2d1s2", "ds4p", + "d4sw", "d4sy", "d2th", "1du", "d1u1a", "du2c", "d1uca", "duc5er", "4duct.", "4ducts", "du5el", "du4g", "d3ule", "dum4be", + "du4n", "4dup", "du4pe", "d1v", "d1w", "d2y", "5dyn", "dy4se", "dys5p", "e1a4b", "e3act", "ead1", "ead5ie", "ea4ge", + "ea5ger", "ea4l", "eal5er", "eal3ou", "eam3er", "e5and", "ear3a", "ear4c", "ear5es", "ear4ic", "ear4il", "ear5k", + "ear2t", "eart3e", "ea5sp", "e3ass", "east3", "ea2t", "eat5en", "eath3i", "e5atif", "e4a3tu", "ea2v", "eav3en", + "eav5i", "eav5o", "2e1b", "e4bel.", "e4bels", "e4ben", "e4bit", "e3br", "e4cad", "ecan5c", "ecca5", "e1ce", "ec5essa", + "ec2i", "e4cib", "ec5ificat", "ec5ifie", "ec5ify", "ec3im", "eci4t", "e5cite", "e4clam", "e4clus", "e2col", + "e4comm", "e4compe", "e4conc", "e2cor", "ec3ora", "eco5ro", "e1cr", "e4crem", "ec4tan", "ec4te", "e1cu", "e4cul", + "ec3ula", "2e2da", "4ed3d", "e4d1er", "ede4s", "4edi", "e3dia", "ed3ib", "ed3ica", "ed3im", "ed1it", "edi5z", "4edo", + "e4dol", "edon2", "e4dri", "e4dul", "ed5ulo", "ee2c", "eed3i", "ee2f", "eel3i", "ee4ly", "ee2m", "ee4na", "ee4p1", + "ee2s4", "eest4", "ee4ty", "e5ex", "e1f", "e4f3ere", "1eff", "e4fic", "5efici", "efil4", "e3fine", "ef5i5nite", + "3efit", "efor5es", "e4fuse.", "4egal", "eger4", "eg5ib", "eg4ic", "eg5ing", "e5git5", "eg5n", "e4go.", "e4gos", + "eg1ul", "e5gur", "5egy", "e1h4", "eher4", "ei2", "e5ic", "ei5d", "eig2", "ei5gl", "e3imb", "e3inf", "e1ing", "e5inst", + "eir4d", "eit3e", "ei3th", "e5ity", "e1j", "e4jud", "ej5udi", "eki4n", "ek4la", "e1la", "e4la.", "e4lac", "elan4d", + "el5ativ", "e4law", "elaxa4", "e3lea", "el5ebra", "5elec", "e4led", "el3ega", "e5len", "e4l1er", "e1les", "el2f", + "el2i", "e3libe", "e4l5ic.", "el3ica", "e3lier", "el5igib", "e5lim", "e4l3ing", "e3lio", "e2lis", "el5ish", + "e3liv3", "4ella", "el4lab", "ello4", "e5loc", "el5og", "el3op.", "el2sh", "el4ta", "e5lud", "el5ug", "e4mac", "e4mag", + "e5man", "em5ana", "em5b", "e1me", "e2mel", "e4met", "em3ica", "emi4e", "em5igra", "em1in2", "em5ine", "em3i3ni", + "e4mis", "em5ish", "e5miss", "em3iz", "5emniz", "emo4g", "emoni5o", "em3pi", "e4mul", "em5ula", "emu3n", "e3my", + "en5amo", "e4nant", "ench4er", "en3dic", "e5nea", "e5nee", "en3em", "en5ero", "en5esi", "en5est", "en3etr", "e3new", + "en5ics", "e5nie", "e5nil", "e3nio", "en3ish", "en3it", "e5niu", "5eniz", "4enn", "4eno", "eno4g", "e4nos", "en3ov", + "en4sw", "ent5age", "4enthes", "en3ua", "en5uf", "e3ny.", "4en3z", "e5of", "eo2g", "e4oi4", "e3ol", "eop3ar", "e1or", + "eo3re", "eo5rol", "eos4", "e4ot", "eo4to", "e5out", "e5ow", "e2pa", "e3pai", "ep5anc", "e5pel", "e3pent", "ep5etitio", + "ephe4", "e4pli", "e1po", "e4prec", "ep5reca", "e4pred", "ep3reh", "e3pro", "e4prob", "ep4sh", "ep5ti5b", "e4put", + "ep5uta", "e1q", "equi3l", "e4q3ui3s", "er1a", "era4b", "4erand", "er3ar", "4erati.", "2erb", "er4bl", "er3ch", + "er4che", "2ere.", "e3real", "ere5co", "ere3in", "er5el.", "er3emo", "er5ena", "er5ence", "4erene", "er3ent", + "ere4q", "er5ess", "er3est", "eret4", "er1h", "er1i", "e1ria4", "5erick", "e3rien", "eri4er", "er3ine", "e1rio", + "4erit", "er4iu", "eri4v", "e4riva", "er3m4", "er4nis", "4ernit", "5erniz", "er3no", "2ero", "er5ob", "e5roc", "ero4r", + "er1ou", "er1s", "er3set", "ert3er", "4ertl", "er3tw", "4eru", "eru4t", "5erwau", "e1s4a", "e4sage.", "e4sages", + "es2c", "e2sca", "es5can", "e3scr", "es5cu", "e1s2e", "e2sec", "es5ecr", "es5enc", "e4sert.", "e4serts", "e4serva", + "4esh", "e3sha", "esh5en", "e1si", "e2sic", "e2sid", "es5iden", "es5igna", "e2s5im", "es4i4n", "esis4te", "esi4u", + "e5skin", "es4mi", "e2sol", "es3olu", "e2son", "es5ona", "e1sp", "es3per", "es5pira", "es4pre", "2ess", "es4si4b", + "estan4", "es3tig", "es5tim", "4es2to", "e3ston", "2estr", "e5stro", "estruc5", "e2sur", "es5urr", "es4w", "eta4b", + "eten4d", "e3teo", "ethod3", "et1ic", "e5tide", "etin4", "eti4no", "e5tir", "e5titio", "et5itiv", "4etn", "et5ona", + "e3tra", "e3tre", "et3ric", "et5rif", "et3rog", "et5ros", "et3ua", "et5ym", "et5z", "4eu", "e5un", "e3up", "eu3ro", + "eus4", "eute4", "euti5l", "eu5tr", "eva2p5", "e2vas", "ev5ast", "e5vea", "ev3ell", "evel3o", "e5veng", "even4i", + "ev1er", "e5verb", "e1vi", "ev3id", "evi4l", "e4vin", "evi4v", "e5voc", "e5vu", "e1wa", "e4wag", "e5wee", "e3wh", "ewil5", + "ew3ing", "e3wit", "1exp", "5eyc", "5eye.", "eys4", "1fa", "fa3bl", "fab3r", "fa4ce", "4fag", "fain4", "fall5e", "4fa4ma", + "fam5is", "5far", "far5th", "fa3ta", "fa3the", "4fato", "fault5", "4f5b", "4fd", "4fe.", "feas4", "feath3", "fe4b", + "4feca", "5fect", "2fed", "fe3li", "fe4mo", "fen2d", "fend5e", "fer1", "5ferr", "fev4", "4f1f", "f4fes", "f4fie", + "f5fin.", "f2f5is", "f4fly", "f2fy", "4fh", "1fi", "fi3a", "2f3ic.", "4f3ical", "f3ican", "4ficate", "f3icen", + "fi3cer", "fic4i", "5ficia", "5ficie", "4fics", "fi3cu", "fi5del", "fight5", "fil5i", "fill5in", "4fily", "2fin", + "5fina", "fin2d5", "fi2ne", "f1in3g", "fin4n", "fis4ti", "f4l2", "f5less", "flin4", "flo3re", "f2ly5", "4fm", "4fn", + "1fo", "5fon", "fon4de", "fon4t", "fo2r", "fo5rat", "for5ay", "fore5t", "for4i", "fort5a", "fos5", "4f5p", "fra4t", + "f5rea", "fres5c", "fri2", "fril4", "frol5", "2f3s", "2ft", "f4to", "f2ty", "3fu", "fu5el", "4fug", "fu4min", "fu5ne", + "fu3ri", "fusi4", "fus4s", "4futa", "1fy", "1ga", "gaf4", "5gal.", "3gali", "ga3lo", "2gam", "ga5met", "g5amo", "gan5is", + "ga3niz", "gani5za", "4gano", "gar5n4", "gass4", "gath3", "4gativ", "4gaz", "g3b", "gd4", "2ge.", "2ged", "geez4", + "gel4in", "ge5lis", "ge5liz", "4gely", "1gen", "ge4nat", "ge5niz", "4geno", "4geny", "1geo", "ge3om", "g4ery", "5gesi", + "geth5", "4geto", "ge4ty", "ge4v", "4g1g2", "g2ge", "g3ger", "gglu5", "ggo4", "gh3in", "gh5out", "gh4to", "5gi.", "1gi4a", + "gia5r", "g1ic", "5gicia", "g4ico", "gien5", "5gies.", "gil4", "g3imen", "3g4in.", "gin5ge", "5g4ins", "5gio", "3gir", + "gir4l", "g3isl", "gi4u", "5giv", "3giz", "gl2", "gla4", "glad5i", "5glas", "1gle", "gli4b", "g3lig", "3glo", "glo3r", "g1m", + "g4my", "gn4a", "g4na.", "gnet4t", "g1ni", "g2nin", "g4nio", "g1no", "g4non", "1go", "3go.", "gob5", "5goe", "3g4o4g", + "go3is", "gon2", "4g3o3na", "gondo5", "go3ni", "5goo", "go5riz", "gor5ou", "5gos.", "gov1", "g3p", "1gr", "4grada", + "g4rai", "gran2", "5graph.", "g5rapher", "5graphic", "4graphy", "4gray", "gre4n", "4gress.", "4grit", "g4ro", + "gruf4", "gs2", "g5ste", "gth3", "gu4a", "3guard", "2gue", "5gui5t", "3gun", "3gus", "4gu4t", "g3w", "1gy", "2g5y3n", + "gy5ra", "h3ab4l", "hach4", "hae4m", "hae4t", "h5agu", "ha3la", "hala3m", "ha4m", "han4ci", "han4cy", "5hand.", + "han4g", "hang5er", "hang5o", "h5a5niz", "han4k", "han4te", "hap3l", "hap5t", "ha3ran", "ha5ras", "har2d", "hard3e", + "har4le", "harp5en", "har5ter", "has5s", "haun4", "5haz", "haz3a", "h1b", "1head", "3hear", "he4can", "h5ecat", "h4ed", + "he5do5", "he3l4i", "hel4lis", "hel4ly", "h5elo", "hem4p", "he2n", "hena4", "hen5at", "heo5r", "hep5", "h4era", + "hera3p", "her4ba", "here5a", "h3ern", "h5erou", "h3ery", "h1es", "he2s5p", "he4t", "het4ed", "heu4", "h1f", "h1h", + "hi5an", "hi4co", "high5", "h4il2", "himer4", "h4ina", "hion4e", "hi4p", "hir4l", "hi3ro", "hir4p", "hir4r", "his3el", + "his4s", "hith5er", "hi2v", "4hk", "4h1l4", "hlan4", "h2lo", "hlo3ri", "4h1m", "hmet4", "2h1n", "h5odiz", "h5ods", "ho4g", + "hoge4", "hol5ar", "3hol4e", "ho4ma", "home3", "hon4a", "ho5ny", "3hood", "hoon4", "hor5at", "ho5ris", "hort3e", + "ho5ru", "hos4e", "ho5sen", "hos1p", "1hous", "house3", "hov5el", "4h5p", "4hr4", "hree5", "hro5niz", "hro3po", + "4h1s2", "h4sh", "h4tar", "ht1en", "ht5es", "h4ty", "hu4g", "hu4min", "hun5ke", "hun4t", "hus3t4", "hu4t", "h1w", + "h4wart", "hy3pe", "hy3ph", "hy2s", "2i1a", "i2al", "iam4", "iam5ete", "i2an", "4ianc", "ian3i", "4ian4t", "ia5pe", + "iass4", "i4ativ", "ia4tric", "i4atu", "ibe4", "ib3era", "ib5ert", "ib5ia", "ib3in", "ib5it.", "ib5ite", "i1bl", + "ib3li", "i5bo", "i1br", "i2b5ri", "i5bun", "4icam", "5icap", "4icar", "i4car.", "i4cara", "icas5", "i4cay", "iccu4", + "4iceo", "4ich", "2ici", "i5cid", "ic5ina", "i2cip", "ic3ipa", "i4cly", "i2c5oc", "4i1cr", "5icra", "i4cry", "ic4te", + "ictu2", "ic4t3ua", "ic3ula", "ic4um", "ic5uo", "i3cur", "2id", "i4dai", "id5anc", "id5d", "ide3al", "ide4s", "i2di", + "id5ian", "idi4ar", "i5die", "id3io", "idi5ou", "id1it", "id5iu", "i3dle", "i4dom", "id3ow", "i4dr", "i2du", "id5uo", + "2ie4", "ied4e", "5ie5ga", "ield3", "ien5a4", "ien4e", "i5enn", "i3enti", "i1er.", "i3esc", "i1est", "i3et", "4if.", + "if5ero", "iff5en", "if4fr", "4ific.", "i3fie", "i3fl", "4ift", "2ig", "iga5b", "ig3era", "ight3i", "4igi", "i3gib", + "ig3il", "ig3in", "ig3it", "i4g4l", "i2go", "ig3or", "ig5ot", "i5gre", "igu5i", "ig1ur", "i3h", "4i5i4", "i3j", "4ik", + "i1la", "il3a4b", "i4lade", "i2l5am", "ila5ra", "i3leg", "il1er", "ilev4", "il5f", "il1i", "il3ia", "il2ib", "il3io", + "il4ist", "2ilit", "il2iz", "ill5ab", "4iln", "il3oq", "il4ty", "il5ur", "il3v", "i4mag", "im3age", "ima5ry", + "imenta5r", "4imet", "im1i", "im5ida", "imi5le", "i5mini", "4imit", "im4ni", "i3mon", "i2mu", "im3ula", "2in.", + "i4n3au", "4inav", "incel4", "in3cer", "4ind", "in5dling", "2ine", "i3nee", "iner4ar", "i5ness", "4inga", "4inge", + "in5gen", "4ingi", "in5gling", "4ingo", "4ingu", "2ini", "i5ni.", "i4nia", "in3io", "in1is", "i5nite.", "5initio", + "in3ity", "4ink", "4inl", "2inn", "2i1no", "i4no4c", "ino4s", "i4not", "2ins", "in3se", "insur5a", "2int.", "2in4th", + "in1u", "i5nus", "4iny", "2io", "4io.", "ioge4", "io2gr", "i1ol", "io4m", "ion3at", "ion4ery", "ion3i", "io5ph", "ior3i", + "i4os", "io5th", "i5oti", "io4to", "i4our", "2ip", "ipe4", "iphras4", "ip3i", "ip4ic", "ip4re4", "ip3ul", "i3qua", + "iq5uef", "iq3uid", "iq3ui3t", "4ir", "i1ra", "ira4b", "i4rac", "ird5e", "ire4de", "i4ref", "i4rel4", "i4res", "ir5gi", + "ir1i", "iri5de", "ir4is", "iri3tu", "5i5r2iz", "ir4min", "iro4g", "5iron.", "ir5ul", "2is.", "is5ag", "is3ar", + "isas5", "2is1c", "is3ch", "4ise", "is3er", "3isf", "is5han", "is3hon", "ish5op", "is3ib", "isi4d", "i5sis", "is5itiv", + "4is4k", "islan4", "4isms", "i2so", "iso5mer", "is1p", "is2pi", "is4py", "4is1s", "is4sal", "issen4", "is4ses", + "is4ta.", "is1te", "is1ti", "ist4ly", "4istral", "i2su", "is5us", "4ita.", "ita4bi", "i4tag", "4ita5m", "i3tan", + "i3tat", "2ite", "it3era", "i5teri", "it4es", "2ith", "i1ti", "4itia", "4i2tic", "it3ica", "5i5tick", "it3ig", + "it5ill", "i2tim", "2itio", "4itis", "i4tism", "i2t5o5m", "4iton", "i4tram", "it5ry", "4itt", "it3uat", "i5tud", + "it3ul", "4itz.", "i1u", "2iv", "iv3ell", "iv3en.", "i4v3er.", "i4vers.", "iv5il.", "iv5io", "iv1it", "i5vore", + "iv3o3ro", "i4v3ot", "4i5w", "ix4o", "4iy", "4izar", "izi4", "5izont", "5ja", "jac4q", "ja4p", "1je", "jer5s", "4jestie", + "4jesty", "jew3", "jo4p", "5judg", "3ka.", "k3ab", "k5ag", "kais4", "kal4", "k1b", "k2ed", "1kee", "ke4g", "ke5li", "k3en4d", + "k1er", "kes4", "k3est.", "ke4ty", "k3f", "kh4", "k1i", "5ki.", "5k2ic", "k4ill", "kilo5", "k4im", "k4in.", "kin4de", + "k5iness", "kin4g", "ki4p", "kis4", "k5ish", "kk4", "k1l", "4kley", "4kly", "k1m", "k5nes", "1k2no", "ko5r", "kosh4", "k3ou", + "kro5n", "4k1s2", "k4sc", "ks4l", "k4sy", "k5t", "k1w", "lab3ic", "l4abo", "laci4", "l4ade", "la3dy", "lag4n", "lam3o", + "3land", "lan4dl", "lan5et", "lan4te", "lar4g", "lar3i", "las4e", "la5tan", "4lateli", "4lativ", "4lav", "la4v4a", + "2l1b", "lbin4", "4l1c2", "lce4", "l3ci", "2ld", "l2de", "ld4ere", "ld4eri", "ldi4", "ld5is", "l3dr", "l4dri", "le2a", + "le4bi", "left5", "5leg.", "5legg", "le4mat", "lem5atic", "4len.", "3lenc", "5lene.", "1lent", "le3ph", "le4pr", + "lera5b", "ler4e", "3lerg", "3l4eri", "l4ero", "les2", "le5sco", "5lesq", "3less", "5less.", "l3eva", "lev4er.", + "lev4era", "lev4ers", "3ley", "4leye", "2lf", "l5fr", "4l1g4", "l5ga", "lgar3", "l4ges", "lgo3", "2l3h", "li4ag", "li2am", + "liar5iz", "li4as", "li4ato", "li5bi", "5licio", "li4cor", "4lics", "4lict.", "l4icu", "l3icy", "l3ida", "lid5er", + "3lidi", "lif3er", "l4iff", "li4fl", "5ligate", "3ligh", "li4gra", "3lik", "4l4i4l", "lim4bl", "lim3i", "li4mo", + "l4im4p", "l4ina", "1l4ine", "lin3ea", "lin3i", "link5er", "li5og", "4l4iq", "lis4p", "l1it", "l2it.", "5litica", + "l5i5tics", "liv3er", "l1iz", "4lj", "lka3", "l3kal", "lka4t", "l1l", "l4law", "l2le", "l5lea", "l3lec", "l3leg", "l3lel", + "l3le4n", "l3le4t", "ll2i", "l2lin4", "l5lina", "ll4o", "lloqui5", "ll5out", "l5low", "2lm", "l5met", "lm3ing", + "l4mod", "lmon4", "2l1n2", "3lo.", "lob5al", "lo4ci", "4lof", "3logic", "l5ogo", "3logu", "lom3er", "5long", "lon4i", + "l3o3niz", "lood5", "5lope.", "lop3i", "l3opm", "lora4", "lo4rato", "lo5rie", "lor5ou", "5los.", "los5et", + "5losophiz", "5losophy", "los4t", "lo4ta", "loun5d", "2lout", "4lov", "2lp", "lpa5b", "l3pha", "l5phi", "lp5ing", + "l3pit", "l4pl", "l5pr", "4l1r", "2l1s2", "l4sc", "l2se", "l4sie", "4lt", "lt5ag", "ltane5", "l1te", "lten4", "ltera4", + "lth3i", "l5ties.", "ltis4", "l1tr", "ltu2", "ltur3a", "lu5a", "lu3br", "luch4", "lu3ci", "lu3en", "luf4", "lu5id", + "lu4ma", "5lumi", "l5umn.", "5lumnia", "lu3o", "luo3r", "4lup", "luss4", "lus3te", "1lut", "l5ven", "l5vet4", "2l1w", + "1ly", "4lya", "4lyb", "ly5me", "ly3no", "2lys4", "l5yse", "1ma", "2mab", "ma2ca", "ma5chine", "ma4cl", "mag5in", "5magn", + "2mah", "maid5", "4mald", "ma3lig", "ma5lin", "mal4li", "mal4ty", "5mania", "man5is", "man3iz", "4map", "ma5rine.", + "ma5riz", "mar4ly", "mar3v", "ma5sce", "mas4e", "mas1t", "5mate", "math3", "ma3tis", "4matiza", "4m1b", "mba4t5", + "m5bil", "m4b3ing", "mbi4v", "4m5c", "4me.", "2med", "4med.", "5media", "me3die", "m5e5dy", "me2g", "mel5on", "mel4t", + "me2m", "mem1o3", "1men", "men4a", "men5ac", "men4de", "4mene", "men4i", "mens4", "mensu5", "3ment", "men4te", "me5on", + "m5ersa", "2mes", "3mesti", "me4ta", "met3al", "me1te", "me5thi", "m4etr", "5metric", "me5trie", "me3try", "me4v", + "4m1f", "2mh", "5mi.", "mi3a", "mid4a", "mid4g", "mig4", "3milia", "m5i5lie", "m4ill", "min4a", "3mind", "m5inee", + "m4ingl", "min5gli", "m5ingly", "min4t", "m4inu", "miot4", "m2is", "mis4er.", "mis5l", "mis4ti", "m5istry", "4mith", + "m2iz", "4mk", "4m1l", "m1m", "mma5ry", "4m1n", "mn4a", "m4nin", "mn4o", "1mo", "4mocr", "5mocratiz", "mo2d1", "mo4go", + "mois2", "moi5se", "4mok", "mo5lest", "mo3me", "mon5et", "mon5ge", "moni3a", "mon4ism", "mon4ist", "mo3niz", + "monol4", "mo3ny.", "mo2r", "4mora.", "mos2", "mo5sey", "mo3sp", "moth3", "m5ouf", "3mous", "mo2v", "4m1p", "mpara5", + "mpa5rab", "mpar5i", "m3pet", "mphas4", "m2pi", "mpi4a", "mp5ies", "m4p1in", "m5pir", "mp5is", "mpo3ri", "mpos5ite", + "m4pous", "mpov5", "mp4tr", "m2py", "4m3r", "4m1s2", "m4sh", "m5si", "4mt", "1mu", "mula5r4", "5mult", "multi3", "3mum", + "mun2", "4mup", "mu4u", "4mw", "1na", "2n1a2b", "n4abu", "4nac.", "na4ca", "n5act", "nag5er.", "nak4", "na4li", "na5lia", + "4nalt", "na5mit", "n2an", "nanci4", "nan4it", "nank4", "nar3c", "4nare", "nar3i", "nar4l", "n5arm", "n4as", "nas4c", + "nas5ti", "n2at", "na3tal", "nato5miz", "n2au", "nau3se", "3naut", "nav4e", "4n1b4", "ncar5", "n4ces.", "n3cha", + "n5cheo", "n5chil", "n3chis", "nc1in", "nc4it", "ncour5a", "n1cr", "n1cu", "n4dai", "n5dan", "n1de", "nd5est.", + "ndi4b", "n5d2if", "n1dit", "n3diz", "n5duc", "ndu4r", "nd2we", "2ne.", "n3ear", "ne2b", "neb3u", "ne2c", "5neck", "2ned", + "ne4gat", "neg5ativ", "5nege", "ne4la", "nel5iz", "ne5mi", "ne4mo", "1nen", "4nene", "3neo", "ne4po", "ne2q", "n1er", + "nera5b", "n4erar", "n2ere", "n4er5i", "ner4r", "1nes", "2nes.", "4nesp", "2nest", "4nesw", "3netic", "ne4v", "n5eve", + "ne4w", "n3f", "n4gab", "n3gel", "nge4n4e", "n5gere", "n3geri", "ng5ha", "n3gib", "ng1in", "n5git", "n4gla", "ngov4", + "ng5sh", "n1gu", "n4gum", "n2gy", "4n1h4", "nha4", "nhab3", "nhe4", "3n4ia", "ni3an", "ni4ap", "ni3ba", "ni4bl", "ni4d", + "ni5di", "ni4er", "ni2fi", "ni5ficat", "n5igr", "nik4", "n1im", "ni3miz", "n1in", "5nine.", "nin4g", "ni4o", "5nis.", + "nis4ta", "n2it", "n4ith", "3nitio", "n3itor", "ni3tr", "n1j", "4nk2", "n5kero", "n3ket", "nk3in", "n1kl", "4n1l", "n5m", + "nme4", "nmet4", "4n1n2", "nne4", "nni3al", "nni4v", "nob4l", "no3ble", "n5ocl", "4n3o2d", "3noe", "4nog", "noge4", + "nois5i", "no5l4i", "5nologis", "3nomic", "n5o5miz", "no4mo", "no3my", "no4n", "non4ag", "non5i", "n5oniz", "4nop", + "5nop5o5li", "nor5ab", "no4rary", "4nosc", "nos4e", "nos5t", "no5ta", "1nou", "3noun", "nov3el3", "nowl3", "n1p4", + "npi4", "npre4c", "n1q", "n1r", "nru4", "2n1s2", "ns5ab", "nsati4", "ns4c", "n2se", "n4s3es", "nsid1", "nsig4", "n2sl", + "ns3m", "n4soc", "ns4pe", "n5spi", "nsta5bl", "n1t", "nta4b", "nter3s", "nt2i", "n5tib", "nti4er", "nti2f", "n3tine", + "n4t3ing", "nti4p", "ntrol5li", "nt4s", "ntu3me", "nu1a", "nu4d", "nu5en", "nuf4fe", "n3uin", "3nu3it", "n4um", + "nu1me", "n5umi", "3nu4n", "n3uo", "nu3tr", "n1v2", "n1w4", "nym4", "nyp4", "4nz", "n3za", "4oa", "oad3", "o5a5les", "oard3", + "oas4e", "oast5e", "oat5i", "ob3a3b", "o5bar", "obe4l", "o1bi", "o2bin", "ob5ing", "o3br", "ob3ul", "o1ce", "och4", + "o3chet", "ocif3", "o4cil", "o4clam", "o4cod", "oc3rac", "oc5ratiz", "ocre3", "5ocrit", "octor5a", "oc3ula", + "o5cure", "od5ded", "od3ic", "odi3o", "o2do4", "odor3", "od5uct.", "od5ucts", "o4el", "o5eng", "o3er", "oe4ta", "o3ev", + "o2fi", "of5ite", "ofit4t", "o2g5a5r", "og5ativ", "o4gato", "o1ge", "o5gene", "o5geo", "o4ger", "o3gie", "1o1gis", + "og3it", "o4gl", "o5g2ly", "3ogniz", "o4gro", "ogu5i", "1ogy", "2ogyn", "o1h2", "ohab5", "oi2", "oic3es", "oi3der", + "oiff4", "oig4", "oi5let", "o3ing", "oint5er", "o5ism", "oi5son", "oist5en", "oi3ter", "o5j", "2ok", "o3ken", "ok5ie", + "o1la", "o4lan", "olass4", "ol2d", "old1e", "ol3er", "o3lesc", "o3let", "ol4fi", "ol2i", "o3lia", "o3lice", "ol5id.", + "o3li4f", "o5lil", "ol3ing", "o5lio", "o5lis.", "ol3ish", "o5lite", "o5litio", "o5liv", "olli4e", "ol5ogiz", + "olo4r", "ol5pl", "ol2t", "ol3ub", "ol3ume", "ol3un", "o5lus", "ol2v", "o2ly", "om5ah", "oma5l", "om5atiz", "om2be", + "om4bl", "o2me", "om3ena", "om5erse", "o4met", "om5etry", "o3mia", "om3ic.", "om3ica", "o5mid", "om1in", "o5mini", + "5ommend", "omo4ge", "o4mon", "om3pi", "ompro5", "o2n", "on1a", "on4ac", "o3nan", "on1c", "3oncil", "2ond", "on5do", + "o3nen", "on5est", "on4gu", "on1ic", "o3nio", "on1is", "o5niu", "on3key", "on4odi", "on3omy", "on3s", "onspi4", + "onspir5a", "onsu4", "onten4", "on3t4i", "ontif5", "on5um", "onva5", "oo2", "ood5e", "ood5i", "oo4k", "oop3i", "o3ord", + "oost5", "o2pa", "ope5d", "op1er", "3opera", "4operag", "2oph", "o5phan", "o5pher", "op3ing", "o3pit", "o5pon", + "o4posi", "o1pr", "op1u", "opy5", "o1q", "o1ra", "o5ra.", "o4r3ag", "or5aliz", "or5ange", "ore5a", "o5real", "or3ei", + "ore5sh", "or5est.", "orew4", "or4gu", "4o5ria", "or3ica", "o5ril", "or1in", "o1rio", "or3ity", "o3riu", "or2mi", + "orn2e", "o5rof", "or3oug", "or5pe", "3orrh", "or4se", "ors5en", "orst4", "or3thi", "or3thy", "or4ty", "o5rum", "o1ry", + "os3al", "os2c", "os4ce", "o3scop", "4oscopi", "o5scr", "os4i4e", "os5itiv", "os3ito", "os3ity", "osi4u", "os4l", + "o2so", "os4pa", "os4po", "os2ta", "o5stati", "os5til", "os5tit", "o4tan", "otele4g", "ot3er.", "ot5ers", "o4tes", + "4oth", "oth5esi", "oth3i4", "ot3ic.", "ot5ica", "o3tice", "o3tif", "o3tis", "oto5s", "ou2", "ou3bl", "ouch5i", + "ou5et", "ou4l", "ounc5er", "oun2d", "ou5v", "ov4en", "over4ne", "over3s", "ov4ert", "o3vis", "oviti4", "o5v4ol", + "ow3der", "ow3el", "ow5est", "ow1i", "own5i", "o4wo", "oy1a", "1pa", "pa4ca", "pa4ce", "pac4t", "p4ad", "5pagan", + "p3agat", "p4ai", "pain4", "p4al", "pan4a", "pan3el", "pan4ty", "pa3ny", "pa1p", "pa4pu", "para5bl", "par5age", + "par5di", "3pare", "par5el", "p4a4ri", "par4is", "pa2te", "pa5ter", "5pathic", "pa5thy", "pa4tric", "pav4", "3pay", + "4p1b", "pd4", "4pe.", "3pe4a", "pear4l", "pe2c", "2p2ed", "3pede", "3pedi", "pedia4", "ped4ic", "p4ee", "pee4d", "pek4", + "pe4la", "peli4e", "pe4nan", "p4enc", "pen4th", "pe5on", "p4era.", "pera5bl", "p4erag", "p4eri", "peri5st", + "per4mal", "perme5", "p4ern", "per3o", "per3ti", "pe5ru", "per1v", "pe2t", "pe5ten", "pe5tiz", "4pf", "4pg", "4ph.", + "phar5i", "phe3no", "ph4er", "ph4es.", "ph1ic", "5phie", "ph5ing", "5phisti", "3phiz", "ph2l", "3phob", "3phone", + "5phoni", "pho4r", "4phs", "ph3t", "5phu", "1phy", "pi3a", "pian4", "pi4cie", "pi4cy", "p4id", "p5ida", "pi3de", "5pidi", + "3piec", "pi3en", "pi4grap", "pi3lo", "pi2n", "p4in.", "pind4", "p4ino", "3pi1o", "pion4", "p3ith", "pi5tha", "pi2tu", + "2p3k2", "1p2l2", "3plan", "plas5t", "pli3a", "pli5er", "4plig", "pli4n", "ploi4", "plu4m", "plum4b", "4p1m", "2p3n", + "po4c", "5pod.", "po5em", "po3et5", "5po4g", "poin2", "5point", "poly5t", "po4ni", "po4p", "1p4or", "po4ry", "1pos", + "pos1s", "p4ot", "po4ta", "5poun", "4p1p", "ppa5ra", "p2pe", "p4ped", "p5pel", "p3pen", "p3per", "p3pet", "ppo5site", + "pr2", "pray4e", "5preci", "pre5co", "pre3em", "pref5ac", "pre4la", "pre3r", "p3rese", "3press", "pre5ten", "pre3v", + "5pri4e", "prin4t3", "pri4s", "pris3o", "p3roca", "prof5it", "pro3l", "pros3e", "pro1t", "2p1s2", "p2se", "ps4h", + "p4sib", "2p1t", "pt5a4b", "p2te", "p2th", "pti3m", "ptu4r", "p4tw", "pub3", "pue4", "puf4", "pul3c", "pu4m", "pu2n", + "pur4r", "5pus", "pu2t", "5pute", "put3er", "pu3tr", "put4ted", "put4tin", "p3w", "qu2", "qua5v", "2que.", "3quer", + "3quet", "2rab", "ra3bi", "rach4e", "r5acl", "raf5fi", "raf4t", "r2ai", "ra4lo", "ram3et", "r2ami", "rane5o", "ran4ge", + "r4ani", "ra5no", "rap3er", "3raphy", "rar5c", "rare4", "rar5ef", "4raril", "r2as", "ration4", "rau4t", "ra5vai", + "rav3el", "ra5zie", "r1b", "r4bab", "r4bag", "rbi2", "rbi4f", "r2bin", "r5bine", "rb5ing.", "rb4o", "r1c", "r2ce", + "rcen4", "r3cha", "rch4er", "r4ci4b", "rc4it", "rcum3", "r4dal", "rd2i", "rdi4a", "rdi4er", "rdin4", "rd3ing", "2re.", + "re1al", "re3an", "re5arr", "5reav", "re4aw", "r5ebrat", "rec5oll", "rec5ompe", "re4cre", "2r2ed", "re1de", + "re3dis", "red5it", "re4fac", "re2fe", "re5fer.", "re3fi", "re4fy", "reg3is", "re5it", "re1li", "re5lu", "r4en4ta", + "ren4te", "re1o", "re5pin", "re4posi", "re1pu", "r1er4", "r4eri", "rero4", "re5ru", "r4es.", "re4spi", "ress5ib", + "res2t", "re5stal", "re3str", "re4ter", "re4ti4z", "re3tri", "reu2", "re5uti", "rev2", "re4val", "rev3el", + "r5ev5er.", "re5vers", "re5vert", "re5vil", "rev5olu", "re4wh", "r1f", "rfu4", "r4fy", "rg2", "rg3er", "r3get", + "r3gic", "rgi4n", "rg3ing", "r5gis", "r5git", "r1gl", "rgo4n", "r3gu", "rh4", "4rh.", "4rhal", "ri3a", "ria4b", "ri4ag", + "r4ib", "rib3a", "ric5as", "r4ice", "4rici", "5ricid", "ri4cie", "r4ico", "rid5er", "ri3enc", "ri3ent", "ri1er", + "ri5et", "rig5an", "5rigi", "ril3iz", "5riman", "rim5i", "3rimo", "rim4pe", "r2ina", "5rina.", "rin4d", "rin4e", + "rin4g", "ri1o", "5riph", "riph5e", "ri2pl", "rip5lic", "r4iq", "r2is", "r4is.", "ris4c", "r3ish", "ris4p", "ri3ta3b", + "r5ited.", "rit5er.", "rit5ers", "rit3ic", "ri2tu", "rit5ur", "riv5el", "riv3et", "riv3i", "r3j", "r3ket", "rk4le", + "rk4lin", "r1l", "rle4", "r2led", "r4lig", "r4lis", "rl5ish", "r3lo4", "r1m", "rma5c", "r2me", "r3men", "rm5ers", + "rm3ing", "r4ming.", "r4mio", "r3mit", "r4my", "r4nar", "r3nel", "r4ner", "r5net", "r3ney", "r5nic", "r1nis4", "r3nit", + "r3niv", "rno4", "r4nou", "r3nu", "rob3l", "r2oc", "ro3cr", "ro4e", "ro1fe", "ro5fil", "rok2", "ro5ker", "5role.", + "rom5ete", "rom4i", "rom4p", "ron4al", "ron4e", "ro5n4is", "ron4ta", "1room", "5root", "ro3pel", "rop3ic", "ror3i", + "ro5ro", "ros5per", "ros4s", "ro4the", "ro4ty", "ro4va", "rov5el", "rox5", "r1p", "r4pea", "r5pent", "rp5er.", "r3pet", + "rp4h4", "rp3ing", "r3po", "r1r4", "rre4c", "rre4f", "r4reo", "rre4st", "rri4o", "rri4v", "rron4", "rros4", "rrys4", + "4rs2", "r1sa", "rsa5ti", "rs4c", "r2se", "r3sec", "rse4cr", "rs5er.", "rs3es", "rse5v2", "r1sh", "r5sha", "r1si", + "r4si4b", "rson3", "r1sp", "r5sw", "rtach4", "r4tag", "r3teb", "rten4d", "rte5o", "r1ti", "rt5ib", "rti4d", "r4tier", + "r3tig", "rtil3i", "rtil4l", "r4tily", "r4tist", "r4tiv", "r3tri", "rtroph4", "rt4sh", "ru3a", "ru3e4l", "ru3en", + "ru4gl", "ru3in", "rum3pl", "ru2n", "runk5", "run4ty", "r5usc", "ruti5n", "rv4e", "rvel4i", "r3ven", "rv5er.", + "r5vest", "r3vey", "r3vic", "rvi4v", "r3vo", "r1w", "ry4c", "5rynge", "ry3t", "sa2", "2s1ab", "5sack", "sac3ri", "s3act", + "5sai", "salar4", "sal4m", "sa5lo", "sal4t", "3sanc", "san4de", "s1ap", "sa5ta", "5sa3tio", "sat3u", "sau4", "sa5vor", + "5saw", "4s5b", "scan4t5", "sca4p", "scav5", "s4ced", "4scei", "s4ces", "sch2", "s4cho", "3s4cie", "5scin4d", "scle5", + "s4cli", "scof4", "4scopy", "scour5a", "s1cu", "4s5d", "4se.", "se4a", "seas4", "sea5w", "se2c3o", "3sect", "4s4ed", + "se4d4e", "s5edl", "se2g", "seg3r", "5sei", "se1le", "5self", "5selv", "4seme", "se4mol", "sen5at", "4senc", "sen4d", + "s5ened", "sen5g", "s5enin", "4sentd", "4sentl", "sep3a3", "4s1er.", "s4erl", "ser4o", "4servo", "s1e4s", "se5sh", + "ses5t", "5se5um", "5sev", "sev3en", "sew4i", "5sex", "4s3f", "2s3g", "s2h", "2sh.", "sh1er", "5shev", "sh1in", "sh3io", + "3ship", "shiv5", "sho4", "sh5old", "shon3", "shor4", "short5", "4shw", "si1b", "s5icc", "3side.", "5sides", "5sidi", + "si5diz", "4signa", "sil4e", "4sily", "2s1in", "s2ina", "5sine.", "s3ing", "1sio", "5sion", "sion5a", "si2r", "sir5a", + "1sis", "3sitio", "5siu", "1siv", "5siz", "sk2", "4ske", "s3ket", "sk5ine", "sk5ing", "s1l2", "s3lat", "s2le", "slith5", + "2s1m", "s3ma", "small3", "sman3", "smel4", "s5men", "5smith", "smol5d4", "s1n4", "1so", "so4ce", "soft3", "so4lab", + "sol3d2", "so3lic", "5solv", "3som", "3s4on.", "sona4", "son4g", "s4op", "5sophic", "s5ophiz", "s5ophy", "sor5c", + "sor5d", "4sov", "so5vi", "2spa", "5spai", "spa4n", "spen4d", "2s5peo", "2sper", "s2phe", "3spher", "spho5", "spil4", + "sp5ing", "4spio", "s4ply", "s4pon", "spor4", "4spot", "squal4l", "s1r", "2ss", "s1sa", "ssas3", "s2s5c", "s3sel", + "s5seng", "s4ses.", "s5set", "s1si", "s4sie", "ssi4er", "ss5ily", "s4sl", "ss4li", "s4sn", "sspend4", "ss2t", "ssur5a", + "ss5w", "2st.", "s2tag", "s2tal", "stam4i", "5stand", "s4ta4p", "5stat.", "s4ted", "stern5i", "s5tero", "ste2w", + "stew5a", "s3the", "st2i", "s4ti.", "s5tia", "s1tic", "5stick", "s4tie", "s3tif", "st3ing", "5stir", "s1tle", "5stock", + "stom3a", "5stone", "s4top", "3store", "st4r", "s4trad", "5stratu", "s4tray", "s4trid", "4stry", "4st3w", "s2ty", + "1su", "su1al", "su4b3", "su2g3", "su5is", "suit3", "s4ul", "su2m", "sum3i", "su2n", "su2r", "4sv", "sw2", "4swo", "s4y", + "4syc", "3syl", "syn5o", "sy5rin", "1ta", "3ta.", "2tab", "ta5bles", "5taboliz", "4taci", "ta5do", "4taf4", "tai5lo", + "ta2l", "ta5la", "tal5en", "tal3i", "4talk", "tal4lis", "ta5log", "ta5mo", "tan4de", "tanta3", "ta5per", "ta5pl", + "tar4a", "4tarc", "4tare", "ta3riz", "tas4e", "ta5sy", "4tatic", "ta4tur", "taun4", "tav4", "2taw", "tax4is", "2t1b", + "4tc", "t4ch", "tch5et", "4t1d", "4te.", "tead4i", "4teat", "tece4", "5tect", "2t1ed", "te5di", "1tee", "teg4", "te5ger", + "te5gi", "3tel.", "teli4", "5tels", "te2ma2", "tem3at", "3tenan", "3tenc", "3tend", "4tenes", "1tent", "ten4tag", + "1teo", "te4p", "te5pe", "ter3c", "5ter3d", "1teri", "ter5ies", "ter3is", "teri5za", "5ternit", "ter5v", "4tes.", + "4tess", "t3ess.", "teth5e", "3teu", "3tex", "4tey", "2t1f", "4t1g", "2th.", "than4", "th2e", "4thea", "th3eas", "the5at", + "the3is", "3thet", "th5ic.", "th5ica", "4thil", "5think", "4thl", "th5ode", "5thodic", "4thoo", "thor5it", + "tho5riz", "2ths", "1tia", "ti4ab", "ti4ato", "2ti2b", "4tick", "t4ico", "t4ic1u", "5tidi", "3tien", "tif2", "ti5fy", + "2tig", "5tigu", "till5in", "1tim", "4timp", "tim5ul", "2t1in", "t2ina", "3tine.", "3tini", "1tio", "ti5oc", "tion5ee", + "5tiq", "ti3sa", "3tise", "tis4m", "ti5so", "tis4p", "5tistica", "ti3tl", "ti4u", "1tiv", "tiv4a", "1tiz", "ti3za", + "ti3zen", "2tl", "t5la", "tlan4", "3tle.", "3tled", "3tles.", "t5let.", "t5lo", "4t1m", "tme4", "2t1n2", "1to", "to3b", + "to5crat", "4todo", "2tof", "to2gr", "to5ic", "to2ma", "tom4b", "to3my", "ton4ali", "to3nat", "4tono", "4tony", + "to2ra", "to3rie", "tor5iz", "tos2", "5tour", "4tout", "to3war", "4t1p", "1tra", "tra3b", "tra5ch", "traci4", + "trac4it", "trac4te", "tras4", "tra5ven", "trav5es5", "tre5f", "tre4m", "trem5i", "5tria", "tri5ces", "5tricia", + "4trics", "2trim", "tri4v", "tro5mi", "tron5i", "4trony", "tro5phe", "tro3sp", "tro3v", "tru5i", "trus4", "4t1s2", + "t4sc", "tsh4", "t4sw", "4t3t2", "t4tes", "t5to", "ttu4", "1tu", "tu1a", "tu3ar", "tu4bi", "tud2", "4tue", "4tuf4", "5tu3i", + "3tum", "tu4nis", "2t3up.", "3ture", "5turi", "tur3is", "tur5o", "tu5ry", "3tus", "4tv", "tw4", "4t1wa", "twis4", "4two", + "1ty", "4tya", "2tyl", "type3", "ty5ph", "4tz", "tz4e", "4uab", "uac4", "ua5na", "uan4i", "uar5ant", "uar2d", "uar3i", + "uar3t", "u1at", "uav4", "ub4e", "u4bel", "u3ber", "u4bero", "u1b4i", "u4b5ing", "u3ble.", "u3ca", "uci4b", "uc4it", + "ucle3", "u3cr", "u3cu", "u4cy", "ud5d", "ud3er", "ud5est", "udev4", "u1dic", "ud3ied", "ud3ies", "ud5is", "u5dit", + "u4don", "ud4si", "u4du", "u4ene", "uens4", "uen4te", "uer4il", "3ufa", "u3fl", "ugh3en", "ug5in", "2ui2", "uil5iz", + "ui4n", "u1ing", "uir4m", "uita4", "uiv3", "uiv4er.", "u5j", "4uk", "u1la", "ula5b", "u5lati", "ulch4", "5ulche", + "ul3der", "ul4e", "u1len", "ul4gi", "ul2i", "u5lia", "ul3ing", "ul5ish", "ul4lar", "ul4li4b", "ul4lis", "4ul3m", + "u1l4o", "4uls", "uls5es", "ul1ti", "ultra3", "4ultu", "u3lu", "ul5ul", "ul5v", "um5ab", "um4bi", "um4bly", "u1mi", + "u4m3ing", "umor5o", "um2p", "unat4", "u2ne", "un4er", "u1ni", "un4im", "u2nin", "un5ish", "uni3v", "un3s4", "un4sw", + "unt3ab", "un4ter.", "un4tes", "unu4", "un5y", "un5z", "u4ors", "u5os", "u1ou", "u1pe", "uper5s", "u5pia", "up3ing", + "u3pl", "up3p", "upport5", "upt5ib", "uptu4", "u1ra", "4ura.", "u4rag", "u4ras", "ur4be", "urc4", "ur1d", "ure5at", + "ur4fer", "ur4fr", "u3rif", "uri4fic", "ur1in", "u3rio", "u1rit", "ur3iz", "ur2l", "url5ing.", "ur4no", "uros4", + "ur4pe", "ur4pi", "urs5er", "ur5tes", "ur3the", "urti4", "ur4tie", "u3ru", "2us", "u5sad", "u5san", "us4ap", "usc2", + "us3ci", "use5a", "u5sia", "u3sic", "us4lin", "us1p", "us5sl", "us5tere", "us1tr", "u2su", "usur4", "uta4b", "u3tat", + "4ute.", "4utel", "4uten", "uten4i", "4u1t2i", "uti5liz", "u3tine", "ut3ing", "ution5a", "u4tis", "5u5tiz", "u4t1l", + "ut5of", "uto5g", "uto5matic", "u5ton", "u4tou", "uts4", "u3u", "uu4m", "u1v2", "uxu3", "uz4e", "1va", "5va.", "2v1a4b", + "vac5il", "vac3u", "vag4", "va4ge", "va5lie", "val5o", "val1u", "va5mo", "va5niz", "va5pi", "var5ied", "3vat", "4ve.", + "4ved", "veg3", "v3el.", "vel3li", "ve4lo", "v4ely", "ven3om", "v5enue", "v4erd", "5vere.", "v4erel", "v3eren", + "ver5enc", "v4eres", "ver3ie", "vermi4n", "3verse", "ver3th", "v4e2s", "4ves.", "ves4te", "ve4te", "vet3er", + "ve4ty", "vi5ali", "5vian", "5vide.", "5vided", "4v3iden", "5vides", "5vidi", "v3if", "vi5gn", "vik4", "2vil", + "5vilit", "v3i3liz", "v1in", "4vi4na", "v2inc", "vin5d", "4ving", "vio3l", "v3io4r", "vi1ou", "vi4p", "vi5ro", + "vis3it", "vi3so", "vi3su", "4viti", "vit3r", "4vity", "3viv", "5vo.", "voi4", "3vok", "vo4la", "v5ole", "5volt", "3volv", + "vom5i", "vor5ab", "vori4", "vo4ry", "vo4ta", "4votee", "4vv4", "v4y", "w5abl", "2wac", "wa5ger", "wag5o", "wait5", + "w5al.", "wam4", "war4t", "was4t", "wa1te", "wa5ver", "w1b", "wea5rie", "weath3", "wed4n", "weet3", "wee5v", "wel4l", + "w1er", "west3", "w3ev", "whi4", "wi2", "wil2", "will5in", "win4de", "win4g", "wir4", "3wise", "with3", "wiz5", "w4k", + "wl4es", "wl3in", "w4no", "1wo2", "wom1", "wo5ven", "w5p", "wra4", "wri4", "writa4", "w3sh", "ws4l", "ws4pe", "w5s4t", "4wt", + "wy4", "x1a", "xac5e", "x4ago", "xam3", "x4ap", "xas5", "x3c2", "x1e", "xe4cuto", "x2ed", "xer4i", "xe5ro", "x1h", "xhi2", + "xhil5", "xhu4", "x3i", "xi5a", "xi5c", "xi5di", "x4ime", "xi5miz", "x3o", "x4ob", "x3p", "xpan4d", "xpecto5", "xpe3d", + "x1t2", "x3ti", "x1u", "xu3a", "xx4", "y5ac", "3yar4", "y5at", "y1b", "y1c", "y2ce", "yc5er", "y3ch", "ych4e", "ycom4", "ycot4", + "y1d", "y5ee", "y1er", "y4erf", "yes4", "ye4t", "y5gi", "4y3h", "y1i", "y3la", "ylla5bl", "y3lo", "y5lu", "ymbol5", "yme4", + "ympa3", "yn3chr", "yn5d", "yn5g", "yn5ic", "5ynx", "y1o4", "yo5d", "y4o5g", "yom4", "yo5net", "y4ons", "y4os", "y4ped", + "yper5", "yp3i", "y3po", "y4poc", "yp2ta", "y5pu", "yra5m", "yr5ia", "y3ro", "yr4r", "ys4c", "y3s2e", "ys3ica", "ys3io", + "3ysis", "y4so", "yss4", "ys1t", "ys3ta", "ysur4", "y3thin", "yt3ic", "y1w", "za1", "z5a2b", "zar2", "4zb", "2ze", "ze4n", + "ze4p", "z1er", "ze3ro", "zet4", "2z1i", "z4il", "z4is", "5zl", "4zm", "1zo", "zo4m", "zo5ol", "zte4", "4z1z2", "z4zy" + ] ++ +-- Extra patterns, from ushyphmax.tex, dated 2005-05-30. +-- Copyright (C) 1990, 2004, 2005 Gerard D.C. Kuiken. +-- Copying and distribution of this file, with or without modification, +-- are permitted in any medium without royalty provided the copyright +-- notice and this notice are preserved. +-- +-- These patterns are based on the Hyphenation Exception Log +-- published in TUGboat, Volume 10 (1989), No. 3, pp. 337-341, +-- and a large number of incorrectly hyphenated words not yet published. + [ + ".con5gr", ".de5riva", ".dri5v4", ".eth1y6l1", ".eu4ler", ".ev2", ".ever5si5b", ".ga4s1om1", ".ge4ome", + ".ge5ot1", ".he3mo1", ".he3p6a", ".he3roe", ".in5u2t", ".kil2n3i", ".ko6r1te1", ".le6ices", ".me4ga1l", + ".met4ala", ".mim5i2c1", ".mi1s4ers", ".ne6o3f", ".noe1th", ".non1e2m", ".poly1s", ".post1am", ".pre1am", + ".rav5en1o", ".semi5", ".sem4ic", ".semid6", ".semip4", ".semir4", ".sem6is4", ".semiv4", ".sph6in1", + ".spin1o", ".ta5pes1tr", ".te3legr", ".to6pog", ".to2q", ".un3at5t", ".un5err5", ".vi2c3ar", ".we2b1l", + ".re1e4c", "a5bolic", "a2cabl", "af6fish", "am1en3ta5b", "anal6ys", "ano5a2c", "ans5gr", "ans3v", "anti1d", + "an3ti1n2", "anti1re", "a4pe5able", "ar3che5t", "ar2range", "as5ymptot", "ath3er1o1s", "at6tes.", + "augh4tl", "au5li5f", "av3iou", "back2er.", "ba6r1onie", "ba1thy", "bbi4t", "be2vie", "bi5d2if", "bil2lab", + "bio5m", "bi1orb", "bio1rh", "b1i3tive", "blan2d1", "blin2d1", "blon2d2", "bor1no5", "bo2t1u1l", "brus4q", + "bus6i2er", "bus6i2es", "buss4ing", "but2ed.", "but4ted", "cad5e1m", "cat1a1s2", "4chs.", "chs3hu", "chie5vo", + "cig3a3r", "cin2q", "cle4ar", "co6ph1o3n", "cous2ti", "cri3tie", "croc1o1d", "cro5e2co", "c2tro3me6c", + "1cu2r1ance", "2d3alone", "data1b", "dd5a5b", "d2d5ib", "de4als.", "de5clar1", "de2c5lina", "de3fin3iti", + "de2mos", "des3ic", "de2tic", "dic1aid", "dif5fra", "3di1methy", "di2ren", "di2rer", "2d1lead", "2d1li2e", + "3do5word", "dren1a5l", "drif2t1a", "d1ri3pleg5", "drom3e5d", "d3tab", "du2al.", "du1op1o1l", "ea4n3ies", + "e3chas", "edg1l", "ed1uling", "eli2t1is", "e1loa", "en1dix", "eo3grap", "1e6p3i3neph1", "e2r3i4an.", + "e3spac6i", "eth1y6l1ene", "5eu2clid1", "feb1rua", "fermi1o", "3fich", "fit5ted.", "fla1g6el", "flow2er.", + "3fluor", "gen2cy.", "ge3o1d", "ght1we", "g1lead", "get2ic.", "4g1lish", "5glo5bin", "1g2nac", "gnet1ism", + "gno5mo", "g2n1or.", "g2noresp", "2g1o4n3i1za", "graph5er.", "griev1", "g1utan", "hair1s", "ha2p3ar5r", + "hatch1", "hex2a3", "hite3sid", "h3i5pel1a4", "hnau3z", "ho6r1ic.", "h2t1eou", "hypo1tha", "id4ios", + "ifac1et", "ign4it", "ignit1er", "i4jk", "im3ped3a", "infra1s2", "i5nitely.", "irre6v3oc", "i1tesima", + "ith5i2l", "itin5er5ar", "janu3a", "japan1e2s", "je1re1m", "1ke6ling", "1ki5netic", "1kovian", "k3sha", + "la4c3i5e", "lai6n3ess", "lar5ce1n", "l3chai", "l3chil6d1", "lead6er.", "lea4s1a", "1lec3ta6b", + "le3g6en2dre", "1le1noid", "lith1o5g", "ll1fl", "l2l3ish", "l5mo3nell", "lo1bot1o1", "lo2ges.", "load4ed.", + "load6er.", "l3tea", "lth5i2ly", "lue1p", "1lunk3er", "1lum5bia.", "3lyg1a1mi", "ly5styr", "ma1la1p", "m2an.", + "man3u1sc", "mar1gin1", "medi2c", "med3i3cin", "medio6c1", "me3gran3", "m2en.", "3mi3da5b", "3milita", + "mil2l1ag", "mil5li5li", "mi6n3is.", "mi1n2ut1er", "mi1n2ut1est", "m3ma1b", "5maph1ro1", "5moc1ra1t", + "mo5e2las", "mol1e5c", "mon4ey1l", "mono3ch", "mo4no1en", "moro6n5is", "mono1s6", "moth4et2", "m1ou3sin", + "m5shack2", "mu2dro", "mul2ti5u", "n3ar4chs.", "n3ch2es1t", "ne3back", "2ne1ski", "n1dieck", "nd3thr", + "nfi6n3ites", "4n5i4an.", "nge5nes", "ng1ho", "ng1spr", "nk3rup", "n5less", "5noc3er1os", "nom1a6l", + "nom5e1no", "n1o1mist", "non1eq", "non1i4so", "5nop1oly.", "no1vemb", "ns5ceiv", "ns4moo", "ntre1p", + "obli2g1", "o3chas", "odel3li", "odit1ic", "oerst2", "oke1st", "o3les3ter", "oli3gop1o1", "o1lo3n4om", + "o3mecha6", "onom1ic", "o3norma", "o3no2t1o3n", "o3nou", "op1ism.", "or4tho3ni4t", "orth1ri", "or5tively", + "o4s3pher", "o5test1er", "o5tes3tor", "oth3e1o1s", "ou3ba3do", "o6v3i4an.", "oxi6d1ic", "pal6mat", + "parag6ra4", "par4a1le", "param4", "para3me", "pee2v1", "phi2l3ant", "phi5lat1e3l", "pi2c1a3d", "pli2c1ab", + "pli5nar", "poin3ca", "1pole.", "poly1e", "po3lyph1ono", "1prema3c", "pre1neu", "pres2pli", "pro2cess", + "proc3i3ty.", "pro2g1e", "3pseu2d", "pseu3d6o3d2", "pseu3d6o3f2", "pto3mat4", "p5trol3", "pu5bes5c", + "quain2t1e", "qu6a3si3", "quasir6", "quasis6", "quin5tes5s", "qui3v4ar", "r1abolic", "3rab1o1loi", + "ra3chu", "r3a3dig", "radi1o6g", "r2amen", "3ra4m5e1triz", "ra3mou", "ra5n2has", "ra1or", "r3bin1ge", + "re2c3i1pr", "rec5t6ang", "re4t1ribu", "r3ial.", "riv1o1l", "6rk.", "rk1ho", "r1krau", "6rks.", "r5le5qu", + "ro1bot1", "ro5e2las", "ro5epide1", "ro3mesh", "ro1tron", "r3pau5li", "rse1rad1i", "r1thou", "r1treu", + "r1veil", "rz1sc", "sales3c", "sales5w", "5sa3par5il", "sca6p1er", "sca2t1ol", "s4chitz", "schro1ding1", + "1sci2utt", "scrap4er.", "scy4th1", "sem1a1ph", "se3mes1t", "se1mi6t5ic", "sep3temb", "shoe1st", "sid2ed.", + "side5st", "side5sw", "si5resid", "sky1sc", "3slova1kia", "3s2og1a1my", "so2lute", "3s2pace", "1s2pacin", + "spe3cio", "spher1o", "spi2c1il", "spokes5w", "sports3c", "sports3w", "s3qui3to", "s2s1a3chu1", "ss3hat", + "s2s3i4an.", "s5sign5a3b", "1s2tamp", "s2t1ant5shi", "star3tli", "sta1ti", "st5b", "1stor1ab", "strat1a1g", + "strib5ut", "st5scr", "stu1pi4d1", "styl1is", "su2per1e6", "1sync", "1syth3i2", "swimm6", "5tab1o1lism", + "ta3gon.", "talk1a5", "t1a1min", "t6ap6ath", "5tar2rh", "tch1c", "tch3i1er", "t1cr", "teach4er.", "tele2g", + "tele1r6o", "3ter1gei", "ter2ic.", "t3ess2es", "tha4l1am", "tho3don", "th1o5gen1i", "tho1k2er", "thy4l1an", + "thy3sc", "2t3i4an.", "ti2n3o1m", "t1li2er", "tolo2gy", "tot3ic", "trai3tor1", "tra1vers", "travers3a3b", + "treach1e", "tr4ial.", "3tro1le1um", "trof4ic.", "tro3fit", "tro1p2is", "3trop1o5les", "3trop1o5lis", + "t1ro1pol3it", "tsch3ie", "ttrib1ut1", "turn3ar", "t1wh", "ty2p5al", "ua3drati", "uad1ratu", "u5do3ny", + "uea1m", "u2r1al.", "uri4al.", "us2er.", "v1ativ", "v1oir5du1", "va6guer", "vaude3v", "1verely.", "v1er1eig", + "ves1tite", "vi1vip3a3r", "voice1p", "waste3w6a2", "wave1g4", "w3c", "week1n", "wide5sp", "wo4k1en", + "wrap3aro", "writ6er.", "x1q", "xquis3", "y5che3d", "ym5e5try", "y1stro", "yes5ter1y", "z3ian.", "z3o1phr", + "z2z3w" + ] + +getWordPoints :: String -> [Int] +getWordPoints s = + case T.lookup (map toLower s) exceptions of + [] -> let s' = '.':s ++ "." in + getFromPattern s' + l -> head l + + +getFromPattern :: String -> [Int] +getFromPattern s = + let startPoints = map (const 0) $ s + lookP c [] = [] + lookP c x = + let r = T.lookup x patterns + in + (map ((++) c) r) ++ lookP (0:c) (tail x) + + foundPoints = reverse . lookP [] $ s + completeWithZeros x found = found + onlyMax a b = zipWith max (a ++ repeat 0) b + in + foldr onlyMax startPoints foundPoints + +hyphenate :: String -> [String] +hyphenate s = + let p = drop 1 . lastPointIsNull . getWordPoints $ s + lastPointIsNull l = let (h,t) = splitAt 1 (reverse l) in reverse (head h:0:drop 1 t) + cutFromList c [] = [reverse c] + cutFromList c ((ch,pnb):l) = + if pnb `mod` 2 == 1 + then if null c + then cutFromList [ch] l + else reverse c : cutFromList [ch] l + else cutFromList (ch:c) l + in + cutFromList [] (zip s p) + +main :: IO () +main = + print exceptions hunk ./Graphics/PDF/Typesetting.hs 39 - , forceNewLine hunk ./Graphics/PDF/Typesetting.hs 40 - , paragraph - -- ** Paragraph construction operators hunk ./Graphics/PDF/Typesetting.hs 44 + -- ** Paragraph construction operators + , forceNewLine + , paragraph + , endPara + , startPara hunk ./HPDF.cabal 2 -Version: 1.2 +Version: 1.3 adddir ./Graphics/PDF/Hyphenate hunk ./Graphics/PDF.hs 49 + , module Graphics.PDF.Hyphenate hunk ./Graphics/PDF.hs 52 +import Graphics.PDF.Hyphenate hunk ./Graphics/PDF/Data/Trie.hs 1 -module Trie ( - MapString +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2006 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Trie data structure +--------------------------------------------------------- +-- #hide +module Graphics.PDF.Data.Trie( + MapString(..) hunk ./Graphics/PDF/Data/Trie.hs 37 -lookup [] (Trie (Just a) b) = [a] -lookup [] (Trie Nothing b) = [] +lookup [] (Trie (Just a) _) = [a] +lookup [] (Trie Nothing _) = [] hunk ./Graphics/PDF/Data/Trie.hs 49 -insert [] v (Trie a b) = Trie (Just v) b +insert [] v (Trie _ b) = Trie (Just v) b hunk ./Graphics/PDF/Hyphenate.hs 1 -module Hyphenate where - -import Data.Char(isAlpha,isDigit,toLower) -import qualified Trie as T -import Data.List(tails,unfoldr) - -exceptionPoints :: String -> [Int] -exceptionPoints s = 0 : map onlyHyphen s - where - onlyHyphen '-' = 1 - onlyHyphen _ = 0 - -removeHyphen :: String -> String -removeHyphen = filter ((/=) '-') - -exceptions = T.fromList . map createException $ exceptionList - where - createException x = (removeHyphen x,exceptionPoints x) - -exceptionList = [ - "as-so-ciate" - , "as-so-ciates" - , "dec-li-na-tion" - , "oblig-a-tory" - , "phil-an-thropic" - , "present" - , "presents" - , "project" - , "projects" - , "reci-procity" - , "re-cog-ni-zance" - , "ref-or-ma-tion" - , "ret-ri-bu-tion ta-ble" - ] - -isChar :: Char -> Bool -isChar = not . isDigit - -fromDigit :: Char -> Int -fromDigit c = fromEnum c - fromEnum '0' - -toNumber :: Char -> Int -toNumber x = if isChar x then 0 else fromDigit x +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2006 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Hyphenate a string +--------------------------------------------------------- +module Graphics.PDF.Hyphenate( + -- * Type + HyphenationDatabase(..) + , MapString + -- * Hyphenation databases + , mkCustomLanguage + , mkExceptions + -- * Hyphenation + , hyphenate + ) where hunk ./Graphics/PDF/Hyphenate.hs 23 -simplify :: [Int] -> [Int] -simplify (a:b:c:l) | a /= 0 && b == 0 && c /= 0 = a:simplify (c:l) - | otherwise = a:simplify (b:c:l) -simplify a = a - -split :: (Char -> Bool) -> String -> [Int] -split f = simplify . map toNumber . unfoldr (split' f) +import qualified Graphics.PDF.Data.Trie as T +import qualified Graphics.PDF.Hyphenate.English as E +import Graphics.PDF.Data.Trie(MapString) +import Graphics.PDF.Hyphenate.LowLevel +import Data.Char(toLower) hunk ./Graphics/PDF/Hyphenate.hs 29 -split' :: (Char -> Bool) -> String -> Maybe (Char, String) -split' f l | null l = Nothing - | otherwise = if null h then Just (' ', drop 1 t) else Just (head h, t) - where (h, t) = span f l - -convertPattern :: String -> (String,[Int]) -convertPattern s = - let s' = filter isChar s - p = split isDigit s - in - (s',p) - -patterns = T.fromList . map convertPattern $ patternList +exceptions :: HyphenationDatabase -> T.MapString [Int] +exceptions (English _) = E.exceptions +exceptions (CustomLanguage e _) = e hunk ./Graphics/PDF/Hyphenate.hs 33 -patternList = --- Knuth and Liang's original hyphenation patterns from classic TeX. --- In the public domain. - [ - ".ach4", ".ad4der", ".af1t", ".al3t", ".am5at", ".an5c", ".ang4", ".ani5m", ".ant4", ".an3te", ".anti5s", ".ar5s", - ".ar4tie", ".ar4ty", ".as3c", ".as1p", ".as1s", ".aster5", ".atom5", ".au1d", ".av4i", ".awn4", ".ba4g", ".ba5na", - ".bas4e", ".ber4", ".be5ra", ".be3sm", ".be5sto", ".bri2", ".but4ti", ".cam4pe", ".can5c", ".capa5b", ".car5ol", - ".ca4t", ".ce4la", ".ch4", ".chill5i", ".ci2", ".cit5r", ".co3e", ".co4r", ".cor5ner", ".de4moi", ".de3o", ".de3ra", - ".de3ri", ".des4c", ".dictio5", ".do4t", ".du4c", ".dumb5", ".earth5", ".eas3i", ".eb4", ".eer4", ".eg2", ".el5d", - ".el3em", ".enam3", ".en3g", ".en3s", ".eq5ui5t", ".er4ri", ".es3", ".eu3", ".eye5", ".fes3", ".for5mer", ".ga2", - ".ge2", ".gen3t4", ".ge5og", ".gi5a", ".gi4b", ".go4r", ".hand5i", ".han5k", ".he2", ".hero5i", ".hes3", ".het3", - ".hi3b", ".hi3er", ".hon5ey", ".hon3o", ".hov5", ".id4l", ".idol3", ".im3m", ".im5pin", ".in1", ".in3ci", ".ine2", - ".in2k", ".in3s", ".ir5r", ".is4i", ".ju3r", ".la4cy", ".la4m", ".lat5er", ".lath5", ".le2", ".leg5e", ".len4", - ".lep5", ".lev1", ".li4g", ".lig5a", ".li2n", ".li3o", ".li4t", ".mag5a5", ".mal5o", ".man5a", ".mar5ti", ".me2", - ".mer3c", ".me5ter", ".mis1", ".mist5i", ".mon3e", ".mo3ro", ".mu5ta", ".muta5b", ".ni4c", ".od2", ".odd5", - ".of5te", ".or5ato", ".or3c", ".or1d", ".or3t", ".os3", ".os4tl", ".oth3", ".out3", ".ped5al", ".pe5te", ".pe5tit", - ".pi4e", ".pio5n", ".pi2t", ".pre3m", ".ra4c", ".ran4t", ".ratio5na", ".ree2", ".re5mit", ".res2", ".re5stat", - ".ri4g", ".rit5u", ".ro4q", ".ros5t", ".row5d", ".ru4d", ".sci3e", ".self5", ".sell5", ".se2n", ".se5rie", ".sh2", - ".si2", ".sing4", ".st4", ".sta5bl", ".sy2", ".ta4", ".te4", ".ten5an", ".th2", ".ti2", ".til4", ".tim5o5", ".ting4", - ".tin5k", ".ton4a", ".to4p", ".top5i", ".tou5s", ".trib5ut", ".un1a", ".un3ce", ".under5", ".un1e", ".un5k", - ".un5o", ".un3u", ".up3", ".ure3", ".us5a", ".ven4de", ".ve5ra", ".wil5i", ".ye4", "4ab.", "a5bal", "a5ban", "abe2", - "ab5erd", "abi5a", "ab5it5ab", "ab5lat", "ab5o5liz", "4abr", "ab5rog", "ab3ul", "a4car", "ac5ard", "ac5aro", - "a5ceou", "ac1er", "a5chet", "4a2ci", "a3cie", "ac1in", "a3cio", "ac5rob", "act5if", "ac3ul", "ac4um", "a2d", "ad4din", - "ad5er.", "2adi", "a3dia", "ad3ica", "adi4er", "a3dio", "a3dit", "a5diu", "ad4le", "ad3ow", "ad5ran", "ad4su", "4adu", - "a3duc", "ad5um", "ae4r", "aeri4e", "a2f", "aff4", "a4gab", "aga4n", "ag5ell", "age4o", "4ageu", "ag1i", "4ag4l", "ag1n", - "a2go", "3agog", "ag3oni", "a5guer", "ag5ul", "a4gy", "a3ha", "a3he", "ah4l", "a3ho", "ai2", "a5ia", "a3ic.", "ai5ly", - "a4i4n", "ain5in", "ain5o", "ait5en", "a1j", "ak1en", "al5ab", "al3ad", "a4lar", "4aldi", "2ale", "al3end", "a4lenti", - "a5le5o", "al1i", "al4ia.", "ali4e", "al5lev", "4allic", "4alm", "a5log.", "a4ly.", "4alys", "5a5lyst", "5alyt", - "3alyz", "4ama", "am5ab", "am3ag", "ama5ra", "am5asc", "a4matis", "a4m5ato", "am5era", "am3ic", "am5if", "am5ily", - "am1in", "ami4no", "a2mo", "a5mon", "amor5i", "amp5en", "a2n", "an3age", "3analy", "a3nar", "an3arc", "anar4i", - "a3nati", "4and", "ande4s", "an3dis", "an1dl", "an4dow", "a5nee", "a3nen", "an5est.", "a3neu", "2ang", "ang5ie", - "an1gl", "a4n1ic", "a3nies", "an3i3f", "an4ime", "a5nimi", "a5nine", "an3io", "a3nip", "an3ish", "an3it", "a3niu", - "an4kli", "5anniz", "ano4", "an5ot", "anoth5", "an2sa", "an4sco", "an4sn", "an2sp", "ans3po", "an4st", "an4sur", - "antal4", "an4tie", "4anto", "an2tr", "an4tw", "an3ua", "an3ul", "a5nur", "4ao", "apar4", "ap5at", "ap5ero", "a3pher", - "4aphi", "a4pilla", "ap5illar", "ap3in", "ap3ita", "a3pitu", "a2pl", "apoc5", "ap5ola", "apor5i", "apos3t", - "aps5es", "a3pu", "aque5", "2a2r", "ar3act", "a5rade", "ar5adis", "ar3al", "a5ramete", "aran4g", "ara3p", "ar4at", - "a5ratio", "ar5ativ", "a5rau", "ar5av4", "araw4", "arbal4", "ar4chan", "ar5dine", "ar4dr", "ar5eas", "a3ree", - "ar3ent", "a5ress", "ar4fi", "ar4fl", "ar1i", "ar5ial", "ar3ian", "a3riet", "ar4im", "ar5inat", "ar3io", "ar2iz", - "ar2mi", "ar5o5d", "a5roni", "a3roo", "ar2p", "ar3q", "arre4", "ar4sa", "ar2sh", "4as.", "as4ab", "as3ant", "ashi4", - "a5sia.", "a3sib", "a3sic", "5a5si4t", "ask3i", "as4l", "a4soc", "as5ph", "as4sh", "as3ten", "as1tr", "asur5a", "a2ta", - "at3abl", "at5ac", "at3alo", "at5ap", "ate5c", "at5ech", "at3ego", "at3en.", "at3era", "ater5n", "a5terna", - "at3est", "at5ev", "4ath", "ath5em", "a5then", "at4ho", "ath5om", "4ati.", "a5tia", "at5i5b", "at1ic", "at3if", - "ation5ar", "at3itu", "a4tog", "a2tom", "at5omiz", "a4top", "a4tos", "a1tr", "at5rop", "at4sk", "at4tag", "at5te", - "at4th", "a2tu", "at5ua", "at5ue", "at3ul", "at3ura", "a2ty", "au4b", "augh3", "au3gu", "au4l2", "aun5d", "au3r", - "au5sib", "aut5en", "au1th", "a2va", "av3ag", "a5van", "ave4no", "av3era", "av5ern", "av5ery", "av1i", "avi4er", - "av3ig", "av5oc", "a1vor", "3away", "aw3i", "aw4ly", "aws4", "ax4ic", "ax4id", "ay5al", "aye4", "ays4", "azi4er", "azz5i", - "5ba.", "bad5ger", "ba4ge", "bal1a", "ban5dag", "ban4e", "ban3i", "barbi5", "bari4a", "bas4si", "1bat", "ba4z", "2b1b", - "b2be", "b3ber", "bbi4na", "4b1d", "4be.", "beak4", "beat3", "4be2d", "be3da", "be3de", "be3di", "be3gi", "be5gu", "1bel", - "be1li", "be3lo", "4be5m", "be5nig", "be5nu", "4bes4", "be3sp", "be5str", "3bet", "bet5iz", "be5tr", "be3tw", "be3w", - "be5yo", "2bf", "4b3h", "bi2b", "bi4d", "3bie", "bi5en", "bi4er", "2b3if", "1bil", "bi3liz", "bina5r4", "bin4d", "bi5net", - "bi3ogr", "bi5ou", "bi2t", "3bi3tio", "bi3tr", "3bit5ua", "b5itz", "b1j", "bk4", "b2l2", "blath5", "b4le.", "blen4", - "5blesp", "b3lis", "b4lo", "blun4t", "4b1m", "4b3n", "bne5g", "3bod", "bod3i", "bo4e", "bol3ic", "bom4bi", "bon4a", - "bon5at", "3boo", "5bor.", "4b1ora", "bor5d", "5bore", "5bori", "5bos4", "b5ota", "both5", "bo4to", "bound3", "4bp", - "4brit", "broth3", "2b5s2", "bsor4", "2bt", "bt4l", "b4to", "b3tr", "buf4fer", "bu4ga", "bu3li", "bumi4", "bu4n", - "bunt4i", "bu3re", "bus5ie", "buss4e", "5bust", "4buta", "3butio", "b5uto", "b1v", "4b5w", "5by.", "bys4", "1ca", - "cab3in", "ca1bl", "cach4", "ca5den", "4cag4", "2c5ah", "ca3lat", "cal4la", "call5in", "4calo", "can5d", "can4e", - "can4ic", "can5is", "can3iz", "can4ty", "cany4", "ca5per", "car5om", "cast5er", "cas5tig", "4casy", "ca4th", - "4cativ", "cav5al", "c3c", "ccha5", "cci4a", "ccompa5", "ccon4", "ccou3t", "2ce.", "4ced.", "4ceden", "3cei", "5cel.", - "3cell", "1cen", "3cenc", "2cen4e", "4ceni", "3cent", "3cep", "ce5ram", "4cesa", "3cessi", "ces5si5b", "ces5t", "cet4", - "c5e4ta", "cew4", "2ch", "4ch.", "4ch3ab", "5chanic", "ch5a5nis", "che2", "cheap3", "4ched", "che5lo", "3chemi", - "ch5ene", "ch3er.", "ch3ers", "4ch1in", "5chine.", "ch5iness", "5chini", "5chio", "3chit", "chi2z", "3cho2", - "ch4ti", "1ci", "3cia", "ci2a5b", "cia5r", "ci5c", "4cier", "5cific.", "4cii", "ci4la", "3cili", "2cim", "2cin", "c4ina", - "3cinat", "cin3em", "c1ing", "c5ing.", "5cino", "cion4", "4cipe", "ci3ph", "4cipic", "4cista", "4cisti", "2c1it", - "cit3iz", "5ciz", "ck1", "ck3i", "1c4l4", "4clar", "c5laratio", "5clare", "cle4m", "4clic", "clim4", "cly4", "c5n", "1co", - "co5ag", "coe2", "2cog", "co4gr", "coi4", "co3inc", "col5i", "5colo", "col3or", "com5er", "con4a", "c4one", "con3g", - "con5t", "co3pa", "cop3ic", "co4pl", "4corb", "coro3n", "cos4e", "cov1", "cove4", "cow5a", "coz5e", "co5zi", "c1q", - "cras5t", "5crat.", "5cratic", "cre3at", "5cred", "4c3reta", "cre4v", "cri2", "cri5f", "c4rin", "cris4", "5criti", - "cro4pl", "crop5o", "cros4e", "cru4d", "4c3s2", "2c1t", "cta4b", "ct5ang", "c5tant", "c2te", "c3ter", "c4ticu", - "ctim3i", "ctu4r", "c4tw", "cud5", "c4uf", "c4ui", "cu5ity", "5culi", "cul4tis", "3cultu", "cu2ma", "c3ume", "cu4mi", - "3cun", "cu3pi", "cu5py", "cur5a4b", "cu5ria", "1cus", "cuss4i", "3c4ut", "cu4tie", "4c5utiv", "4cutr", "1cy", "cze4", - "1d2a", "5da.", "2d3a4b", "dach4", "4daf", "2dag", "da2m2", "dan3g", "dard5", "dark5", "4dary", "3dat", "4dativ", "4dato", - "5dav4", "dav5e", "5day", "d1b", "d5c", "d1d4", "2de.", "deaf5", "deb5it", "de4bon", "decan4", "de4cil", "de5com", - "2d1ed", "4dee.", "de5if", "deli4e", "del5i5q", "de5lo", "d4em", "5dem.", "3demic", "dem5ic.", "de5mil", "de4mons", - "demor5", "1den", "de4nar", "de3no", "denti5f", "de3nu", "de1p", "de3pa", "depi4", "de2pu", "d3eq", "d4erh", "5derm", - "dern5iz", "der5s", "des2", "d2es.", "de1sc", "de2s5o", "des3ti", "de3str", "de4su", "de1t", "de2to", "de1v", "dev3il", - "4dey", "4d1f", "d4ga", "d3ge4t", "dg1i", "d2gy", "d1h2", "5di.", "1d4i3a", "dia5b", "di4cam", "d4ice", "3dict", "3did", - "5di3en", "d1if", "di3ge", "di4lato", "d1in", "1dina", "3dine.", "5dini", "di5niz", "1dio", "dio5g", "di4pl", "dir2", - "di1re", "dirt5i", "dis1", "5disi", "d4is3t", "d2iti", "1di1v", "d1j", "d5k2", "4d5la", "3dle.", "3dled", "3dles.", - "4dless", "2d3lo", "4d5lu", "2dly", "d1m", "4d1n4", "1do", "3do.", "do5de", "5doe", "2d5of", "d4og", "do4la", "doli4", - "do5lor", "dom5iz", "do3nat", "doni4", "doo3d", "dop4p", "d4or", "3dos", "4d5out", "do4v", "3dox", "d1p", "1dr", - "drag5on", "4drai", "dre4", "drea5r", "5dren", "dri4b", "dril4", "dro4p", "4drow", "5drupli", "4dry", "2d1s2", "ds4p", - "d4sw", "d4sy", "d2th", "1du", "d1u1a", "du2c", "d1uca", "duc5er", "4duct.", "4ducts", "du5el", "du4g", "d3ule", "dum4be", - "du4n", "4dup", "du4pe", "d1v", "d1w", "d2y", "5dyn", "dy4se", "dys5p", "e1a4b", "e3act", "ead1", "ead5ie", "ea4ge", - "ea5ger", "ea4l", "eal5er", "eal3ou", "eam3er", "e5and", "ear3a", "ear4c", "ear5es", "ear4ic", "ear4il", "ear5k", - "ear2t", "eart3e", "ea5sp", "e3ass", "east3", "ea2t", "eat5en", "eath3i", "e5atif", "e4a3tu", "ea2v", "eav3en", - "eav5i", "eav5o", "2e1b", "e4bel.", "e4bels", "e4ben", "e4bit", "e3br", "e4cad", "ecan5c", "ecca5", "e1ce", "ec5essa", - "ec2i", "e4cib", "ec5ificat", "ec5ifie", "ec5ify", "ec3im", "eci4t", "e5cite", "e4clam", "e4clus", "e2col", - "e4comm", "e4compe", "e4conc", "e2cor", "ec3ora", "eco5ro", "e1cr", "e4crem", "ec4tan", "ec4te", "e1cu", "e4cul", - "ec3ula", "2e2da", "4ed3d", "e4d1er", "ede4s", "4edi", "e3dia", "ed3ib", "ed3ica", "ed3im", "ed1it", "edi5z", "4edo", - "e4dol", "edon2", "e4dri", "e4dul", "ed5ulo", "ee2c", "eed3i", "ee2f", "eel3i", "ee4ly", "ee2m", "ee4na", "ee4p1", - "ee2s4", "eest4", "ee4ty", "e5ex", "e1f", "e4f3ere", "1eff", "e4fic", "5efici", "efil4", "e3fine", "ef5i5nite", - "3efit", "efor5es", "e4fuse.", "4egal", "eger4", "eg5ib", "eg4ic", "eg5ing", "e5git5", "eg5n", "e4go.", "e4gos", - "eg1ul", "e5gur", "5egy", "e1h4", "eher4", "ei2", "e5ic", "ei5d", "eig2", "ei5gl", "e3imb", "e3inf", "e1ing", "e5inst", - "eir4d", "eit3e", "ei3th", "e5ity", "e1j", "e4jud", "ej5udi", "eki4n", "ek4la", "e1la", "e4la.", "e4lac", "elan4d", - "el5ativ", "e4law", "elaxa4", "e3lea", "el5ebra", "5elec", "e4led", "el3ega", "e5len", "e4l1er", "e1les", "el2f", - "el2i", "e3libe", "e4l5ic.", "el3ica", "e3lier", "el5igib", "e5lim", "e4l3ing", "e3lio", "e2lis", "el5ish", - "e3liv3", "4ella", "el4lab", "ello4", "e5loc", "el5og", "el3op.", "el2sh", "el4ta", "e5lud", "el5ug", "e4mac", "e4mag", - "e5man", "em5ana", "em5b", "e1me", "e2mel", "e4met", "em3ica", "emi4e", "em5igra", "em1in2", "em5ine", "em3i3ni", - "e4mis", "em5ish", "e5miss", "em3iz", "5emniz", "emo4g", "emoni5o", "em3pi", "e4mul", "em5ula", "emu3n", "e3my", - "en5amo", "e4nant", "ench4er", "en3dic", "e5nea", "e5nee", "en3em", "en5ero", "en5esi", "en5est", "en3etr", "e3new", - "en5ics", "e5nie", "e5nil", "e3nio", "en3ish", "en3it", "e5niu", "5eniz", "4enn", "4eno", "eno4g", "e4nos", "en3ov", - "en4sw", "ent5age", "4enthes", "en3ua", "en5uf", "e3ny.", "4en3z", "e5of", "eo2g", "e4oi4", "e3ol", "eop3ar", "e1or", - "eo3re", "eo5rol", "eos4", "e4ot", "eo4to", "e5out", "e5ow", "e2pa", "e3pai", "ep5anc", "e5pel", "e3pent", "ep5etitio", - "ephe4", "e4pli", "e1po", "e4prec", "ep5reca", "e4pred", "ep3reh", "e3pro", "e4prob", "ep4sh", "ep5ti5b", "e4put", - "ep5uta", "e1q", "equi3l", "e4q3ui3s", "er1a", "era4b", "4erand", "er3ar", "4erati.", "2erb", "er4bl", "er3ch", - "er4che", "2ere.", "e3real", "ere5co", "ere3in", "er5el.", "er3emo", "er5ena", "er5ence", "4erene", "er3ent", - "ere4q", "er5ess", "er3est", "eret4", "er1h", "er1i", "e1ria4", "5erick", "e3rien", "eri4er", "er3ine", "e1rio", - "4erit", "er4iu", "eri4v", "e4riva", "er3m4", "er4nis", "4ernit", "5erniz", "er3no", "2ero", "er5ob", "e5roc", "ero4r", - "er1ou", "er1s", "er3set", "ert3er", "4ertl", "er3tw", "4eru", "eru4t", "5erwau", "e1s4a", "e4sage.", "e4sages", - "es2c", "e2sca", "es5can", "e3scr", "es5cu", "e1s2e", "e2sec", "es5ecr", "es5enc", "e4sert.", "e4serts", "e4serva", - "4esh", "e3sha", "esh5en", "e1si", "e2sic", "e2sid", "es5iden", "es5igna", "e2s5im", "es4i4n", "esis4te", "esi4u", - "e5skin", "es4mi", "e2sol", "es3olu", "e2son", "es5ona", "e1sp", "es3per", "es5pira", "es4pre", "2ess", "es4si4b", - "estan4", "es3tig", "es5tim", "4es2to", "e3ston", "2estr", "e5stro", "estruc5", "e2sur", "es5urr", "es4w", "eta4b", - "eten4d", "e3teo", "ethod3", "et1ic", "e5tide", "etin4", "eti4no", "e5tir", "e5titio", "et5itiv", "4etn", "et5ona", - "e3tra", "e3tre", "et3ric", "et5rif", "et3rog", "et5ros", "et3ua", "et5ym", "et5z", "4eu", "e5un", "e3up", "eu3ro", - "eus4", "eute4", "euti5l", "eu5tr", "eva2p5", "e2vas", "ev5ast", "e5vea", "ev3ell", "evel3o", "e5veng", "even4i", - "ev1er", "e5verb", "e1vi", "ev3id", "evi4l", "e4vin", "evi4v", "e5voc", "e5vu", "e1wa", "e4wag", "e5wee", "e3wh", "ewil5", - "ew3ing", "e3wit", "1exp", "5eyc", "5eye.", "eys4", "1fa", "fa3bl", "fab3r", "fa4ce", "4fag", "fain4", "fall5e", "4fa4ma", - "fam5is", "5far", "far5th", "fa3ta", "fa3the", "4fato", "fault5", "4f5b", "4fd", "4fe.", "feas4", "feath3", "fe4b", - "4feca", "5fect", "2fed", "fe3li", "fe4mo", "fen2d", "fend5e", "fer1", "5ferr", "fev4", "4f1f", "f4fes", "f4fie", - "f5fin.", "f2f5is", "f4fly", "f2fy", "4fh", "1fi", "fi3a", "2f3ic.", "4f3ical", "f3ican", "4ficate", "f3icen", - "fi3cer", "fic4i", "5ficia", "5ficie", "4fics", "fi3cu", "fi5del", "fight5", "fil5i", "fill5in", "4fily", "2fin", - "5fina", "fin2d5", "fi2ne", "f1in3g", "fin4n", "fis4ti", "f4l2", "f5less", "flin4", "flo3re", "f2ly5", "4fm", "4fn", - "1fo", "5fon", "fon4de", "fon4t", "fo2r", "fo5rat", "for5ay", "fore5t", "for4i", "fort5a", "fos5", "4f5p", "fra4t", - "f5rea", "fres5c", "fri2", "fril4", "frol5", "2f3s", "2ft", "f4to", "f2ty", "3fu", "fu5el", "4fug", "fu4min", "fu5ne", - "fu3ri", "fusi4", "fus4s", "4futa", "1fy", "1ga", "gaf4", "5gal.", "3gali", "ga3lo", "2gam", "ga5met", "g5amo", "gan5is", - "ga3niz", "gani5za", "4gano", "gar5n4", "gass4", "gath3", "4gativ", "4gaz", "g3b", "gd4", "2ge.", "2ged", "geez4", - "gel4in", "ge5lis", "ge5liz", "4gely", "1gen", "ge4nat", "ge5niz", "4geno", "4geny", "1geo", "ge3om", "g4ery", "5gesi", - "geth5", "4geto", "ge4ty", "ge4v", "4g1g2", "g2ge", "g3ger", "gglu5", "ggo4", "gh3in", "gh5out", "gh4to", "5gi.", "1gi4a", - "gia5r", "g1ic", "5gicia", "g4ico", "gien5", "5gies.", "gil4", "g3imen", "3g4in.", "gin5ge", "5g4ins", "5gio", "3gir", - "gir4l", "g3isl", "gi4u", "5giv", "3giz", "gl2", "gla4", "glad5i", "5glas", "1gle", "gli4b", "g3lig", "3glo", "glo3r", "g1m", - "g4my", "gn4a", "g4na.", "gnet4t", "g1ni", "g2nin", "g4nio", "g1no", "g4non", "1go", "3go.", "gob5", "5goe", "3g4o4g", - "go3is", "gon2", "4g3o3na", "gondo5", "go3ni", "5goo", "go5riz", "gor5ou", "5gos.", "gov1", "g3p", "1gr", "4grada", - "g4rai", "gran2", "5graph.", "g5rapher", "5graphic", "4graphy", "4gray", "gre4n", "4gress.", "4grit", "g4ro", - "gruf4", "gs2", "g5ste", "gth3", "gu4a", "3guard", "2gue", "5gui5t", "3gun", "3gus", "4gu4t", "g3w", "1gy", "2g5y3n", - "gy5ra", "h3ab4l", "hach4", "hae4m", "hae4t", "h5agu", "ha3la", "hala3m", "ha4m", "han4ci", "han4cy", "5hand.", - "han4g", "hang5er", "hang5o", "h5a5niz", "han4k", "han4te", "hap3l", "hap5t", "ha3ran", "ha5ras", "har2d", "hard3e", - "har4le", "harp5en", "har5ter", "has5s", "haun4", "5haz", "haz3a", "h1b", "1head", "3hear", "he4can", "h5ecat", "h4ed", - "he5do5", "he3l4i", "hel4lis", "hel4ly", "h5elo", "hem4p", "he2n", "hena4", "hen5at", "heo5r", "hep5", "h4era", - "hera3p", "her4ba", "here5a", "h3ern", "h5erou", "h3ery", "h1es", "he2s5p", "he4t", "het4ed", "heu4", "h1f", "h1h", - "hi5an", "hi4co", "high5", "h4il2", "himer4", "h4ina", "hion4e", "hi4p", "hir4l", "hi3ro", "hir4p", "hir4r", "his3el", - "his4s", "hith5er", "hi2v", "4hk", "4h1l4", "hlan4", "h2lo", "hlo3ri", "4h1m", "hmet4", "2h1n", "h5odiz", "h5ods", "ho4g", - "hoge4", "hol5ar", "3hol4e", "ho4ma", "home3", "hon4a", "ho5ny", "3hood", "hoon4", "hor5at", "ho5ris", "hort3e", - "ho5ru", "hos4e", "ho5sen", "hos1p", "1hous", "house3", "hov5el", "4h5p", "4hr4", "hree5", "hro5niz", "hro3po", - "4h1s2", "h4sh", "h4tar", "ht1en", "ht5es", "h4ty", "hu4g", "hu4min", "hun5ke", "hun4t", "hus3t4", "hu4t", "h1w", - "h4wart", "hy3pe", "hy3ph", "hy2s", "2i1a", "i2al", "iam4", "iam5ete", "i2an", "4ianc", "ian3i", "4ian4t", "ia5pe", - "iass4", "i4ativ", "ia4tric", "i4atu", "ibe4", "ib3era", "ib5ert", "ib5ia", "ib3in", "ib5it.", "ib5ite", "i1bl", - "ib3li", "i5bo", "i1br", "i2b5ri", "i5bun", "4icam", "5icap", "4icar", "i4car.", "i4cara", "icas5", "i4cay", "iccu4", - "4iceo", "4ich", "2ici", "i5cid", "ic5ina", "i2cip", "ic3ipa", "i4cly", "i2c5oc", "4i1cr", "5icra", "i4cry", "ic4te", - "ictu2", "ic4t3ua", "ic3ula", "ic4um", "ic5uo", "i3cur", "2id", "i4dai", "id5anc", "id5d", "ide3al", "ide4s", "i2di", - "id5ian", "idi4ar", "i5die", "id3io", "idi5ou", "id1it", "id5iu", "i3dle", "i4dom", "id3ow", "i4dr", "i2du", "id5uo", - "2ie4", "ied4e", "5ie5ga", "ield3", "ien5a4", "ien4e", "i5enn", "i3enti", "i1er.", "i3esc", "i1est", "i3et", "4if.", - "if5ero", "iff5en", "if4fr", "4ific.", "i3fie", "i3fl", "4ift", "2ig", "iga5b", "ig3era", "ight3i", "4igi", "i3gib", - "ig3il", "ig3in", "ig3it", "i4g4l", "i2go", "ig3or", "ig5ot", "i5gre", "igu5i", "ig1ur", "i3h", "4i5i4", "i3j", "4ik", - "i1la", "il3a4b", "i4lade", "i2l5am", "ila5ra", "i3leg", "il1er", "ilev4", "il5f", "il1i", "il3ia", "il2ib", "il3io", - "il4ist", "2ilit", "il2iz", "ill5ab", "4iln", "il3oq", "il4ty", "il5ur", "il3v", "i4mag", "im3age", "ima5ry", - "imenta5r", "4imet", "im1i", "im5ida", "imi5le", "i5mini", "4imit", "im4ni", "i3mon", "i2mu", "im3ula", "2in.", - "i4n3au", "4inav", "incel4", "in3cer", "4ind", "in5dling", "2ine", "i3nee", "iner4ar", "i5ness", "4inga", "4inge", - "in5gen", "4ingi", "in5gling", "4ingo", "4ingu", "2ini", "i5ni.", "i4nia", "in3io", "in1is", "i5nite.", "5initio", - "in3ity", "4ink", "4inl", "2inn", "2i1no", "i4no4c", "ino4s", "i4not", "2ins", "in3se", "insur5a", "2int.", "2in4th", - "in1u", "i5nus", "4iny", "2io", "4io.", "ioge4", "io2gr", "i1ol", "io4m", "ion3at", "ion4ery", "ion3i", "io5ph", "ior3i", - "i4os", "io5th", "i5oti", "io4to", "i4our", "2ip", "ipe4", "iphras4", "ip3i", "ip4ic", "ip4re4", "ip3ul", "i3qua", - "iq5uef", "iq3uid", "iq3ui3t", "4ir", "i1ra", "ira4b", "i4rac", "ird5e", "ire4de", "i4ref", "i4rel4", "i4res", "ir5gi", - "ir1i", "iri5de", "ir4is", "iri3tu", "5i5r2iz", "ir4min", "iro4g", "5iron.", "ir5ul", "2is.", "is5ag", "is3ar", - "isas5", "2is1c", "is3ch", "4ise", "is3er", "3isf", "is5han", "is3hon", "ish5op", "is3ib", "isi4d", "i5sis", "is5itiv", - "4is4k", "islan4", "4isms", "i2so", "iso5mer", "is1p", "is2pi", "is4py", "4is1s", "is4sal", "issen4", "is4ses", - "is4ta.", "is1te", "is1ti", "ist4ly", "4istral", "i2su", "is5us", "4ita.", "ita4bi", "i4tag", "4ita5m", "i3tan", - "i3tat", "2ite", "it3era", "i5teri", "it4es", "2ith", "i1ti", "4itia", "4i2tic", "it3ica", "5i5tick", "it3ig", - "it5ill", "i2tim", "2itio", "4itis", "i4tism", "i2t5o5m", "4iton", "i4tram", "it5ry", "4itt", "it3uat", "i5tud", - "it3ul", "4itz.", "i1u", "2iv", "iv3ell", "iv3en.", "i4v3er.", "i4vers.", "iv5il.", "iv5io", "iv1it", "i5vore", - "iv3o3ro", "i4v3ot", "4i5w", "ix4o", "4iy", "4izar", "izi4", "5izont", "5ja", "jac4q", "ja4p", "1je", "jer5s", "4jestie", - "4jesty", "jew3", "jo4p", "5judg", "3ka.", "k3ab", "k5ag", "kais4", "kal4", "k1b", "k2ed", "1kee", "ke4g", "ke5li", "k3en4d", - "k1er", "kes4", "k3est.", "ke4ty", "k3f", "kh4", "k1i", "5ki.", "5k2ic", "k4ill", "kilo5", "k4im", "k4in.", "kin4de", - "k5iness", "kin4g", "ki4p", "kis4", "k5ish", "kk4", "k1l", "4kley", "4kly", "k1m", "k5nes", "1k2no", "ko5r", "kosh4", "k3ou", - "kro5n", "4k1s2", "k4sc", "ks4l", "k4sy", "k5t", "k1w", "lab3ic", "l4abo", "laci4", "l4ade", "la3dy", "lag4n", "lam3o", - "3land", "lan4dl", "lan5et", "lan4te", "lar4g", "lar3i", "las4e", "la5tan", "4lateli", "4lativ", "4lav", "la4v4a", - "2l1b", "lbin4", "4l1c2", "lce4", "l3ci", "2ld", "l2de", "ld4ere", "ld4eri", "ldi4", "ld5is", "l3dr", "l4dri", "le2a", - "le4bi", "left5", "5leg.", "5legg", "le4mat", "lem5atic", "4len.", "3lenc", "5lene.", "1lent", "le3ph", "le4pr", - "lera5b", "ler4e", "3lerg", "3l4eri", "l4ero", "les2", "le5sco", "5lesq", "3less", "5less.", "l3eva", "lev4er.", - "lev4era", "lev4ers", "3ley", "4leye", "2lf", "l5fr", "4l1g4", "l5ga", "lgar3", "l4ges", "lgo3", "2l3h", "li4ag", "li2am", - "liar5iz", "li4as", "li4ato", "li5bi", "5licio", "li4cor", "4lics", "4lict.", "l4icu", "l3icy", "l3ida", "lid5er", - "3lidi", "lif3er", "l4iff", "li4fl", "5ligate", "3ligh", "li4gra", "3lik", "4l4i4l", "lim4bl", "lim3i", "li4mo", - "l4im4p", "l4ina", "1l4ine", "lin3ea", "lin3i", "link5er", "li5og", "4l4iq", "lis4p", "l1it", "l2it.", "5litica", - "l5i5tics", "liv3er", "l1iz", "4lj", "lka3", "l3kal", "lka4t", "l1l", "l4law", "l2le", "l5lea", "l3lec", "l3leg", "l3lel", - "l3le4n", "l3le4t", "ll2i", "l2lin4", "l5lina", "ll4o", "lloqui5", "ll5out", "l5low", "2lm", "l5met", "lm3ing", - "l4mod", "lmon4", "2l1n2", "3lo.", "lob5al", "lo4ci", "4lof", "3logic", "l5ogo", "3logu", "lom3er", "5long", "lon4i", - "l3o3niz", "lood5", "5lope.", "lop3i", "l3opm", "lora4", "lo4rato", "lo5rie", "lor5ou", "5los.", "los5et", - "5losophiz", "5losophy", "los4t", "lo4ta", "loun5d", "2lout", "4lov", "2lp", "lpa5b", "l3pha", "l5phi", "lp5ing", - "l3pit", "l4pl", "l5pr", "4l1r", "2l1s2", "l4sc", "l2se", "l4sie", "4lt", "lt5ag", "ltane5", "l1te", "lten4", "ltera4", - "lth3i", "l5ties.", "ltis4", "l1tr", "ltu2", "ltur3a", "lu5a", "lu3br", "luch4", "lu3ci", "lu3en", "luf4", "lu5id", - "lu4ma", "5lumi", "l5umn.", "5lumnia", "lu3o", "luo3r", "4lup", "luss4", "lus3te", "1lut", "l5ven", "l5vet4", "2l1w", - "1ly", "4lya", "4lyb", "ly5me", "ly3no", "2lys4", "l5yse", "1ma", "2mab", "ma2ca", "ma5chine", "ma4cl", "mag5in", "5magn", - "2mah", "maid5", "4mald", "ma3lig", "ma5lin", "mal4li", "mal4ty", "5mania", "man5is", "man3iz", "4map", "ma5rine.", - "ma5riz", "mar4ly", "mar3v", "ma5sce", "mas4e", "mas1t", "5mate", "math3", "ma3tis", "4matiza", "4m1b", "mba4t5", - "m5bil", "m4b3ing", "mbi4v", "4m5c", "4me.", "2med", "4med.", "5media", "me3die", "m5e5dy", "me2g", "mel5on", "mel4t", - "me2m", "mem1o3", "1men", "men4a", "men5ac", "men4de", "4mene", "men4i", "mens4", "mensu5", "3ment", "men4te", "me5on", - "m5ersa", "2mes", "3mesti", "me4ta", "met3al", "me1te", "me5thi", "m4etr", "5metric", "me5trie", "me3try", "me4v", - "4m1f", "2mh", "5mi.", "mi3a", "mid4a", "mid4g", "mig4", "3milia", "m5i5lie", "m4ill", "min4a", "3mind", "m5inee", - "m4ingl", "min5gli", "m5ingly", "min4t", "m4inu", "miot4", "m2is", "mis4er.", "mis5l", "mis4ti", "m5istry", "4mith", - "m2iz", "4mk", "4m1l", "m1m", "mma5ry", "4m1n", "mn4a", "m4nin", "mn4o", "1mo", "4mocr", "5mocratiz", "mo2d1", "mo4go", - "mois2", "moi5se", "4mok", "mo5lest", "mo3me", "mon5et", "mon5ge", "moni3a", "mon4ism", "mon4ist", "mo3niz", - "monol4", "mo3ny.", "mo2r", "4mora.", "mos2", "mo5sey", "mo3sp", "moth3", "m5ouf", "3mous", "mo2v", "4m1p", "mpara5", - "mpa5rab", "mpar5i", "m3pet", "mphas4", "m2pi", "mpi4a", "mp5ies", "m4p1in", "m5pir", "mp5is", "mpo3ri", "mpos5ite", - "m4pous", "mpov5", "mp4tr", "m2py", "4m3r", "4m1s2", "m4sh", "m5si", "4mt", "1mu", "mula5r4", "5mult", "multi3", "3mum", - "mun2", "4mup", "mu4u", "4mw", "1na", "2n1a2b", "n4abu", "4nac.", "na4ca", "n5act", "nag5er.", "nak4", "na4li", "na5lia", - "4nalt", "na5mit", "n2an", "nanci4", "nan4it", "nank4", "nar3c", "4nare", "nar3i", "nar4l", "n5arm", "n4as", "nas4c", - "nas5ti", "n2at", "na3tal", "nato5miz", "n2au", "nau3se", "3naut", "nav4e", "4n1b4", "ncar5", "n4ces.", "n3cha", - "n5cheo", "n5chil", "n3chis", "nc1in", "nc4it", "ncour5a", "n1cr", "n1cu", "n4dai", "n5dan", "n1de", "nd5est.", - "ndi4b", "n5d2if", "n1dit", "n3diz", "n5duc", "ndu4r", "nd2we", "2ne.", "n3ear", "ne2b", "neb3u", "ne2c", "5neck", "2ned", - "ne4gat", "neg5ativ", "5nege", "ne4la", "nel5iz", "ne5mi", "ne4mo", "1nen", "4nene", "3neo", "ne4po", "ne2q", "n1er", - "nera5b", "n4erar", "n2ere", "n4er5i", "ner4r", "1nes", "2nes.", "4nesp", "2nest", "4nesw", "3netic", "ne4v", "n5eve", - "ne4w", "n3f", "n4gab", "n3gel", "nge4n4e", "n5gere", "n3geri", "ng5ha", "n3gib", "ng1in", "n5git", "n4gla", "ngov4", - "ng5sh", "n1gu", "n4gum", "n2gy", "4n1h4", "nha4", "nhab3", "nhe4", "3n4ia", "ni3an", "ni4ap", "ni3ba", "ni4bl", "ni4d", - "ni5di", "ni4er", "ni2fi", "ni5ficat", "n5igr", "nik4", "n1im", "ni3miz", "n1in", "5nine.", "nin4g", "ni4o", "5nis.", - "nis4ta", "n2it", "n4ith", "3nitio", "n3itor", "ni3tr", "n1j", "4nk2", "n5kero", "n3ket", "nk3in", "n1kl", "4n1l", "n5m", - "nme4", "nmet4", "4n1n2", "nne4", "nni3al", "nni4v", "nob4l", "no3ble", "n5ocl", "4n3o2d", "3noe", "4nog", "noge4", - "nois5i", "no5l4i", "5nologis", "3nomic", "n5o5miz", "no4mo", "no3my", "no4n", "non4ag", "non5i", "n5oniz", "4nop", - "5nop5o5li", "nor5ab", "no4rary", "4nosc", "nos4e", "nos5t", "no5ta", "1nou", "3noun", "nov3el3", "nowl3", "n1p4", - "npi4", "npre4c", "n1q", "n1r", "nru4", "2n1s2", "ns5ab", "nsati4", "ns4c", "n2se", "n4s3es", "nsid1", "nsig4", "n2sl", - "ns3m", "n4soc", "ns4pe", "n5spi", "nsta5bl", "n1t", "nta4b", "nter3s", "nt2i", "n5tib", "nti4er", "nti2f", "n3tine", - "n4t3ing", "nti4p", "ntrol5li", "nt4s", "ntu3me", "nu1a", "nu4d", "nu5en", "nuf4fe", "n3uin", "3nu3it", "n4um", - "nu1me", "n5umi", "3nu4n", "n3uo", "nu3tr", "n1v2", "n1w4", "nym4", "nyp4", "4nz", "n3za", "4oa", "oad3", "o5a5les", "oard3", - "oas4e", "oast5e", "oat5i", "ob3a3b", "o5bar", "obe4l", "o1bi", "o2bin", "ob5ing", "o3br", "ob3ul", "o1ce", "och4", - "o3chet", "ocif3", "o4cil", "o4clam", "o4cod", "oc3rac", "oc5ratiz", "ocre3", "5ocrit", "octor5a", "oc3ula", - "o5cure", "od5ded", "od3ic", "odi3o", "o2do4", "odor3", "od5uct.", "od5ucts", "o4el", "o5eng", "o3er", "oe4ta", "o3ev", - "o2fi", "of5ite", "ofit4t", "o2g5a5r", "og5ativ", "o4gato", "o1ge", "o5gene", "o5geo", "o4ger", "o3gie", "1o1gis", - "og3it", "o4gl", "o5g2ly", "3ogniz", "o4gro", "ogu5i", "1ogy", "2ogyn", "o1h2", "ohab5", "oi2", "oic3es", "oi3der", - "oiff4", "oig4", "oi5let", "o3ing", "oint5er", "o5ism", "oi5son", "oist5en", "oi3ter", "o5j", "2ok", "o3ken", "ok5ie", - "o1la", "o4lan", "olass4", "ol2d", "old1e", "ol3er", "o3lesc", "o3let", "ol4fi", "ol2i", "o3lia", "o3lice", "ol5id.", - "o3li4f", "o5lil", "ol3ing", "o5lio", "o5lis.", "ol3ish", "o5lite", "o5litio", "o5liv", "olli4e", "ol5ogiz", - "olo4r", "ol5pl", "ol2t", "ol3ub", "ol3ume", "ol3un", "o5lus", "ol2v", "o2ly", "om5ah", "oma5l", "om5atiz", "om2be", - "om4bl", "o2me", "om3ena", "om5erse", "o4met", "om5etry", "o3mia", "om3ic.", "om3ica", "o5mid", "om1in", "o5mini", - "5ommend", "omo4ge", "o4mon", "om3pi", "ompro5", "o2n", "on1a", "on4ac", "o3nan", "on1c", "3oncil", "2ond", "on5do", - "o3nen", "on5est", "on4gu", "on1ic", "o3nio", "on1is", "o5niu", "on3key", "on4odi", "on3omy", "on3s", "onspi4", - "onspir5a", "onsu4", "onten4", "on3t4i", "ontif5", "on5um", "onva5", "oo2", "ood5e", "ood5i", "oo4k", "oop3i", "o3ord", - "oost5", "o2pa", "ope5d", "op1er", "3opera", "4operag", "2oph", "o5phan", "o5pher", "op3ing", "o3pit", "o5pon", - "o4posi", "o1pr", "op1u", "opy5", "o1q", "o1ra", "o5ra.", "o4r3ag", "or5aliz", "or5ange", "ore5a", "o5real", "or3ei", - "ore5sh", "or5est.", "orew4", "or4gu", "4o5ria", "or3ica", "o5ril", "or1in", "o1rio", "or3ity", "o3riu", "or2mi", - "orn2e", "o5rof", "or3oug", "or5pe", "3orrh", "or4se", "ors5en", "orst4", "or3thi", "or3thy", "or4ty", "o5rum", "o1ry", - "os3al", "os2c", "os4ce", "o3scop", "4oscopi", "o5scr", "os4i4e", "os5itiv", "os3ito", "os3ity", "osi4u", "os4l", - "o2so", "os4pa", "os4po", "os2ta", "o5stati", "os5til", "os5tit", "o4tan", "otele4g", "ot3er.", "ot5ers", "o4tes", - "4oth", "oth5esi", "oth3i4", "ot3ic.", "ot5ica", "o3tice", "o3tif", "o3tis", "oto5s", "ou2", "ou3bl", "ouch5i", - "ou5et", "ou4l", "ounc5er", "oun2d", "ou5v", "ov4en", "over4ne", "over3s", "ov4ert", "o3vis", "oviti4", "o5v4ol", - "ow3der", "ow3el", "ow5est", "ow1i", "own5i", "o4wo", "oy1a", "1pa", "pa4ca", "pa4ce", "pac4t", "p4ad", "5pagan", - "p3agat", "p4ai", "pain4", "p4al", "pan4a", "pan3el", "pan4ty", "pa3ny", "pa1p", "pa4pu", "para5bl", "par5age", - "par5di", "3pare", "par5el", "p4a4ri", "par4is", "pa2te", "pa5ter", "5pathic", "pa5thy", "pa4tric", "pav4", "3pay", - "4p1b", "pd4", "4pe.", "3pe4a", "pear4l", "pe2c", "2p2ed", "3pede", "3pedi", "pedia4", "ped4ic", "p4ee", "pee4d", "pek4", - "pe4la", "peli4e", "pe4nan", "p4enc", "pen4th", "pe5on", "p4era.", "pera5bl", "p4erag", "p4eri", "peri5st", - "per4mal", "perme5", "p4ern", "per3o", "per3ti", "pe5ru", "per1v", "pe2t", "pe5ten", "pe5tiz", "4pf", "4pg", "4ph.", - "phar5i", "phe3no", "ph4er", "ph4es.", "ph1ic", "5phie", "ph5ing", "5phisti", "3phiz", "ph2l", "3phob", "3phone", - "5phoni", "pho4r", "4phs", "ph3t", "5phu", "1phy", "pi3a", "pian4", "pi4cie", "pi4cy", "p4id", "p5ida", "pi3de", "5pidi", - "3piec", "pi3en", "pi4grap", "pi3lo", "pi2n", "p4in.", "pind4", "p4ino", "3pi1o", "pion4", "p3ith", "pi5tha", "pi2tu", - "2p3k2", "1p2l2", "3plan", "plas5t", "pli3a", "pli5er", "4plig", "pli4n", "ploi4", "plu4m", "plum4b", "4p1m", "2p3n", - "po4c", "5pod.", "po5em", "po3et5", "5po4g", "poin2", "5point", "poly5t", "po4ni", "po4p", "1p4or", "po4ry", "1pos", - "pos1s", "p4ot", "po4ta", "5poun", "4p1p", "ppa5ra", "p2pe", "p4ped", "p5pel", "p3pen", "p3per", "p3pet", "ppo5site", - "pr2", "pray4e", "5preci", "pre5co", "pre3em", "pref5ac", "pre4la", "pre3r", "p3rese", "3press", "pre5ten", "pre3v", - "5pri4e", "prin4t3", "pri4s", "pris3o", "p3roca", "prof5it", "pro3l", "pros3e", "pro1t", "2p1s2", "p2se", "ps4h", - "p4sib", "2p1t", "pt5a4b", "p2te", "p2th", "pti3m", "ptu4r", "p4tw", "pub3", "pue4", "puf4", "pul3c", "pu4m", "pu2n", - "pur4r", "5pus", "pu2t", "5pute", "put3er", "pu3tr", "put4ted", "put4tin", "p3w", "qu2", "qua5v", "2que.", "3quer", - "3quet", "2rab", "ra3bi", "rach4e", "r5acl", "raf5fi", "raf4t", "r2ai", "ra4lo", "ram3et", "r2ami", "rane5o", "ran4ge", - "r4ani", "ra5no", "rap3er", "3raphy", "rar5c", "rare4", "rar5ef", "4raril", "r2as", "ration4", "rau4t", "ra5vai", - "rav3el", "ra5zie", "r1b", "r4bab", "r4bag", "rbi2", "rbi4f", "r2bin", "r5bine", "rb5ing.", "rb4o", "r1c", "r2ce", - "rcen4", "r3cha", "rch4er", "r4ci4b", "rc4it", "rcum3", "r4dal", "rd2i", "rdi4a", "rdi4er", "rdin4", "rd3ing", "2re.", - "re1al", "re3an", "re5arr", "5reav", "re4aw", "r5ebrat", "rec5oll", "rec5ompe", "re4cre", "2r2ed", "re1de", - "re3dis", "red5it", "re4fac", "re2fe", "re5fer.", "re3fi", "re4fy", "reg3is", "re5it", "re1li", "re5lu", "r4en4ta", - "ren4te", "re1o", "re5pin", "re4posi", "re1pu", "r1er4", "r4eri", "rero4", "re5ru", "r4es.", "re4spi", "ress5ib", - "res2t", "re5stal", "re3str", "re4ter", "re4ti4z", "re3tri", "reu2", "re5uti", "rev2", "re4val", "rev3el", - "r5ev5er.", "re5vers", "re5vert", "re5vil", "rev5olu", "re4wh", "r1f", "rfu4", "r4fy", "rg2", "rg3er", "r3get", - "r3gic", "rgi4n", "rg3ing", "r5gis", "r5git", "r1gl", "rgo4n", "r3gu", "rh4", "4rh.", "4rhal", "ri3a", "ria4b", "ri4ag", - "r4ib", "rib3a", "ric5as", "r4ice", "4rici", "5ricid", "ri4cie", "r4ico", "rid5er", "ri3enc", "ri3ent", "ri1er", - "ri5et", "rig5an", "5rigi", "ril3iz", "5riman", "rim5i", "3rimo", "rim4pe", "r2ina", "5rina.", "rin4d", "rin4e", - "rin4g", "ri1o", "5riph", "riph5e", "ri2pl", "rip5lic", "r4iq", "r2is", "r4is.", "ris4c", "r3ish", "ris4p", "ri3ta3b", - "r5ited.", "rit5er.", "rit5ers", "rit3ic", "ri2tu", "rit5ur", "riv5el", "riv3et", "riv3i", "r3j", "r3ket", "rk4le", - "rk4lin", "r1l", "rle4", "r2led", "r4lig", "r4lis", "rl5ish", "r3lo4", "r1m", "rma5c", "r2me", "r3men", "rm5ers", - "rm3ing", "r4ming.", "r4mio", "r3mit", "r4my", "r4nar", "r3nel", "r4ner", "r5net", "r3ney", "r5nic", "r1nis4", "r3nit", - "r3niv", "rno4", "r4nou", "r3nu", "rob3l", "r2oc", "ro3cr", "ro4e", "ro1fe", "ro5fil", "rok2", "ro5ker", "5role.", - "rom5ete", "rom4i", "rom4p", "ron4al", "ron4e", "ro5n4is", "ron4ta", "1room", "5root", "ro3pel", "rop3ic", "ror3i", - "ro5ro", "ros5per", "ros4s", "ro4the", "ro4ty", "ro4va", "rov5el", "rox5", "r1p", "r4pea", "r5pent", "rp5er.", "r3pet", - "rp4h4", "rp3ing", "r3po", "r1r4", "rre4c", "rre4f", "r4reo", "rre4st", "rri4o", "rri4v", "rron4", "rros4", "rrys4", - "4rs2", "r1sa", "rsa5ti", "rs4c", "r2se", "r3sec", "rse4cr", "rs5er.", "rs3es", "rse5v2", "r1sh", "r5sha", "r1si", - "r4si4b", "rson3", "r1sp", "r5sw", "rtach4", "r4tag", "r3teb", "rten4d", "rte5o", "r1ti", "rt5ib", "rti4d", "r4tier", - "r3tig", "rtil3i", "rtil4l", "r4tily", "r4tist", "r4tiv", "r3tri", "rtroph4", "rt4sh", "ru3a", "ru3e4l", "ru3en", - "ru4gl", "ru3in", "rum3pl", "ru2n", "runk5", "run4ty", "r5usc", "ruti5n", "rv4e", "rvel4i", "r3ven", "rv5er.", - "r5vest", "r3vey", "r3vic", "rvi4v", "r3vo", "r1w", "ry4c", "5rynge", "ry3t", "sa2", "2s1ab", "5sack", "sac3ri", "s3act", - "5sai", "salar4", "sal4m", "sa5lo", "sal4t", "3sanc", "san4de", "s1ap", "sa5ta", "5sa3tio", "sat3u", "sau4", "sa5vor", - "5saw", "4s5b", "scan4t5", "sca4p", "scav5", "s4ced", "4scei", "s4ces", "sch2", "s4cho", "3s4cie", "5scin4d", "scle5", - "s4cli", "scof4", "4scopy", "scour5a", "s1cu", "4s5d", "4se.", "se4a", "seas4", "sea5w", "se2c3o", "3sect", "4s4ed", - "se4d4e", "s5edl", "se2g", "seg3r", "5sei", "se1le", "5self", "5selv", "4seme", "se4mol", "sen5at", "4senc", "sen4d", - "s5ened", "sen5g", "s5enin", "4sentd", "4sentl", "sep3a3", "4s1er.", "s4erl", "ser4o", "4servo", "s1e4s", "se5sh", - "ses5t", "5se5um", "5sev", "sev3en", "sew4i", "5sex", "4s3f", "2s3g", "s2h", "2sh.", "sh1er", "5shev", "sh1in", "sh3io", - "3ship", "shiv5", "sho4", "sh5old", "shon3", "shor4", "short5", "4shw", "si1b", "s5icc", "3side.", "5sides", "5sidi", - "si5diz", "4signa", "sil4e", "4sily", "2s1in", "s2ina", "5sine.", "s3ing", "1sio", "5sion", "sion5a", "si2r", "sir5a", - "1sis", "3sitio", "5siu", "1siv", "5siz", "sk2", "4ske", "s3ket", "sk5ine", "sk5ing", "s1l2", "s3lat", "s2le", "slith5", - "2s1m", "s3ma", "small3", "sman3", "smel4", "s5men", "5smith", "smol5d4", "s1n4", "1so", "so4ce", "soft3", "so4lab", - "sol3d2", "so3lic", "5solv", "3som", "3s4on.", "sona4", "son4g", "s4op", "5sophic", "s5ophiz", "s5ophy", "sor5c", - "sor5d", "4sov", "so5vi", "2spa", "5spai", "spa4n", "spen4d", "2s5peo", "2sper", "s2phe", "3spher", "spho5", "spil4", - "sp5ing", "4spio", "s4ply", "s4pon", "spor4", "4spot", "squal4l", "s1r", "2ss", "s1sa", "ssas3", "s2s5c", "s3sel", - "s5seng", "s4ses.", "s5set", "s1si", "s4sie", "ssi4er", "ss5ily", "s4sl", "ss4li", "s4sn", "sspend4", "ss2t", "ssur5a", - "ss5w", "2st.", "s2tag", "s2tal", "stam4i", "5stand", "s4ta4p", "5stat.", "s4ted", "stern5i", "s5tero", "ste2w", - "stew5a", "s3the", "st2i", "s4ti.", "s5tia", "s1tic", "5stick", "s4tie", "s3tif", "st3ing", "5stir", "s1tle", "5stock", - "stom3a", "5stone", "s4top", "3store", "st4r", "s4trad", "5stratu", "s4tray", "s4trid", "4stry", "4st3w", "s2ty", - "1su", "su1al", "su4b3", "su2g3", "su5is", "suit3", "s4ul", "su2m", "sum3i", "su2n", "su2r", "4sv", "sw2", "4swo", "s4y", - "4syc", "3syl", "syn5o", "sy5rin", "1ta", "3ta.", "2tab", "ta5bles", "5taboliz", "4taci", "ta5do", "4taf4", "tai5lo", - "ta2l", "ta5la", "tal5en", "tal3i", "4talk", "tal4lis", "ta5log", "ta5mo", "tan4de", "tanta3", "ta5per", "ta5pl", - "tar4a", "4tarc", "4tare", "ta3riz", "tas4e", "ta5sy", "4tatic", "ta4tur", "taun4", "tav4", "2taw", "tax4is", "2t1b", - "4tc", "t4ch", "tch5et", "4t1d", "4te.", "tead4i", "4teat", "tece4", "5tect", "2t1ed", "te5di", "1tee", "teg4", "te5ger", - "te5gi", "3tel.", "teli4", "5tels", "te2ma2", "tem3at", "3tenan", "3tenc", "3tend", "4tenes", "1tent", "ten4tag", - "1teo", "te4p", "te5pe", "ter3c", "5ter3d", "1teri", "ter5ies", "ter3is", "teri5za", "5ternit", "ter5v", "4tes.", - "4tess", "t3ess.", "teth5e", "3teu", "3tex", "4tey", "2t1f", "4t1g", "2th.", "than4", "th2e", "4thea", "th3eas", "the5at", - "the3is", "3thet", "th5ic.", "th5ica", "4thil", "5think", "4thl", "th5ode", "5thodic", "4thoo", "thor5it", - "tho5riz", "2ths", "1tia", "ti4ab", "ti4ato", "2ti2b", "4tick", "t4ico", "t4ic1u", "5tidi", "3tien", "tif2", "ti5fy", - "2tig", "5tigu", "till5in", "1tim", "4timp", "tim5ul", "2t1in", "t2ina", "3tine.", "3tini", "1tio", "ti5oc", "tion5ee", - "5tiq", "ti3sa", "3tise", "tis4m", "ti5so", "tis4p", "5tistica", "ti3tl", "ti4u", "1tiv", "tiv4a", "1tiz", "ti3za", - "ti3zen", "2tl", "t5la", "tlan4", "3tle.", "3tled", "3tles.", "t5let.", "t5lo", "4t1m", "tme4", "2t1n2", "1to", "to3b", - "to5crat", "4todo", "2tof", "to2gr", "to5ic", "to2ma", "tom4b", "to3my", "ton4ali", "to3nat", "4tono", "4tony", - "to2ra", "to3rie", "tor5iz", "tos2", "5tour", "4tout", "to3war", "4t1p", "1tra", "tra3b", "tra5ch", "traci4", - "trac4it", "trac4te", "tras4", "tra5ven", "trav5es5", "tre5f", "tre4m", "trem5i", "5tria", "tri5ces", "5tricia", - "4trics", "2trim", "tri4v", "tro5mi", "tron5i", "4trony", "tro5phe", "tro3sp", "tro3v", "tru5i", "trus4", "4t1s2", - "t4sc", "tsh4", "t4sw", "4t3t2", "t4tes", "t5to", "ttu4", "1tu", "tu1a", "tu3ar", "tu4bi", "tud2", "4tue", "4tuf4", "5tu3i", - "3tum", "tu4nis", "2t3up.", "3ture", "5turi", "tur3is", "tur5o", "tu5ry", "3tus", "4tv", "tw4", "4t1wa", "twis4", "4two", - "1ty", "4tya", "2tyl", "type3", "ty5ph", "4tz", "tz4e", "4uab", "uac4", "ua5na", "uan4i", "uar5ant", "uar2d", "uar3i", - "uar3t", "u1at", "uav4", "ub4e", "u4bel", "u3ber", "u4bero", "u1b4i", "u4b5ing", "u3ble.", "u3ca", "uci4b", "uc4it", - "ucle3", "u3cr", "u3cu", "u4cy", "ud5d", "ud3er", "ud5est", "udev4", "u1dic", "ud3ied", "ud3ies", "ud5is", "u5dit", - "u4don", "ud4si", "u4du", "u4ene", "uens4", "uen4te", "uer4il", "3ufa", "u3fl", "ugh3en", "ug5in", "2ui2", "uil5iz", - "ui4n", "u1ing", "uir4m", "uita4", "uiv3", "uiv4er.", "u5j", "4uk", "u1la", "ula5b", "u5lati", "ulch4", "5ulche", - "ul3der", "ul4e", "u1len", "ul4gi", "ul2i", "u5lia", "ul3ing", "ul5ish", "ul4lar", "ul4li4b", "ul4lis", "4ul3m", - "u1l4o", "4uls", "uls5es", "ul1ti", "ultra3", "4ultu", "u3lu", "ul5ul", "ul5v", "um5ab", "um4bi", "um4bly", "u1mi", - "u4m3ing", "umor5o", "um2p", "unat4", "u2ne", "un4er", "u1ni", "un4im", "u2nin", "un5ish", "uni3v", "un3s4", "un4sw", - "unt3ab", "un4ter.", "un4tes", "unu4", "un5y", "un5z", "u4ors", "u5os", "u1ou", "u1pe", "uper5s", "u5pia", "up3ing", - "u3pl", "up3p", "upport5", "upt5ib", "uptu4", "u1ra", "4ura.", "u4rag", "u4ras", "ur4be", "urc4", "ur1d", "ure5at", - "ur4fer", "ur4fr", "u3rif", "uri4fic", "ur1in", "u3rio", "u1rit", "ur3iz", "ur2l", "url5ing.", "ur4no", "uros4", - "ur4pe", "ur4pi", "urs5er", "ur5tes", "ur3the", "urti4", "ur4tie", "u3ru", "2us", "u5sad", "u5san", "us4ap", "usc2", - "us3ci", "use5a", "u5sia", "u3sic", "us4lin", "us1p", "us5sl", "us5tere", "us1tr", "u2su", "usur4", "uta4b", "u3tat", - "4ute.", "4utel", "4uten", "uten4i", "4u1t2i", "uti5liz", "u3tine", "ut3ing", "ution5a", "u4tis", "5u5tiz", "u4t1l", - "ut5of", "uto5g", "uto5matic", "u5ton", "u4tou", "uts4", "u3u", "uu4m", "u1v2", "uxu3", "uz4e", "1va", "5va.", "2v1a4b", - "vac5il", "vac3u", "vag4", "va4ge", "va5lie", "val5o", "val1u", "va5mo", "va5niz", "va5pi", "var5ied", "3vat", "4ve.", - "4ved", "veg3", "v3el.", "vel3li", "ve4lo", "v4ely", "ven3om", "v5enue", "v4erd", "5vere.", "v4erel", "v3eren", - "ver5enc", "v4eres", "ver3ie", "vermi4n", "3verse", "ver3th", "v4e2s", "4ves.", "ves4te", "ve4te", "vet3er", - "ve4ty", "vi5ali", "5vian", "5vide.", "5vided", "4v3iden", "5vides", "5vidi", "v3if", "vi5gn", "vik4", "2vil", - "5vilit", "v3i3liz", "v1in", "4vi4na", "v2inc", "vin5d", "4ving", "vio3l", "v3io4r", "vi1ou", "vi4p", "vi5ro", - "vis3it", "vi3so", "vi3su", "4viti", "vit3r", "4vity", "3viv", "5vo.", "voi4", "3vok", "vo4la", "v5ole", "5volt", "3volv", - "vom5i", "vor5ab", "vori4", "vo4ry", "vo4ta", "4votee", "4vv4", "v4y", "w5abl", "2wac", "wa5ger", "wag5o", "wait5", - "w5al.", "wam4", "war4t", "was4t", "wa1te", "wa5ver", "w1b", "wea5rie", "weath3", "wed4n", "weet3", "wee5v", "wel4l", - "w1er", "west3", "w3ev", "whi4", "wi2", "wil2", "will5in", "win4de", "win4g", "wir4", "3wise", "with3", "wiz5", "w4k", - "wl4es", "wl3in", "w4no", "1wo2", "wom1", "wo5ven", "w5p", "wra4", "wri4", "writa4", "w3sh", "ws4l", "ws4pe", "w5s4t", "4wt", - "wy4", "x1a", "xac5e", "x4ago", "xam3", "x4ap", "xas5", "x3c2", "x1e", "xe4cuto", "x2ed", "xer4i", "xe5ro", "x1h", "xhi2", - "xhil5", "xhu4", "x3i", "xi5a", "xi5c", "xi5di", "x4ime", "xi5miz", "x3o", "x4ob", "x3p", "xpan4d", "xpecto5", "xpe3d", - "x1t2", "x3ti", "x1u", "xu3a", "xx4", "y5ac", "3yar4", "y5at", "y1b", "y1c", "y2ce", "yc5er", "y3ch", "ych4e", "ycom4", "ycot4", - "y1d", "y5ee", "y1er", "y4erf", "yes4", "ye4t", "y5gi", "4y3h", "y1i", "y3la", "ylla5bl", "y3lo", "y5lu", "ymbol5", "yme4", - "ympa3", "yn3chr", "yn5d", "yn5g", "yn5ic", "5ynx", "y1o4", "yo5d", "y4o5g", "yom4", "yo5net", "y4ons", "y4os", "y4ped", - "yper5", "yp3i", "y3po", "y4poc", "yp2ta", "y5pu", "yra5m", "yr5ia", "y3ro", "yr4r", "ys4c", "y3s2e", "ys3ica", "ys3io", - "3ysis", "y4so", "yss4", "ys1t", "ys3ta", "ysur4", "y3thin", "yt3ic", "y1w", "za1", "z5a2b", "zar2", "4zb", "2ze", "ze4n", - "ze4p", "z1er", "ze3ro", "zet4", "2z1i", "z4il", "z4is", "5zl", "4zm", "1zo", "zo4m", "zo5ol", "zte4", "4z1z2", "z4zy" - ] ++ --- Extra patterns, from ushyphmax.tex, dated 2005-05-30. --- Copyright (C) 1990, 2004, 2005 Gerard D.C. Kuiken. --- Copying and distribution of this file, with or without modification, --- are permitted in any medium without royalty provided the copyright --- notice and this notice are preserved. --- --- These patterns are based on the Hyphenation Exception Log --- published in TUGboat, Volume 10 (1989), No. 3, pp. 337-341, --- and a large number of incorrectly hyphenated words not yet published. - [ - ".con5gr", ".de5riva", ".dri5v4", ".eth1y6l1", ".eu4ler", ".ev2", ".ever5si5b", ".ga4s1om1", ".ge4ome", - ".ge5ot1", ".he3mo1", ".he3p6a", ".he3roe", ".in5u2t", ".kil2n3i", ".ko6r1te1", ".le6ices", ".me4ga1l", - ".met4ala", ".mim5i2c1", ".mi1s4ers", ".ne6o3f", ".noe1th", ".non1e2m", ".poly1s", ".post1am", ".pre1am", - ".rav5en1o", ".semi5", ".sem4ic", ".semid6", ".semip4", ".semir4", ".sem6is4", ".semiv4", ".sph6in1", - ".spin1o", ".ta5pes1tr", ".te3legr", ".to6pog", ".to2q", ".un3at5t", ".un5err5", ".vi2c3ar", ".we2b1l", - ".re1e4c", "a5bolic", "a2cabl", "af6fish", "am1en3ta5b", "anal6ys", "ano5a2c", "ans5gr", "ans3v", "anti1d", - "an3ti1n2", "anti1re", "a4pe5able", "ar3che5t", "ar2range", "as5ymptot", "ath3er1o1s", "at6tes.", - "augh4tl", "au5li5f", "av3iou", "back2er.", "ba6r1onie", "ba1thy", "bbi4t", "be2vie", "bi5d2if", "bil2lab", - "bio5m", "bi1orb", "bio1rh", "b1i3tive", "blan2d1", "blin2d1", "blon2d2", "bor1no5", "bo2t1u1l", "brus4q", - "bus6i2er", "bus6i2es", "buss4ing", "but2ed.", "but4ted", "cad5e1m", "cat1a1s2", "4chs.", "chs3hu", "chie5vo", - "cig3a3r", "cin2q", "cle4ar", "co6ph1o3n", "cous2ti", "cri3tie", "croc1o1d", "cro5e2co", "c2tro3me6c", - "1cu2r1ance", "2d3alone", "data1b", "dd5a5b", "d2d5ib", "de4als.", "de5clar1", "de2c5lina", "de3fin3iti", - "de2mos", "des3ic", "de2tic", "dic1aid", "dif5fra", "3di1methy", "di2ren", "di2rer", "2d1lead", "2d1li2e", - "3do5word", "dren1a5l", "drif2t1a", "d1ri3pleg5", "drom3e5d", "d3tab", "du2al.", "du1op1o1l", "ea4n3ies", - "e3chas", "edg1l", "ed1uling", "eli2t1is", "e1loa", "en1dix", "eo3grap", "1e6p3i3neph1", "e2r3i4an.", - "e3spac6i", "eth1y6l1ene", "5eu2clid1", "feb1rua", "fermi1o", "3fich", "fit5ted.", "fla1g6el", "flow2er.", - "3fluor", "gen2cy.", "ge3o1d", "ght1we", "g1lead", "get2ic.", "4g1lish", "5glo5bin", "1g2nac", "gnet1ism", - "gno5mo", "g2n1or.", "g2noresp", "2g1o4n3i1za", "graph5er.", "griev1", "g1utan", "hair1s", "ha2p3ar5r", - "hatch1", "hex2a3", "hite3sid", "h3i5pel1a4", "hnau3z", "ho6r1ic.", "h2t1eou", "hypo1tha", "id4ios", - "ifac1et", "ign4it", "ignit1er", "i4jk", "im3ped3a", "infra1s2", "i5nitely.", "irre6v3oc", "i1tesima", - "ith5i2l", "itin5er5ar", "janu3a", "japan1e2s", "je1re1m", "1ke6ling", "1ki5netic", "1kovian", "k3sha", - "la4c3i5e", "lai6n3ess", "lar5ce1n", "l3chai", "l3chil6d1", "lead6er.", "lea4s1a", "1lec3ta6b", - "le3g6en2dre", "1le1noid", "lith1o5g", "ll1fl", "l2l3ish", "l5mo3nell", "lo1bot1o1", "lo2ges.", "load4ed.", - "load6er.", "l3tea", "lth5i2ly", "lue1p", "1lunk3er", "1lum5bia.", "3lyg1a1mi", "ly5styr", "ma1la1p", "m2an.", - "man3u1sc", "mar1gin1", "medi2c", "med3i3cin", "medio6c1", "me3gran3", "m2en.", "3mi3da5b", "3milita", - "mil2l1ag", "mil5li5li", "mi6n3is.", "mi1n2ut1er", "mi1n2ut1est", "m3ma1b", "5maph1ro1", "5moc1ra1t", - "mo5e2las", "mol1e5c", "mon4ey1l", "mono3ch", "mo4no1en", "moro6n5is", "mono1s6", "moth4et2", "m1ou3sin", - "m5shack2", "mu2dro", "mul2ti5u", "n3ar4chs.", "n3ch2es1t", "ne3back", "2ne1ski", "n1dieck", "nd3thr", - "nfi6n3ites", "4n5i4an.", "nge5nes", "ng1ho", "ng1spr", "nk3rup", "n5less", "5noc3er1os", "nom1a6l", - "nom5e1no", "n1o1mist", "non1eq", "non1i4so", "5nop1oly.", "no1vemb", "ns5ceiv", "ns4moo", "ntre1p", - "obli2g1", "o3chas", "odel3li", "odit1ic", "oerst2", "oke1st", "o3les3ter", "oli3gop1o1", "o1lo3n4om", - "o3mecha6", "onom1ic", "o3norma", "o3no2t1o3n", "o3nou", "op1ism.", "or4tho3ni4t", "orth1ri", "or5tively", - "o4s3pher", "o5test1er", "o5tes3tor", "oth3e1o1s", "ou3ba3do", "o6v3i4an.", "oxi6d1ic", "pal6mat", - "parag6ra4", "par4a1le", "param4", "para3me", "pee2v1", "phi2l3ant", "phi5lat1e3l", "pi2c1a3d", "pli2c1ab", - "pli5nar", "poin3ca", "1pole.", "poly1e", "po3lyph1ono", "1prema3c", "pre1neu", "pres2pli", "pro2cess", - "proc3i3ty.", "pro2g1e", "3pseu2d", "pseu3d6o3d2", "pseu3d6o3f2", "pto3mat4", "p5trol3", "pu5bes5c", - "quain2t1e", "qu6a3si3", "quasir6", "quasis6", "quin5tes5s", "qui3v4ar", "r1abolic", "3rab1o1loi", - "ra3chu", "r3a3dig", "radi1o6g", "r2amen", "3ra4m5e1triz", "ra3mou", "ra5n2has", "ra1or", "r3bin1ge", - "re2c3i1pr", "rec5t6ang", "re4t1ribu", "r3ial.", "riv1o1l", "6rk.", "rk1ho", "r1krau", "6rks.", "r5le5qu", - "ro1bot1", "ro5e2las", "ro5epide1", "ro3mesh", "ro1tron", "r3pau5li", "rse1rad1i", "r1thou", "r1treu", - "r1veil", "rz1sc", "sales3c", "sales5w", "5sa3par5il", "sca6p1er", "sca2t1ol", "s4chitz", "schro1ding1", - "1sci2utt", "scrap4er.", "scy4th1", "sem1a1ph", "se3mes1t", "se1mi6t5ic", "sep3temb", "shoe1st", "sid2ed.", - "side5st", "side5sw", "si5resid", "sky1sc", "3slova1kia", "3s2og1a1my", "so2lute", "3s2pace", "1s2pacin", - "spe3cio", "spher1o", "spi2c1il", "spokes5w", "sports3c", "sports3w", "s3qui3to", "s2s1a3chu1", "ss3hat", - "s2s3i4an.", "s5sign5a3b", "1s2tamp", "s2t1ant5shi", "star3tli", "sta1ti", "st5b", "1stor1ab", "strat1a1g", - "strib5ut", "st5scr", "stu1pi4d1", "styl1is", "su2per1e6", "1sync", "1syth3i2", "swimm6", "5tab1o1lism", - "ta3gon.", "talk1a5", "t1a1min", "t6ap6ath", "5tar2rh", "tch1c", "tch3i1er", "t1cr", "teach4er.", "tele2g", - "tele1r6o", "3ter1gei", "ter2ic.", "t3ess2es", "tha4l1am", "tho3don", "th1o5gen1i", "tho1k2er", "thy4l1an", - "thy3sc", "2t3i4an.", "ti2n3o1m", "t1li2er", "tolo2gy", "tot3ic", "trai3tor1", "tra1vers", "travers3a3b", - "treach1e", "tr4ial.", "3tro1le1um", "trof4ic.", "tro3fit", "tro1p2is", "3trop1o5les", "3trop1o5lis", - "t1ro1pol3it", "tsch3ie", "ttrib1ut1", "turn3ar", "t1wh", "ty2p5al", "ua3drati", "uad1ratu", "u5do3ny", - "uea1m", "u2r1al.", "uri4al.", "us2er.", "v1ativ", "v1oir5du1", "va6guer", "vaude3v", "1verely.", "v1er1eig", - "ves1tite", "vi1vip3a3r", "voice1p", "waste3w6a2", "wave1g4", "w3c", "week1n", "wide5sp", "wo4k1en", - "wrap3aro", "writ6er.", "x1q", "xquis3", "y5che3d", "ym5e5try", "y1stro", "yes5ter1y", "z3ian.", "z3o1phr", - "z2z3w" - ] +addedExceptions :: HyphenationDatabase -> T.MapString [Int] +addedExceptions (English (Just e)) = e +addedExceptions _ = T.EmptyTrie + +patterns :: HyphenationDatabase -> T.MapString [Int] +patterns (English _) = E.patterns +patterns (CustomLanguage _ p) = p hunk ./Graphics/PDF/Hyphenate.hs 41 -getWordPoints :: String -> [Int] -getWordPoints s = - case T.lookup (map toLower s) exceptions of +-- | Get the hyphen positions for a word +getWordPoints :: HyphenationDatabase -> String -> [Int] +getWordPoints db s = + case (T.lookup (map toLower s) (exceptions db)) ++ (T.lookup (map toLower s) (addedExceptions db)) of hunk ./Graphics/PDF/Hyphenate.hs 46 - getFromPattern s' + getFromPattern db s' hunk ./Graphics/PDF/Hyphenate.hs 49 - -getFromPattern :: String -> [Int] -getFromPattern s = +-- | Get the hyphen positions from the patterns +getFromPattern :: HyphenationDatabase -> String -> [Int] +getFromPattern db s = hunk ./Graphics/PDF/Hyphenate.hs 53 - lookP c [] = [] + lookP _ [] = [] hunk ./Graphics/PDF/Hyphenate.hs 55 - let r = T.lookup x patterns + let r = T.lookup x (patterns db) hunk ./Graphics/PDF/Hyphenate.hs 60 - completeWithZeros x found = found hunk ./Graphics/PDF/Hyphenate.hs 64 -hyphenate :: String -> [String] -hyphenate s = - let p = drop 1 . lastPointIsNull . getWordPoints $ s +-- | Hyphenate a string +hyphenate :: HyphenationDatabase -- ^ Hyphenation database to use to hyphenate the word + -> String -- ^ Word to hyphenate + -> [String] +hyphenate db s = + let p = drop 1 . lastPointIsNull . getWordPoints db $ s hunk ./Graphics/PDF/Hyphenate.hs 81 -main :: IO () -main = - print exceptions addfile ./Graphics/PDF/Hyphenate/English.hs hunk ./Graphics/PDF/Hyphenate/English.hs 1 +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2006 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- English rules for hyphenation +--------------------------------------------------------- +-- #hide +module Graphics.PDF.Hyphenate.English ( + exceptions + , patterns + ) + where + +import qualified Graphics.PDF.Data.Trie as T +import Graphics.PDF.Hyphenate.LowLevel + +-- | List of exception +exceptions :: T.MapString [Int] +exceptions = mkExceptions exceptionList + +exceptionList :: [String] +exceptionList = [ + "as-so-ciate" + , "as-so-ciates" + , "dec-li-na-tion" + , "oblig-a-tory" + , "phil-an-thropic" + , "present" + , "presents" + , "project" + , "projects" + , "reci-procity" + , "re-cog-ni-zance" + , "ref-or-ma-tion" + , "ret-ri-bu-tion ta-ble" + ] + +-- | List of hyphenation patterns +patterns :: T.MapString [Int] +patterns = mkPatterns patternList + +patternList :: [String] +patternList = + -- Knuth and Liang's original hyphenation patterns from classic TeX. + -- In the public domain. + [ + ".ach4", ".ad4der", ".af1t", ".al3t", ".am5at", ".an5c", ".ang4", ".ani5m", ".ant4", ".an3te", ".anti5s", ".ar5s", + ".ar4tie", ".ar4ty", ".as3c", ".as1p", ".as1s", ".aster5", ".atom5", ".au1d", ".av4i", ".awn4", ".ba4g", ".ba5na", + ".bas4e", ".ber4", ".be5ra", ".be3sm", ".be5sto", ".bri2", ".but4ti", ".cam4pe", ".can5c", ".capa5b", ".car5ol", + ".ca4t", ".ce4la", ".ch4", ".chill5i", ".ci2", ".cit5r", ".co3e", ".co4r", ".cor5ner", ".de4moi", ".de3o", ".de3ra", + ".de3ri", ".des4c", ".dictio5", ".do4t", ".du4c", ".dumb5", ".earth5", ".eas3i", ".eb4", ".eer4", ".eg2", ".el5d", + ".el3em", ".enam3", ".en3g", ".en3s", ".eq5ui5t", ".er4ri", ".es3", ".eu3", ".eye5", ".fes3", ".for5mer", ".ga2", + ".ge2", ".gen3t4", ".ge5og", ".gi5a", ".gi4b", ".go4r", ".hand5i", ".han5k", ".he2", ".hero5i", ".hes3", ".het3", + ".hi3b", ".hi3er", ".hon5ey", ".hon3o", ".hov5", ".id4l", ".idol3", ".im3m", ".im5pin", ".in1", ".in3ci", ".ine2", + ".in2k", ".in3s", ".ir5r", ".is4i", ".ju3r", ".la4cy", ".la4m", ".lat5er", ".lath5", ".le2", ".leg5e", ".len4", + ".lep5", ".lev1", ".li4g", ".lig5a", ".li2n", ".li3o", ".li4t", ".mag5a5", ".mal5o", ".man5a", ".mar5ti", ".me2", + ".mer3c", ".me5ter", ".mis1", ".mist5i", ".mon3e", ".mo3ro", ".mu5ta", ".muta5b", ".ni4c", ".od2", ".odd5", + ".of5te", ".or5ato", ".or3c", ".or1d", ".or3t", ".os3", ".os4tl", ".oth3", ".out3", ".ped5al", ".pe5te", ".pe5tit", + ".pi4e", ".pio5n", ".pi2t", ".pre3m", ".ra4c", ".ran4t", ".ratio5na", ".ree2", ".re5mit", ".res2", ".re5stat", + ".ri4g", ".rit5u", ".ro4q", ".ros5t", ".row5d", ".ru4d", ".sci3e", ".self5", ".sell5", ".se2n", ".se5rie", ".sh2", + ".si2", ".sing4", ".st4", ".sta5bl", ".sy2", ".ta4", ".te4", ".ten5an", ".th2", ".ti2", ".til4", ".tim5o5", ".ting4", + ".tin5k", ".ton4a", ".to4p", ".top5i", ".tou5s", ".trib5ut", ".un1a", ".un3ce", ".under5", ".un1e", ".un5k", + ".un5o", ".un3u", ".up3", ".ure3", ".us5a", ".ven4de", ".ve5ra", ".wil5i", ".ye4", "4ab.", "a5bal", "a5ban", "abe2", + "ab5erd", "abi5a", "ab5it5ab", "ab5lat", "ab5o5liz", "4abr", "ab5rog", "ab3ul", "a4car", "ac5ard", "ac5aro", + "a5ceou", "ac1er", "a5chet", "4a2ci", "a3cie", "ac1in", "a3cio", "ac5rob", "act5if", "ac3ul", "ac4um", "a2d", "ad4din", + "ad5er.", "2adi", "a3dia", "ad3ica", "adi4er", "a3dio", "a3dit", "a5diu", "ad4le", "ad3ow", "ad5ran", "ad4su", "4adu", + "a3duc", "ad5um", "ae4r", "aeri4e", "a2f", "aff4", "a4gab", "aga4n", "ag5ell", "age4o", "4ageu", "ag1i", "4ag4l", "ag1n", + "a2go", "3agog", "ag3oni", "a5guer", "ag5ul", "a4gy", "a3ha", "a3he", "ah4l", "a3ho", "ai2", "a5ia", "a3ic.", "ai5ly", + "a4i4n", "ain5in", "ain5o", "ait5en", "a1j", "ak1en", "al5ab", "al3ad", "a4lar", "4aldi", "2ale", "al3end", "a4lenti", + "a5le5o", "al1i", "al4ia.", "ali4e", "al5lev", "4allic", "4alm", "a5log.", "a4ly.", "4alys", "5a5lyst", "5alyt", + "3alyz", "4ama", "am5ab", "am3ag", "ama5ra", "am5asc", "a4matis", "a4m5ato", "am5era", "am3ic", "am5if", "am5ily", + "am1in", "ami4no", "a2mo", "a5mon", "amor5i", "amp5en", "a2n", "an3age", "3analy", "a3nar", "an3arc", "anar4i", + "a3nati", "4and", "ande4s", "an3dis", "an1dl", "an4dow", "a5nee", "a3nen", "an5est.", "a3neu", "2ang", "ang5ie", + "an1gl", "a4n1ic", "a3nies", "an3i3f", "an4ime", "a5nimi", "a5nine", "an3io", "a3nip", "an3ish", "an3it", "a3niu", + "an4kli", "5anniz", "ano4", "an5ot", "anoth5", "an2sa", "an4sco", "an4sn", "an2sp", "ans3po", "an4st", "an4sur", + "antal4", "an4tie", "4anto", "an2tr", "an4tw", "an3ua", "an3ul", "a5nur", "4ao", "apar4", "ap5at", "ap5ero", "a3pher", + "4aphi", "a4pilla", "ap5illar", "ap3in", "ap3ita", "a3pitu", "a2pl", "apoc5", "ap5ola", "apor5i", "apos3t", + "aps5es", "a3pu", "aque5", "2a2r", "ar3act", "a5rade", "ar5adis", "ar3al", "a5ramete", "aran4g", "ara3p", "ar4at", + "a5ratio", "ar5ativ", "a5rau", "ar5av4", "araw4", "arbal4", "ar4chan", "ar5dine", "ar4dr", "ar5eas", "a3ree", + "ar3ent", "a5ress", "ar4fi", "ar4fl", "ar1i", "ar5ial", "ar3ian", "a3riet", "ar4im", "ar5inat", "ar3io", "ar2iz", + "ar2mi", "ar5o5d", "a5roni", "a3roo", "ar2p", "ar3q", "arre4", "ar4sa", "ar2sh", "4as.", "as4ab", "as3ant", "ashi4", + "a5sia.", "a3sib", "a3sic", "5a5si4t", "ask3i", "as4l", "a4soc", "as5ph", "as4sh", "as3ten", "as1tr", "asur5a", "a2ta", + "at3abl", "at5ac", "at3alo", "at5ap", "ate5c", "at5ech", "at3ego", "at3en.", "at3era", "ater5n", "a5terna", + "at3est", "at5ev", "4ath", "ath5em", "a5then", "at4ho", "ath5om", "4ati.", "a5tia", "at5i5b", "at1ic", "at3if", + "ation5ar", "at3itu", "a4tog", "a2tom", "at5omiz", "a4top", "a4tos", "a1tr", "at5rop", "at4sk", "at4tag", "at5te", + "at4th", "a2tu", "at5ua", "at5ue", "at3ul", "at3ura", "a2ty", "au4b", "augh3", "au3gu", "au4l2", "aun5d", "au3r", + "au5sib", "aut5en", "au1th", "a2va", "av3ag", "a5van", "ave4no", "av3era", "av5ern", "av5ery", "av1i", "avi4er", + "av3ig", "av5oc", "a1vor", "3away", "aw3i", "aw4ly", "aws4", "ax4ic", "ax4id", "ay5al", "aye4", "ays4", "azi4er", "azz5i", + "5ba.", "bad5ger", "ba4ge", "bal1a", "ban5dag", "ban4e", "ban3i", "barbi5", "bari4a", "bas4si", "1bat", "ba4z", "2b1b", + "b2be", "b3ber", "bbi4na", "4b1d", "4be.", "beak4", "beat3", "4be2d", "be3da", "be3de", "be3di", "be3gi", "be5gu", "1bel", + "be1li", "be3lo", "4be5m", "be5nig", "be5nu", "4bes4", "be3sp", "be5str", "3bet", "bet5iz", "be5tr", "be3tw", "be3w", + "be5yo", "2bf", "4b3h", "bi2b", "bi4d", "3bie", "bi5en", "bi4er", "2b3if", "1bil", "bi3liz", "bina5r4", "bin4d", "bi5net", + "bi3ogr", "bi5ou", "bi2t", "3bi3tio", "bi3tr", "3bit5ua", "b5itz", "b1j", "bk4", "b2l2", "blath5", "b4le.", "blen4", + "5blesp", "b3lis", "b4lo", "blun4t", "4b1m", "4b3n", "bne5g", "3bod", "bod3i", "bo4e", "bol3ic", "bom4bi", "bon4a", + "bon5at", "3boo", "5bor.", "4b1ora", "bor5d", "5bore", "5bori", "5bos4", "b5ota", "both5", "bo4to", "bound3", "4bp", + "4brit", "broth3", "2b5s2", "bsor4", "2bt", "bt4l", "b4to", "b3tr", "buf4fer", "bu4ga", "bu3li", "bumi4", "bu4n", + "bunt4i", "bu3re", "bus5ie", "buss4e", "5bust", "4buta", "3butio", "b5uto", "b1v", "4b5w", "5by.", "bys4", "1ca", + "cab3in", "ca1bl", "cach4", "ca5den", "4cag4", "2c5ah", "ca3lat", "cal4la", "call5in", "4calo", "can5d", "can4e", + "can4ic", "can5is", "can3iz", "can4ty", "cany4", "ca5per", "car5om", "cast5er", "cas5tig", "4casy", "ca4th", + "4cativ", "cav5al", "c3c", "ccha5", "cci4a", "ccompa5", "ccon4", "ccou3t", "2ce.", "4ced.", "4ceden", "3cei", "5cel.", + "3cell", "1cen", "3cenc", "2cen4e", "4ceni", "3cent", "3cep", "ce5ram", "4cesa", "3cessi", "ces5si5b", "ces5t", "cet4", + "c5e4ta", "cew4", "2ch", "4ch.", "4ch3ab", "5chanic", "ch5a5nis", "che2", "cheap3", "4ched", "che5lo", "3chemi", + "ch5ene", "ch3er.", "ch3ers", "4ch1in", "5chine.", "ch5iness", "5chini", "5chio", "3chit", "chi2z", "3cho2", + "ch4ti", "1ci", "3cia", "ci2a5b", "cia5r", "ci5c", "4cier", "5cific.", "4cii", "ci4la", "3cili", "2cim", "2cin", "c4ina", + "3cinat", "cin3em", "c1ing", "c5ing.", "5cino", "cion4", "4cipe", "ci3ph", "4cipic", "4cista", "4cisti", "2c1it", + "cit3iz", "5ciz", "ck1", "ck3i", "1c4l4", "4clar", "c5laratio", "5clare", "cle4m", "4clic", "clim4", "cly4", "c5n", "1co", + "co5ag", "coe2", "2cog", "co4gr", "coi4", "co3inc", "col5i", "5colo", "col3or", "com5er", "con4a", "c4one", "con3g", + "con5t", "co3pa", "cop3ic", "co4pl", "4corb", "coro3n", "cos4e", "cov1", "cove4", "cow5a", "coz5e", "co5zi", "c1q", + "cras5t", "5crat.", "5cratic", "cre3at", "5cred", "4c3reta", "cre4v", "cri2", "cri5f", "c4rin", "cris4", "5criti", + "cro4pl", "crop5o", "cros4e", "cru4d", "4c3s2", "2c1t", "cta4b", "ct5ang", "c5tant", "c2te", "c3ter", "c4ticu", + "ctim3i", "ctu4r", "c4tw", "cud5", "c4uf", "c4ui", "cu5ity", "5culi", "cul4tis", "3cultu", "cu2ma", "c3ume", "cu4mi", + "3cun", "cu3pi", "cu5py", "cur5a4b", "cu5ria", "1cus", "cuss4i", "3c4ut", "cu4tie", "4c5utiv", "4cutr", "1cy", "cze4", + "1d2a", "5da.", "2d3a4b", "dach4", "4daf", "2dag", "da2m2", "dan3g", "dard5", "dark5", "4dary", "3dat", "4dativ", "4dato", + "5dav4", "dav5e", "5day", "d1b", "d5c", "d1d4", "2de.", "deaf5", "deb5it", "de4bon", "decan4", "de4cil", "de5com", + "2d1ed", "4dee.", "de5if", "deli4e", "del5i5q", "de5lo", "d4em", "5dem.", "3demic", "dem5ic.", "de5mil", "de4mons", + "demor5", "1den", "de4nar", "de3no", "denti5f", "de3nu", "de1p", "de3pa", "depi4", "de2pu", "d3eq", "d4erh", "5derm", + "dern5iz", "der5s", "des2", "d2es.", "de1sc", "de2s5o", "des3ti", "de3str", "de4su", "de1t", "de2to", "de1v", "dev3il", + "4dey", "4d1f", "d4ga", "d3ge4t", "dg1i", "d2gy", "d1h2", "5di.", "1d4i3a", "dia5b", "di4cam", "d4ice", "3dict", "3did", + "5di3en", "d1if", "di3ge", "di4lato", "d1in", "1dina", "3dine.", "5dini", "di5niz", "1dio", "dio5g", "di4pl", "dir2", + "di1re", "dirt5i", "dis1", "5disi", "d4is3t", "d2iti", "1di1v", "d1j", "d5k2", "4d5la", "3dle.", "3dled", "3dles.", + "4dless", "2d3lo", "4d5lu", "2dly", "d1m", "4d1n4", "1do", "3do.", "do5de", "5doe", "2d5of", "d4og", "do4la", "doli4", + "do5lor", "dom5iz", "do3nat", "doni4", "doo3d", "dop4p", "d4or", "3dos", "4d5out", "do4v", "3dox", "d1p", "1dr", + "drag5on", "4drai", "dre4", "drea5r", "5dren", "dri4b", "dril4", "dro4p", "4drow", "5drupli", "4dry", "2d1s2", "ds4p", + "d4sw", "d4sy", "d2th", "1du", "d1u1a", "du2c", "d1uca", "duc5er", "4duct.", "4ducts", "du5el", "du4g", "d3ule", "dum4be", + "du4n", "4dup", "du4pe", "d1v", "d1w", "d2y", "5dyn", "dy4se", "dys5p", "e1a4b", "e3act", "ead1", "ead5ie", "ea4ge", + "ea5ger", "ea4l", "eal5er", "eal3ou", "eam3er", "e5and", "ear3a", "ear4c", "ear5es", "ear4ic", "ear4il", "ear5k", + "ear2t", "eart3e", "ea5sp", "e3ass", "east3", "ea2t", "eat5en", "eath3i", "e5atif", "e4a3tu", "ea2v", "eav3en", + "eav5i", "eav5o", "2e1b", "e4bel.", "e4bels", "e4ben", "e4bit", "e3br", "e4cad", "ecan5c", "ecca5", "e1ce", "ec5essa", + "ec2i", "e4cib", "ec5ificat", "ec5ifie", "ec5ify", "ec3im", "eci4t", "e5cite", "e4clam", "e4clus", "e2col", + "e4comm", "e4compe", "e4conc", "e2cor", "ec3ora", "eco5ro", "e1cr", "e4crem", "ec4tan", "ec4te", "e1cu", "e4cul", + "ec3ula", "2e2da", "4ed3d", "e4d1er", "ede4s", "4edi", "e3dia", "ed3ib", "ed3ica", "ed3im", "ed1it", "edi5z", "4edo", + "e4dol", "edon2", "e4dri", "e4dul", "ed5ulo", "ee2c", "eed3i", "ee2f", "eel3i", "ee4ly", "ee2m", "ee4na", "ee4p1", + "ee2s4", "eest4", "ee4ty", "e5ex", "e1f", "e4f3ere", "1eff", "e4fic", "5efici", "efil4", "e3fine", "ef5i5nite", + "3efit", "efor5es", "e4fuse.", "4egal", "eger4", "eg5ib", "eg4ic", "eg5ing", "e5git5", "eg5n", "e4go.", "e4gos", + "eg1ul", "e5gur", "5egy", "e1h4", "eher4", "ei2", "e5ic", "ei5d", "eig2", "ei5gl", "e3imb", "e3inf", "e1ing", "e5inst", + "eir4d", "eit3e", "ei3th", "e5ity", "e1j", "e4jud", "ej5udi", "eki4n", "ek4la", "e1la", "e4la.", "e4lac", "elan4d", + "el5ativ", "e4law", "elaxa4", "e3lea", "el5ebra", "5elec", "e4led", "el3ega", "e5len", "e4l1er", "e1les", "el2f", + "el2i", "e3libe", "e4l5ic.", "el3ica", "e3lier", "el5igib", "e5lim", "e4l3ing", "e3lio", "e2lis", "el5ish", + "e3liv3", "4ella", "el4lab", "ello4", "e5loc", "el5og", "el3op.", "el2sh", "el4ta", "e5lud", "el5ug", "e4mac", "e4mag", + "e5man", "em5ana", "em5b", "e1me", "e2mel", "e4met", "em3ica", "emi4e", "em5igra", "em1in2", "em5ine", "em3i3ni", + "e4mis", "em5ish", "e5miss", "em3iz", "5emniz", "emo4g", "emoni5o", "em3pi", "e4mul", "em5ula", "emu3n", "e3my", + "en5amo", "e4nant", "ench4er", "en3dic", "e5nea", "e5nee", "en3em", "en5ero", "en5esi", "en5est", "en3etr", "e3new", + "en5ics", "e5nie", "e5nil", "e3nio", "en3ish", "en3it", "e5niu", "5eniz", "4enn", "4eno", "eno4g", "e4nos", "en3ov", + "en4sw", "ent5age", "4enthes", "en3ua", "en5uf", "e3ny.", "4en3z", "e5of", "eo2g", "e4oi4", "e3ol", "eop3ar", "e1or", + "eo3re", "eo5rol", "eos4", "e4ot", "eo4to", "e5out", "e5ow", "e2pa", "e3pai", "ep5anc", "e5pel", "e3pent", "ep5etitio", + "ephe4", "e4pli", "e1po", "e4prec", "ep5reca", "e4pred", "ep3reh", "e3pro", "e4prob", "ep4sh", "ep5ti5b", "e4put", + "ep5uta", "e1q", "equi3l", "e4q3ui3s", "er1a", "era4b", "4erand", "er3ar", "4erati.", "2erb", "er4bl", "er3ch", + "er4che", "2ere.", "e3real", "ere5co", "ere3in", "er5el.", "er3emo", "er5ena", "er5ence", "4erene", "er3ent", + "ere4q", "er5ess", "er3est", "eret4", "er1h", "er1i", "e1ria4", "5erick", "e3rien", "eri4er", "er3ine", "e1rio", + "4erit", "er4iu", "eri4v", "e4riva", "er3m4", "er4nis", "4ernit", "5erniz", "er3no", "2ero", "er5ob", "e5roc", "ero4r", + "er1ou", "er1s", "er3set", "ert3er", "4ertl", "er3tw", "4eru", "eru4t", "5erwau", "e1s4a", "e4sage.", "e4sages", + "es2c", "e2sca", "es5can", "e3scr", "es5cu", "e1s2e", "e2sec", "es5ecr", "es5enc", "e4sert.", "e4serts", "e4serva", + "4esh", "e3sha", "esh5en", "e1si", "e2sic", "e2sid", "es5iden", "es5igna", "e2s5im", "es4i4n", "esis4te", "esi4u", + "e5skin", "es4mi", "e2sol", "es3olu", "e2son", "es5ona", "e1sp", "es3per", "es5pira", "es4pre", "2ess", "es4si4b", + "estan4", "es3tig", "es5tim", "4es2to", "e3ston", "2estr", "e5stro", "estruc5", "e2sur", "es5urr", "es4w", "eta4b", + "eten4d", "e3teo", "ethod3", "et1ic", "e5tide", "etin4", "eti4no", "e5tir", "e5titio", "et5itiv", "4etn", "et5ona", + "e3tra", "e3tre", "et3ric", "et5rif", "et3rog", "et5ros", "et3ua", "et5ym", "et5z", "4eu", "e5un", "e3up", "eu3ro", + "eus4", "eute4", "euti5l", "eu5tr", "eva2p5", "e2vas", "ev5ast", "e5vea", "ev3ell", "evel3o", "e5veng", "even4i", + "ev1er", "e5verb", "e1vi", "ev3id", "evi4l", "e4vin", "evi4v", "e5voc", "e5vu", "e1wa", "e4wag", "e5wee", "e3wh", "ewil5", + "ew3ing", "e3wit", "1exp", "5eyc", "5eye.", "eys4", "1fa", "fa3bl", "fab3r", "fa4ce", "4fag", "fain4", "fall5e", "4fa4ma", + "fam5is", "5far", "far5th", "fa3ta", "fa3the", "4fato", "fault5", "4f5b", "4fd", "4fe.", "feas4", "feath3", "fe4b", + "4feca", "5fect", "2fed", "fe3li", "fe4mo", "fen2d", "fend5e", "fer1", "5ferr", "fev4", "4f1f", "f4fes", "f4fie", + "f5fin.", "f2f5is", "f4fly", "f2fy", "4fh", "1fi", "fi3a", "2f3ic.", "4f3ical", "f3ican", "4ficate", "f3icen", + "fi3cer", "fic4i", "5ficia", "5ficie", "4fics", "fi3cu", "fi5del", "fight5", "fil5i", "fill5in", "4fily", "2fin", + "5fina", "fin2d5", "fi2ne", "f1in3g", "fin4n", "fis4ti", "f4l2", "f5less", "flin4", "flo3re", "f2ly5", "4fm", "4fn", + "1fo", "5fon", "fon4de", "fon4t", "fo2r", "fo5rat", "for5ay", "fore5t", "for4i", "fort5a", "fos5", "4f5p", "fra4t", + "f5rea", "fres5c", "fri2", "fril4", "frol5", "2f3s", "2ft", "f4to", "f2ty", "3fu", "fu5el", "4fug", "fu4min", "fu5ne", + "fu3ri", "fusi4", "fus4s", "4futa", "1fy", "1ga", "gaf4", "5gal.", "3gali", "ga3lo", "2gam", "ga5met", "g5amo", "gan5is", + "ga3niz", "gani5za", "4gano", "gar5n4", "gass4", "gath3", "4gativ", "4gaz", "g3b", "gd4", "2ge.", "2ged", "geez4", + "gel4in", "ge5lis", "ge5liz", "4gely", "1gen", "ge4nat", "ge5niz", "4geno", "4geny", "1geo", "ge3om", "g4ery", "5gesi", + "geth5", "4geto", "ge4ty", "ge4v", "4g1g2", "g2ge", "g3ger", "gglu5", "ggo4", "gh3in", "gh5out", "gh4to", "5gi.", "1gi4a", + "gia5r", "g1ic", "5gicia", "g4ico", "gien5", "5gies.", "gil4", "g3imen", "3g4in.", "gin5ge", "5g4ins", "5gio", "3gir", + "gir4l", "g3isl", "gi4u", "5giv", "3giz", "gl2", "gla4", "glad5i", "5glas", "1gle", "gli4b", "g3lig", "3glo", "glo3r", "g1m", + "g4my", "gn4a", "g4na.", "gnet4t", "g1ni", "g2nin", "g4nio", "g1no", "g4non", "1go", "3go.", "gob5", "5goe", "3g4o4g", + "go3is", "gon2", "4g3o3na", "gondo5", "go3ni", "5goo", "go5riz", "gor5ou", "5gos.", "gov1", "g3p", "1gr", "4grada", + "g4rai", "gran2", "5graph.", "g5rapher", "5graphic", "4graphy", "4gray", "gre4n", "4gress.", "4grit", "g4ro", + "gruf4", "gs2", "g5ste", "gth3", "gu4a", "3guard", "2gue", "5gui5t", "3gun", "3gus", "4gu4t", "g3w", "1gy", "2g5y3n", + "gy5ra", "h3ab4l", "hach4", "hae4m", "hae4t", "h5agu", "ha3la", "hala3m", "ha4m", "han4ci", "han4cy", "5hand.", + "han4g", "hang5er", "hang5o", "h5a5niz", "han4k", "han4te", "hap3l", "hap5t", "ha3ran", "ha5ras", "har2d", "hard3e", + "har4le", "harp5en", "har5ter", "has5s", "haun4", "5haz", "haz3a", "h1b", "1head", "3hear", "he4can", "h5ecat", "h4ed", + "he5do5", "he3l4i", "hel4lis", "hel4ly", "h5elo", "hem4p", "he2n", "hena4", "hen5at", "heo5r", "hep5", "h4era", + "hera3p", "her4ba", "here5a", "h3ern", "h5erou", "h3ery", "h1es", "he2s5p", "he4t", "het4ed", "heu4", "h1f", "h1h", + "hi5an", "hi4co", "high5", "h4il2", "himer4", "h4ina", "hion4e", "hi4p", "hir4l", "hi3ro", "hir4p", "hir4r", "his3el", + "his4s", "hith5er", "hi2v", "4hk", "4h1l4", "hlan4", "h2lo", "hlo3ri", "4h1m", "hmet4", "2h1n", "h5odiz", "h5ods", "ho4g", + "hoge4", "hol5ar", "3hol4e", "ho4ma", "home3", "hon4a", "ho5ny", "3hood", "hoon4", "hor5at", "ho5ris", "hort3e", + "ho5ru", "hos4e", "ho5sen", "hos1p", "1hous", "house3", "hov5el", "4h5p", "4hr4", "hree5", "hro5niz", "hro3po", + "4h1s2", "h4sh", "h4tar", "ht1en", "ht5es", "h4ty", "hu4g", "hu4min", "hun5ke", "hun4t", "hus3t4", "hu4t", "h1w", + "h4wart", "hy3pe", "hy3ph", "hy2s", "2i1a", "i2al", "iam4", "iam5ete", "i2an", "4ianc", "ian3i", "4ian4t", "ia5pe", + "iass4", "i4ativ", "ia4tric", "i4atu", "ibe4", "ib3era", "ib5ert", "ib5ia", "ib3in", "ib5it.", "ib5ite", "i1bl", + "ib3li", "i5bo", "i1br", "i2b5ri", "i5bun", "4icam", "5icap", "4icar", "i4car.", "i4cara", "icas5", "i4cay", "iccu4", + "4iceo", "4ich", "2ici", "i5cid", "ic5ina", "i2cip", "ic3ipa", "i4cly", "i2c5oc", "4i1cr", "5icra", "i4cry", "ic4te", + "ictu2", "ic4t3ua", "ic3ula", "ic4um", "ic5uo", "i3cur", "2id", "i4dai", "id5anc", "id5d", "ide3al", "ide4s", "i2di", + "id5ian", "idi4ar", "i5die", "id3io", "idi5ou", "id1it", "id5iu", "i3dle", "i4dom", "id3ow", "i4dr", "i2du", "id5uo", + "2ie4", "ied4e", "5ie5ga", "ield3", "ien5a4", "ien4e", "i5enn", "i3enti", "i1er.", "i3esc", "i1est", "i3et", "4if.", + "if5ero", "iff5en", "if4fr", "4ific.", "i3fie", "i3fl", "4ift", "2ig", "iga5b", "ig3era", "ight3i", "4igi", "i3gib", + "ig3il", "ig3in", "ig3it", "i4g4l", "i2go", "ig3or", "ig5ot", "i5gre", "igu5i", "ig1ur", "i3h", "4i5i4", "i3j", "4ik", + "i1la", "il3a4b", "i4lade", "i2l5am", "ila5ra", "i3leg", "il1er", "ilev4", "il5f", "il1i", "il3ia", "il2ib", "il3io", + "il4ist", "2ilit", "il2iz", "ill5ab", "4iln", "il3oq", "il4ty", "il5ur", "il3v", "i4mag", "im3age", "ima5ry", + "imenta5r", "4imet", "im1i", "im5ida", "imi5le", "i5mini", "4imit", "im4ni", "i3mon", "i2mu", "im3ula", "2in.", + "i4n3au", "4inav", "incel4", "in3cer", "4ind", "in5dling", "2ine", "i3nee", "iner4ar", "i5ness", "4inga", "4inge", + "in5gen", "4ingi", "in5gling", "4ingo", "4ingu", "2ini", "i5ni.", "i4nia", "in3io", "in1is", "i5nite.", "5initio", + "in3ity", "4ink", "4inl", "2inn", "2i1no", "i4no4c", "ino4s", "i4not", "2ins", "in3se", "insur5a", "2int.", "2in4th", + "in1u", "i5nus", "4iny", "2io", "4io.", "ioge4", "io2gr", "i1ol", "io4m", "ion3at", "ion4ery", "ion3i", "io5ph", "ior3i", + "i4os", "io5th", "i5oti", "io4to", "i4our", "2ip", "ipe4", "iphras4", "ip3i", "ip4ic", "ip4re4", "ip3ul", "i3qua", + "iq5uef", "iq3uid", "iq3ui3t", "4ir", "i1ra", "ira4b", "i4rac", "ird5e", "ire4de", "i4ref", "i4rel4", "i4res", "ir5gi", + "ir1i", "iri5de", "ir4is", "iri3tu", "5i5r2iz", "ir4min", "iro4g", "5iron.", "ir5ul", "2is.", "is5ag", "is3ar", + "isas5", "2is1c", "is3ch", "4ise", "is3er", "3isf", "is5han", "is3hon", "ish5op", "is3ib", "isi4d", "i5sis", "is5itiv", + "4is4k", "islan4", "4isms", "i2so", "iso5mer", "is1p", "is2pi", "is4py", "4is1s", "is4sal", "issen4", "is4ses", + "is4ta.", "is1te", "is1ti", "ist4ly", "4istral", "i2su", "is5us", "4ita.", "ita4bi", "i4tag", "4ita5m", "i3tan", + "i3tat", "2ite", "it3era", "i5teri", "it4es", "2ith", "i1ti", "4itia", "4i2tic", "it3ica", "5i5tick", "it3ig", + "it5ill", "i2tim", "2itio", "4itis", "i4tism", "i2t5o5m", "4iton", "i4tram", "it5ry", "4itt", "it3uat", "i5tud", + "it3ul", "4itz.", "i1u", "2iv", "iv3ell", "iv3en.", "i4v3er.", "i4vers.", "iv5il.", "iv5io", "iv1it", "i5vore", + "iv3o3ro", "i4v3ot", "4i5w", "ix4o", "4iy", "4izar", "izi4", "5izont", "5ja", "jac4q", "ja4p", "1je", "jer5s", "4jestie", + "4jesty", "jew3", "jo4p", "5judg", "3ka.", "k3ab", "k5ag", "kais4", "kal4", "k1b", "k2ed", "1kee", "ke4g", "ke5li", "k3en4d", + "k1er", "kes4", "k3est.", "ke4ty", "k3f", "kh4", "k1i", "5ki.", "5k2ic", "k4ill", "kilo5", "k4im", "k4in.", "kin4de", + "k5iness", "kin4g", "ki4p", "kis4", "k5ish", "kk4", "k1l", "4kley", "4kly", "k1m", "k5nes", "1k2no", "ko5r", "kosh4", "k3ou", + "kro5n", "4k1s2", "k4sc", "ks4l", "k4sy", "k5t", "k1w", "lab3ic", "l4abo", "laci4", "l4ade", "la3dy", "lag4n", "lam3o", + "3land", "lan4dl", "lan5et", "lan4te", "lar4g", "lar3i", "las4e", "la5tan", "4lateli", "4lativ", "4lav", "la4v4a", + "2l1b", "lbin4", "4l1c2", "lce4", "l3ci", "2ld", "l2de", "ld4ere", "ld4eri", "ldi4", "ld5is", "l3dr", "l4dri", "le2a", + "le4bi", "left5", "5leg.", "5legg", "le4mat", "lem5atic", "4len.", "3lenc", "5lene.", "1lent", "le3ph", "le4pr", + "lera5b", "ler4e", "3lerg", "3l4eri", "l4ero", "les2", "le5sco", "5lesq", "3less", "5less.", "l3eva", "lev4er.", + "lev4era", "lev4ers", "3ley", "4leye", "2lf", "l5fr", "4l1g4", "l5ga", "lgar3", "l4ges", "lgo3", "2l3h", "li4ag", "li2am", + "liar5iz", "li4as", "li4ato", "li5bi", "5licio", "li4cor", "4lics", "4lict.", "l4icu", "l3icy", "l3ida", "lid5er", + "3lidi", "lif3er", "l4iff", "li4fl", "5ligate", "3ligh", "li4gra", "3lik", "4l4i4l", "lim4bl", "lim3i", "li4mo", + "l4im4p", "l4ina", "1l4ine", "lin3ea", "lin3i", "link5er", "li5og", "4l4iq", "lis4p", "l1it", "l2it.", "5litica", + "l5i5tics", "liv3er", "l1iz", "4lj", "lka3", "l3kal", "lka4t", "l1l", "l4law", "l2le", "l5lea", "l3lec", "l3leg", "l3lel", + "l3le4n", "l3le4t", "ll2i", "l2lin4", "l5lina", "ll4o", "lloqui5", "ll5out", "l5low", "2lm", "l5met", "lm3ing", + "l4mod", "lmon4", "2l1n2", "3lo.", "lob5al", "lo4ci", "4lof", "3logic", "l5ogo", "3logu", "lom3er", "5long", "lon4i", + "l3o3niz", "lood5", "5lope.", "lop3i", "l3opm", "lora4", "lo4rato", "lo5rie", "lor5ou", "5los.", "los5et", + "5losophiz", "5losophy", "los4t", "lo4ta", "loun5d", "2lout", "4lov", "2lp", "lpa5b", "l3pha", "l5phi", "lp5ing", + "l3pit", "l4pl", "l5pr", "4l1r", "2l1s2", "l4sc", "l2se", "l4sie", "4lt", "lt5ag", "ltane5", "l1te", "lten4", "ltera4", + "lth3i", "l5ties.", "ltis4", "l1tr", "ltu2", "ltur3a", "lu5a", "lu3br", "luch4", "lu3ci", "lu3en", "luf4", "lu5id", + "lu4ma", "5lumi", "l5umn.", "5lumnia", "lu3o", "luo3r", "4lup", "luss4", "lus3te", "1lut", "l5ven", "l5vet4", "2l1w", + "1ly", "4lya", "4lyb", "ly5me", "ly3no", "2lys4", "l5yse", "1ma", "2mab", "ma2ca", "ma5chine", "ma4cl", "mag5in", "5magn", + "2mah", "maid5", "4mald", "ma3lig", "ma5lin", "mal4li", "mal4ty", "5mania", "man5is", "man3iz", "4map", "ma5rine.", + "ma5riz", "mar4ly", "mar3v", "ma5sce", "mas4e", "mas1t", "5mate", "math3", "ma3tis", "4matiza", "4m1b", "mba4t5", + "m5bil", "m4b3ing", "mbi4v", "4m5c", "4me.", "2med", "4med.", "5media", "me3die", "m5e5dy", "me2g", "mel5on", "mel4t", + "me2m", "mem1o3", "1men", "men4a", "men5ac", "men4de", "4mene", "men4i", "mens4", "mensu5", "3ment", "men4te", "me5on", + "m5ersa", "2mes", "3mesti", "me4ta", "met3al", "me1te", "me5thi", "m4etr", "5metric", "me5trie", "me3try", "me4v", + "4m1f", "2mh", "5mi.", "mi3a", "mid4a", "mid4g", "mig4", "3milia", "m5i5lie", "m4ill", "min4a", "3mind", "m5inee", + "m4ingl", "min5gli", "m5ingly", "min4t", "m4inu", "miot4", "m2is", "mis4er.", "mis5l", "mis4ti", "m5istry", "4mith", + "m2iz", "4mk", "4m1l", "m1m", "mma5ry", "4m1n", "mn4a", "m4nin", "mn4o", "1mo", "4mocr", "5mocratiz", "mo2d1", "mo4go", + "mois2", "moi5se", "4mok", "mo5lest", "mo3me", "mon5et", "mon5ge", "moni3a", "mon4ism", "mon4ist", "mo3niz", + "monol4", "mo3ny.", "mo2r", "4mora.", "mos2", "mo5sey", "mo3sp", "moth3", "m5ouf", "3mous", "mo2v", "4m1p", "mpara5", + "mpa5rab", "mpar5i", "m3pet", "mphas4", "m2pi", "mpi4a", "mp5ies", "m4p1in", "m5pir", "mp5is", "mpo3ri", "mpos5ite", + "m4pous", "mpov5", "mp4tr", "m2py", "4m3r", "4m1s2", "m4sh", "m5si", "4mt", "1mu", "mula5r4", "5mult", "multi3", "3mum", + "mun2", "4mup", "mu4u", "4mw", "1na", "2n1a2b", "n4abu", "4nac.", "na4ca", "n5act", "nag5er.", "nak4", "na4li", "na5lia", + "4nalt", "na5mit", "n2an", "nanci4", "nan4it", "nank4", "nar3c", "4nare", "nar3i", "nar4l", "n5arm", "n4as", "nas4c", + "nas5ti", "n2at", "na3tal", "nato5miz", "n2au", "nau3se", "3naut", "nav4e", "4n1b4", "ncar5", "n4ces.", "n3cha", + "n5cheo", "n5chil", "n3chis", "nc1in", "nc4it", "ncour5a", "n1cr", "n1cu", "n4dai", "n5dan", "n1de", "nd5est.", + "ndi4b", "n5d2if", "n1dit", "n3diz", "n5duc", "ndu4r", "nd2we", "2ne.", "n3ear", "ne2b", "neb3u", "ne2c", "5neck", "2ned", + "ne4gat", "neg5ativ", "5nege", "ne4la", "nel5iz", "ne5mi", "ne4mo", "1nen", "4nene", "3neo", "ne4po", "ne2q", "n1er", + "nera5b", "n4erar", "n2ere", "n4er5i", "ner4r", "1nes", "2nes.", "4nesp", "2nest", "4nesw", "3netic", "ne4v", "n5eve", + "ne4w", "n3f", "n4gab", "n3gel", "nge4n4e", "n5gere", "n3geri", "ng5ha", "n3gib", "ng1in", "n5git", "n4gla", "ngov4", + "ng5sh", "n1gu", "n4gum", "n2gy", "4n1h4", "nha4", "nhab3", "nhe4", "3n4ia", "ni3an", "ni4ap", "ni3ba", "ni4bl", "ni4d", + "ni5di", "ni4er", "ni2fi", "ni5ficat", "n5igr", "nik4", "n1im", "ni3miz", "n1in", "5nine.", "nin4g", "ni4o", "5nis.", + "nis4ta", "n2it", "n4ith", "3nitio", "n3itor", "ni3tr", "n1j", "4nk2", "n5kero", "n3ket", "nk3in", "n1kl", "4n1l", "n5m", + "nme4", "nmet4", "4n1n2", "nne4", "nni3al", "nni4v", "nob4l", "no3ble", "n5ocl", "4n3o2d", "3noe", "4nog", "noge4", + "nois5i", "no5l4i", "5nologis", "3nomic", "n5o5miz", "no4mo", "no3my", "no4n", "non4ag", "non5i", "n5oniz", "4nop", + "5nop5o5li", "nor5ab", "no4rary", "4nosc", "nos4e", "nos5t", "no5ta", "1nou", "3noun", "nov3el3", "nowl3", "n1p4", + "npi4", "npre4c", "n1q", "n1r", "nru4", "2n1s2", "ns5ab", "nsati4", "ns4c", "n2se", "n4s3es", "nsid1", "nsig4", "n2sl", + "ns3m", "n4soc", "ns4pe", "n5spi", "nsta5bl", "n1t", "nta4b", "nter3s", "nt2i", "n5tib", "nti4er", "nti2f", "n3tine", + "n4t3ing", "nti4p", "ntrol5li", "nt4s", "ntu3me", "nu1a", "nu4d", "nu5en", "nuf4fe", "n3uin", "3nu3it", "n4um", + "nu1me", "n5umi", "3nu4n", "n3uo", "nu3tr", "n1v2", "n1w4", "nym4", "nyp4", "4nz", "n3za", "4oa", "oad3", "o5a5les", "oard3", + "oas4e", "oast5e", "oat5i", "ob3a3b", "o5bar", "obe4l", "o1bi", "o2bin", "ob5ing", "o3br", "ob3ul", "o1ce", "och4", + "o3chet", "ocif3", "o4cil", "o4clam", "o4cod", "oc3rac", "oc5ratiz", "ocre3", "5ocrit", "octor5a", "oc3ula", + "o5cure", "od5ded", "od3ic", "odi3o", "o2do4", "odor3", "od5uct.", "od5ucts", "o4el", "o5eng", "o3er", "oe4ta", "o3ev", + "o2fi", "of5ite", "ofit4t", "o2g5a5r", "og5ativ", "o4gato", "o1ge", "o5gene", "o5geo", "o4ger", "o3gie", "1o1gis", + "og3it", "o4gl", "o5g2ly", "3ogniz", "o4gro", "ogu5i", "1ogy", "2ogyn", "o1h2", "ohab5", "oi2", "oic3es", "oi3der", + "oiff4", "oig4", "oi5let", "o3ing", "oint5er", "o5ism", "oi5son", "oist5en", "oi3ter", "o5j", "2ok", "o3ken", "ok5ie", + "o1la", "o4lan", "olass4", "ol2d", "old1e", "ol3er", "o3lesc", "o3let", "ol4fi", "ol2i", "o3lia", "o3lice", "ol5id.", + "o3li4f", "o5lil", "ol3ing", "o5lio", "o5lis.", "ol3ish", "o5lite", "o5litio", "o5liv", "olli4e", "ol5ogiz", + "olo4r", "ol5pl", "ol2t", "ol3ub", "ol3ume", "ol3un", "o5lus", "ol2v", "o2ly", "om5ah", "oma5l", "om5atiz", "om2be", + "om4bl", "o2me", "om3ena", "om5erse", "o4met", "om5etry", "o3mia", "om3ic.", "om3ica", "o5mid", "om1in", "o5mini", + "5ommend", "omo4ge", "o4mon", "om3pi", "ompro5", "o2n", "on1a", "on4ac", "o3nan", "on1c", "3oncil", "2ond", "on5do", + "o3nen", "on5est", "on4gu", "on1ic", "o3nio", "on1is", "o5niu", "on3key", "on4odi", "on3omy", "on3s", "onspi4", + "onspir5a", "onsu4", "onten4", "on3t4i", "ontif5", "on5um", "onva5", "oo2", "ood5e", "ood5i", "oo4k", "oop3i", "o3ord", + "oost5", "o2pa", "ope5d", "op1er", "3opera", "4operag", "2oph", "o5phan", "o5pher", "op3ing", "o3pit", "o5pon", + "o4posi", "o1pr", "op1u", "opy5", "o1q", "o1ra", "o5ra.", "o4r3ag", "or5aliz", "or5ange", "ore5a", "o5real", "or3ei", + "ore5sh", "or5est.", "orew4", "or4gu", "4o5ria", "or3ica", "o5ril", "or1in", "o1rio", "or3ity", "o3riu", "or2mi", + "orn2e", "o5rof", "or3oug", "or5pe", "3orrh", "or4se", "ors5en", "orst4", "or3thi", "or3thy", "or4ty", "o5rum", "o1ry", + "os3al", "os2c", "os4ce", "o3scop", "4oscopi", "o5scr", "os4i4e", "os5itiv", "os3ito", "os3ity", "osi4u", "os4l", + "o2so", "os4pa", "os4po", "os2ta", "o5stati", "os5til", "os5tit", "o4tan", "otele4g", "ot3er.", "ot5ers", "o4tes", + "4oth", "oth5esi", "oth3i4", "ot3ic.", "ot5ica", "o3tice", "o3tif", "o3tis", "oto5s", "ou2", "ou3bl", "ouch5i", + "ou5et", "ou4l", "ounc5er", "oun2d", "ou5v", "ov4en", "over4ne", "over3s", "ov4ert", "o3vis", "oviti4", "o5v4ol", + "ow3der", "ow3el", "ow5est", "ow1i", "own5i", "o4wo", "oy1a", "1pa", "pa4ca", "pa4ce", "pac4t", "p4ad", "5pagan", + "p3agat", "p4ai", "pain4", "p4al", "pan4a", "pan3el", "pan4ty", "pa3ny", "pa1p", "pa4pu", "para5bl", "par5age", + "par5di", "3pare", "par5el", "p4a4ri", "par4is", "pa2te", "pa5ter", "5pathic", "pa5thy", "pa4tric", "pav4", "3pay", + "4p1b", "pd4", "4pe.", "3pe4a", "pear4l", "pe2c", "2p2ed", "3pede", "3pedi", "pedia4", "ped4ic", "p4ee", "pee4d", "pek4", + "pe4la", "peli4e", "pe4nan", "p4enc", "pen4th", "pe5on", "p4era.", "pera5bl", "p4erag", "p4eri", "peri5st", + "per4mal", "perme5", "p4ern", "per3o", "per3ti", "pe5ru", "per1v", "pe2t", "pe5ten", "pe5tiz", "4pf", "4pg", "4ph.", + "phar5i", "phe3no", "ph4er", "ph4es.", "ph1ic", "5phie", "ph5ing", "5phisti", "3phiz", "ph2l", "3phob", "3phone", + "5phoni", "pho4r", "4phs", "ph3t", "5phu", "1phy", "pi3a", "pian4", "pi4cie", "pi4cy", "p4id", "p5ida", "pi3de", "5pidi", + "3piec", "pi3en", "pi4grap", "pi3lo", "pi2n", "p4in.", "pind4", "p4ino", "3pi1o", "pion4", "p3ith", "pi5tha", "pi2tu", + "2p3k2", "1p2l2", "3plan", "plas5t", "pli3a", "pli5er", "4plig", "pli4n", "ploi4", "plu4m", "plum4b", "4p1m", "2p3n", + "po4c", "5pod.", "po5em", "po3et5", "5po4g", "poin2", "5point", "poly5t", "po4ni", "po4p", "1p4or", "po4ry", "1pos", + "pos1s", "p4ot", "po4ta", "5poun", "4p1p", "ppa5ra", "p2pe", "p4ped", "p5pel", "p3pen", "p3per", "p3pet", "ppo5site", + "pr2", "pray4e", "5preci", "pre5co", "pre3em", "pref5ac", "pre4la", "pre3r", "p3rese", "3press", "pre5ten", "pre3v", + "5pri4e", "prin4t3", "pri4s", "pris3o", "p3roca", "prof5it", "pro3l", "pros3e", "pro1t", "2p1s2", "p2se", "ps4h", + "p4sib", "2p1t", "pt5a4b", "p2te", "p2th", "pti3m", "ptu4r", "p4tw", "pub3", "pue4", "puf4", "pul3c", "pu4m", "pu2n", + "pur4r", "5pus", "pu2t", "5pute", "put3er", "pu3tr", "put4ted", "put4tin", "p3w", "qu2", "qua5v", "2que.", "3quer", + "3quet", "2rab", "ra3bi", "rach4e", "r5acl", "raf5fi", "raf4t", "r2ai", "ra4lo", "ram3et", "r2ami", "rane5o", "ran4ge", + "r4ani", "ra5no", "rap3er", "3raphy", "rar5c", "rare4", "rar5ef", "4raril", "r2as", "ration4", "rau4t", "ra5vai", + "rav3el", "ra5zie", "r1b", "r4bab", "r4bag", "rbi2", "rbi4f", "r2bin", "r5bine", "rb5ing.", "rb4o", "r1c", "r2ce", + "rcen4", "r3cha", "rch4er", "r4ci4b", "rc4it", "rcum3", "r4dal", "rd2i", "rdi4a", "rdi4er", "rdin4", "rd3ing", "2re.", + "re1al", "re3an", "re5arr", "5reav", "re4aw", "r5ebrat", "rec5oll", "rec5ompe", "re4cre", "2r2ed", "re1de", + "re3dis", "red5it", "re4fac", "re2fe", "re5fer.", "re3fi", "re4fy", "reg3is", "re5it", "re1li", "re5lu", "r4en4ta", + "ren4te", "re1o", "re5pin", "re4posi", "re1pu", "r1er4", "r4eri", "rero4", "re5ru", "r4es.", "re4spi", "ress5ib", + "res2t", "re5stal", "re3str", "re4ter", "re4ti4z", "re3tri", "reu2", "re5uti", "rev2", "re4val", "rev3el", + "r5ev5er.", "re5vers", "re5vert", "re5vil", "rev5olu", "re4wh", "r1f", "rfu4", "r4fy", "rg2", "rg3er", "r3get", + "r3gic", "rgi4n", "rg3ing", "r5gis", "r5git", "r1gl", "rgo4n", "r3gu", "rh4", "4rh.", "4rhal", "ri3a", "ria4b", "ri4ag", + "r4ib", "rib3a", "ric5as", "r4ice", "4rici", "5ricid", "ri4cie", "r4ico", "rid5er", "ri3enc", "ri3ent", "ri1er", + "ri5et", "rig5an", "5rigi", "ril3iz", "5riman", "rim5i", "3rimo", "rim4pe", "r2ina", "5rina.", "rin4d", "rin4e", + "rin4g", "ri1o", "5riph", "riph5e", "ri2pl", "rip5lic", "r4iq", "r2is", "r4is.", "ris4c", "r3ish", "ris4p", "ri3ta3b", + "r5ited.", "rit5er.", "rit5ers", "rit3ic", "ri2tu", "rit5ur", "riv5el", "riv3et", "riv3i", "r3j", "r3ket", "rk4le", + "rk4lin", "r1l", "rle4", "r2led", "r4lig", "r4lis", "rl5ish", "r3lo4", "r1m", "rma5c", "r2me", "r3men", "rm5ers", + "rm3ing", "r4ming.", "r4mio", "r3mit", "r4my", "r4nar", "r3nel", "r4ner", "r5net", "r3ney", "r5nic", "r1nis4", "r3nit", + "r3niv", "rno4", "r4nou", "r3nu", "rob3l", "r2oc", "ro3cr", "ro4e", "ro1fe", "ro5fil", "rok2", "ro5ker", "5role.", + "rom5ete", "rom4i", "rom4p", "ron4al", "ron4e", "ro5n4is", "ron4ta", "1room", "5root", "ro3pel", "rop3ic", "ror3i", + "ro5ro", "ros5per", "ros4s", "ro4the", "ro4ty", "ro4va", "rov5el", "rox5", "r1p", "r4pea", "r5pent", "rp5er.", "r3pet", + "rp4h4", "rp3ing", "r3po", "r1r4", "rre4c", "rre4f", "r4reo", "rre4st", "rri4o", "rri4v", "rron4", "rros4", "rrys4", + "4rs2", "r1sa", "rsa5ti", "rs4c", "r2se", "r3sec", "rse4cr", "rs5er.", "rs3es", "rse5v2", "r1sh", "r5sha", "r1si", + "r4si4b", "rson3", "r1sp", "r5sw", "rtach4", "r4tag", "r3teb", "rten4d", "rte5o", "r1ti", "rt5ib", "rti4d", "r4tier", + "r3tig", "rtil3i", "rtil4l", "r4tily", "r4tist", "r4tiv", "r3tri", "rtroph4", "rt4sh", "ru3a", "ru3e4l", "ru3en", + "ru4gl", "ru3in", "rum3pl", "ru2n", "runk5", "run4ty", "r5usc", "ruti5n", "rv4e", "rvel4i", "r3ven", "rv5er.", + "r5vest", "r3vey", "r3vic", "rvi4v", "r3vo", "r1w", "ry4c", "5rynge", "ry3t", "sa2", "2s1ab", "5sack", "sac3ri", "s3act", + "5sai", "salar4", "sal4m", "sa5lo", "sal4t", "3sanc", "san4de", "s1ap", "sa5ta", "5sa3tio", "sat3u", "sau4", "sa5vor", + "5saw", "4s5b", "scan4t5", "sca4p", "scav5", "s4ced", "4scei", "s4ces", "sch2", "s4cho", "3s4cie", "5scin4d", "scle5", + "s4cli", "scof4", "4scopy", "scour5a", "s1cu", "4s5d", "4se.", "se4a", "seas4", "sea5w", "se2c3o", "3sect", "4s4ed", + "se4d4e", "s5edl", "se2g", "seg3r", "5sei", "se1le", "5self", "5selv", "4seme", "se4mol", "sen5at", "4senc", "sen4d", + "s5ened", "sen5g", "s5enin", "4sentd", "4sentl", "sep3a3", "4s1er.", "s4erl", "ser4o", "4servo", "s1e4s", "se5sh", + "ses5t", "5se5um", "5sev", "sev3en", "sew4i", "5sex", "4s3f", "2s3g", "s2h", "2sh.", "sh1er", "5shev", "sh1in", "sh3io", + "3ship", "shiv5", "sho4", "sh5old", "shon3", "shor4", "short5", "4shw", "si1b", "s5icc", "3side.", "5sides", "5sidi", + "si5diz", "4signa", "sil4e", "4sily", "2s1in", "s2ina", "5sine.", "s3ing", "1sio", "5sion", "sion5a", "si2r", "sir5a", + "1sis", "3sitio", "5siu", "1siv", "5siz", "sk2", "4ske", "s3ket", "sk5ine", "sk5ing", "s1l2", "s3lat", "s2le", "slith5", + "2s1m", "s3ma", "small3", "sman3", "smel4", "s5men", "5smith", "smol5d4", "s1n4", "1so", "so4ce", "soft3", "so4lab", + "sol3d2", "so3lic", "5solv", "3som", "3s4on.", "sona4", "son4g", "s4op", "5sophic", "s5ophiz", "s5ophy", "sor5c", + "sor5d", "4sov", "so5vi", "2spa", "5spai", "spa4n", "spen4d", "2s5peo", "2sper", "s2phe", "3spher", "spho5", "spil4", + "sp5ing", "4spio", "s4ply", "s4pon", "spor4", "4spot", "squal4l", "s1r", "2ss", "s1sa", "ssas3", "s2s5c", "s3sel", + "s5seng", "s4ses.", "s5set", "s1si", "s4sie", "ssi4er", "ss5ily", "s4sl", "ss4li", "s4sn", "sspend4", "ss2t", "ssur5a", + "ss5w", "2st.", "s2tag", "s2tal", "stam4i", "5stand", "s4ta4p", "5stat.", "s4ted", "stern5i", "s5tero", "ste2w", + "stew5a", "s3the", "st2i", "s4ti.", "s5tia", "s1tic", "5stick", "s4tie", "s3tif", "st3ing", "5stir", "s1tle", "5stock", + "stom3a", "5stone", "s4top", "3store", "st4r", "s4trad", "5stratu", "s4tray", "s4trid", "4stry", "4st3w", "s2ty", + "1su", "su1al", "su4b3", "su2g3", "su5is", "suit3", "s4ul", "su2m", "sum3i", "su2n", "su2r", "4sv", "sw2", "4swo", "s4y", + "4syc", "3syl", "syn5o", "sy5rin", "1ta", "3ta.", "2tab", "ta5bles", "5taboliz", "4taci", "ta5do", "4taf4", "tai5lo", + "ta2l", "ta5la", "tal5en", "tal3i", "4talk", "tal4lis", "ta5log", "ta5mo", "tan4de", "tanta3", "ta5per", "ta5pl", + "tar4a", "4tarc", "4tare", "ta3riz", "tas4e", "ta5sy", "4tatic", "ta4tur", "taun4", "tav4", "2taw", "tax4is", "2t1b", + "4tc", "t4ch", "tch5et", "4t1d", "4te.", "tead4i", "4teat", "tece4", "5tect", "2t1ed", "te5di", "1tee", "teg4", "te5ger", + "te5gi", "3tel.", "teli4", "5tels", "te2ma2", "tem3at", "3tenan", "3tenc", "3tend", "4tenes", "1tent", "ten4tag", + "1teo", "te4p", "te5pe", "ter3c", "5ter3d", "1teri", "ter5ies", "ter3is", "teri5za", "5ternit", "ter5v", "4tes.", + "4tess", "t3ess.", "teth5e", "3teu", "3tex", "4tey", "2t1f", "4t1g", "2th.", "than4", "th2e", "4thea", "th3eas", "the5at", + "the3is", "3thet", "th5ic.", "th5ica", "4thil", "5think", "4thl", "th5ode", "5thodic", "4thoo", "thor5it", + "tho5riz", "2ths", "1tia", "ti4ab", "ti4ato", "2ti2b", "4tick", "t4ico", "t4ic1u", "5tidi", "3tien", "tif2", "ti5fy", + "2tig", "5tigu", "till5in", "1tim", "4timp", "tim5ul", "2t1in", "t2ina", "3tine.", "3tini", "1tio", "ti5oc", "tion5ee", + "5tiq", "ti3sa", "3tise", "tis4m", "ti5so", "tis4p", "5tistica", "ti3tl", "ti4u", "1tiv", "tiv4a", "1tiz", "ti3za", + "ti3zen", "2tl", "t5la", "tlan4", "3tle.", "3tled", "3tles.", "t5let.", "t5lo", "4t1m", "tme4", "2t1n2", "1to", "to3b", + "to5crat", "4todo", "2tof", "to2gr", "to5ic", "to2ma", "tom4b", "to3my", "ton4ali", "to3nat", "4tono", "4tony", + "to2ra", "to3rie", "tor5iz", "tos2", "5tour", "4tout", "to3war", "4t1p", "1tra", "tra3b", "tra5ch", "traci4", + "trac4it", "trac4te", "tras4", "tra5ven", "trav5es5", "tre5f", "tre4m", "trem5i", "5tria", "tri5ces", "5tricia", + "4trics", "2trim", "tri4v", "tro5mi", "tron5i", "4trony", "tro5phe", "tro3sp", "tro3v", "tru5i", "trus4", "4t1s2", + "t4sc", "tsh4", "t4sw", "4t3t2", "t4tes", "t5to", "ttu4", "1tu", "tu1a", "tu3ar", "tu4bi", "tud2", "4tue", "4tuf4", "5tu3i", + "3tum", "tu4nis", "2t3up.", "3ture", "5turi", "tur3is", "tur5o", "tu5ry", "3tus", "4tv", "tw4", "4t1wa", "twis4", "4two", + "1ty", "4tya", "2tyl", "type3", "ty5ph", "4tz", "tz4e", "4uab", "uac4", "ua5na", "uan4i", "uar5ant", "uar2d", "uar3i", + "uar3t", "u1at", "uav4", "ub4e", "u4bel", "u3ber", "u4bero", "u1b4i", "u4b5ing", "u3ble.", "u3ca", "uci4b", "uc4it", + "ucle3", "u3cr", "u3cu", "u4cy", "ud5d", "ud3er", "ud5est", "udev4", "u1dic", "ud3ied", "ud3ies", "ud5is", "u5dit", + "u4don", "ud4si", "u4du", "u4ene", "uens4", "uen4te", "uer4il", "3ufa", "u3fl", "ugh3en", "ug5in", "2ui2", "uil5iz", + "ui4n", "u1ing", "uir4m", "uita4", "uiv3", "uiv4er.", "u5j", "4uk", "u1la", "ula5b", "u5lati", "ulch4", "5ulche", + "ul3der", "ul4e", "u1len", "ul4gi", "ul2i", "u5lia", "ul3ing", "ul5ish", "ul4lar", "ul4li4b", "ul4lis", "4ul3m", + "u1l4o", "4uls", "uls5es", "ul1ti", "ultra3", "4ultu", "u3lu", "ul5ul", "ul5v", "um5ab", "um4bi", "um4bly", "u1mi", + "u4m3ing", "umor5o", "um2p", "unat4", "u2ne", "un4er", "u1ni", "un4im", "u2nin", "un5ish", "uni3v", "un3s4", "un4sw", + "unt3ab", "un4ter.", "un4tes", "unu4", "un5y", "un5z", "u4ors", "u5os", "u1ou", "u1pe", "uper5s", "u5pia", "up3ing", + "u3pl", "up3p", "upport5", "upt5ib", "uptu4", "u1ra", "4ura.", "u4rag", "u4ras", "ur4be", "urc4", "ur1d", "ure5at", + "ur4fer", "ur4fr", "u3rif", "uri4fic", "ur1in", "u3rio", "u1rit", "ur3iz", "ur2l", "url5ing.", "ur4no", "uros4", + "ur4pe", "ur4pi", "urs5er", "ur5tes", "ur3the", "urti4", "ur4tie", "u3ru", "2us", "u5sad", "u5san", "us4ap", "usc2", + "us3ci", "use5a", "u5sia", "u3sic", "us4lin", "us1p", "us5sl", "us5tere", "us1tr", "u2su", "usur4", "uta4b", "u3tat", + "4ute.", "4utel", "4uten", "uten4i", "4u1t2i", "uti5liz", "u3tine", "ut3ing", "ution5a", "u4tis", "5u5tiz", "u4t1l", + "ut5of", "uto5g", "uto5matic", "u5ton", "u4tou", "uts4", "u3u", "uu4m", "u1v2", "uxu3", "uz4e", "1va", "5va.", "2v1a4b", + "vac5il", "vac3u", "vag4", "va4ge", "va5lie", "val5o", "val1u", "va5mo", "va5niz", "va5pi", "var5ied", "3vat", "4ve.", + "4ved", "veg3", "v3el.", "vel3li", "ve4lo", "v4ely", "ven3om", "v5enue", "v4erd", "5vere.", "v4erel", "v3eren", + "ver5enc", "v4eres", "ver3ie", "vermi4n", "3verse", "ver3th", "v4e2s", "4ves.", "ves4te", "ve4te", "vet3er", + "ve4ty", "vi5ali", "5vian", "5vide.", "5vided", "4v3iden", "5vides", "5vidi", "v3if", "vi5gn", "vik4", "2vil", + "5vilit", "v3i3liz", "v1in", "4vi4na", "v2inc", "vin5d", "4ving", "vio3l", "v3io4r", "vi1ou", "vi4p", "vi5ro", + "vis3it", "vi3so", "vi3su", "4viti", "vit3r", "4vity", "3viv", "5vo.", "voi4", "3vok", "vo4la", "v5ole", "5volt", "3volv", + "vom5i", "vor5ab", "vori4", "vo4ry", "vo4ta", "4votee", "4vv4", "v4y", "w5abl", "2wac", "wa5ger", "wag5o", "wait5", + "w5al.", "wam4", "war4t", "was4t", "wa1te", "wa5ver", "w1b", "wea5rie", "weath3", "wed4n", "weet3", "wee5v", "wel4l", + "w1er", "west3", "w3ev", "whi4", "wi2", "wil2", "will5in", "win4de", "win4g", "wir4", "3wise", "with3", "wiz5", "w4k", + "wl4es", "wl3in", "w4no", "1wo2", "wom1", "wo5ven", "w5p", "wra4", "wri4", "writa4", "w3sh", "ws4l", "ws4pe", "w5s4t", "4wt", + "wy4", "x1a", "xac5e", "x4ago", "xam3", "x4ap", "xas5", "x3c2", "x1e", "xe4cuto", "x2ed", "xer4i", "xe5ro", "x1h", "xhi2", + "xhil5", "xhu4", "x3i", "xi5a", "xi5c", "xi5di", "x4ime", "xi5miz", "x3o", "x4ob", "x3p", "xpan4d", "xpecto5", "xpe3d", + "x1t2", "x3ti", "x1u", "xu3a", "xx4", "y5ac", "3yar4", "y5at", "y1b", "y1c", "y2ce", "yc5er", "y3ch", "ych4e", "ycom4", "ycot4", + "y1d", "y5ee", "y1er", "y4erf", "yes4", "ye4t", "y5gi", "4y3h", "y1i", "y3la", "ylla5bl", "y3lo", "y5lu", "ymbol5", "yme4", + "ympa3", "yn3chr", "yn5d", "yn5g", "yn5ic", "5ynx", "y1o4", "yo5d", "y4o5g", "yom4", "yo5net", "y4ons", "y4os", "y4ped", + "yper5", "yp3i", "y3po", "y4poc", "yp2ta", "y5pu", "yra5m", "yr5ia", "y3ro", "yr4r", "ys4c", "y3s2e", "ys3ica", "ys3io", + "3ysis", "y4so", "yss4", "ys1t", "ys3ta", "ysur4", "y3thin", "yt3ic", "y1w", "za1", "z5a2b", "zar2", "4zb", "2ze", "ze4n", + "ze4p", "z1er", "ze3ro", "zet4", "2z1i", "z4il", "z4is", "5zl", "4zm", "1zo", "zo4m", "zo5ol", "zte4", "4z1z2", "z4zy" + ] ++ + -- Extra patterns, from ushyphmax.tex, dated 2005-05-30. + -- Copyright (C) 1990, 2004, 2005 Gerard D.C. Kuiken. + -- Copying and distribution of this file, with or without modification, + -- are permitted in any medium without royalty provided the copyright + -- notice and this notice are preserved. + -- + -- These patterns are based on the Hyphenation Exception Log + -- published in TUGboat, Volume 10 (1989), No. 3, pp. 337-341, + -- and a large number of incorrectly hyphenated words not yet published. + [ + ".con5gr", ".de5riva", ".dri5v4", ".eth1y6l1", ".eu4ler", ".ev2", ".ever5si5b", ".ga4s1om1", ".ge4ome", + ".ge5ot1", ".he3mo1", ".he3p6a", ".he3roe", ".in5u2t", ".kil2n3i", ".ko6r1te1", ".le6ices", ".me4ga1l", + ".met4ala", ".mim5i2c1", ".mi1s4ers", ".ne6o3f", ".noe1th", ".non1e2m", ".poly1s", ".post1am", ".pre1am", + ".rav5en1o", ".semi5", ".sem4ic", ".semid6", ".semip4", ".semir4", ".sem6is4", ".semiv4", ".sph6in1", + ".spin1o", ".ta5pes1tr", ".te3legr", ".to6pog", ".to2q", ".un3at5t", ".un5err5", ".vi2c3ar", ".we2b1l", + ".re1e4c", "a5bolic", "a2cabl", "af6fish", "am1en3ta5b", "anal6ys", "ano5a2c", "ans5gr", "ans3v", "anti1d", + "an3ti1n2", "anti1re", "a4pe5able", "ar3che5t", "ar2range", "as5ymptot", "ath3er1o1s", "at6tes.", + "augh4tl", "au5li5f", "av3iou", "back2er.", "ba6r1onie", "ba1thy", "bbi4t", "be2vie", "bi5d2if", "bil2lab", + "bio5m", "bi1orb", "bio1rh", "b1i3tive", "blan2d1", "blin2d1", "blon2d2", "bor1no5", "bo2t1u1l", "brus4q", + "bus6i2er", "bus6i2es", "buss4ing", "but2ed.", "but4ted", "cad5e1m", "cat1a1s2", "4chs.", "chs3hu", "chie5vo", + "cig3a3r", "cin2q", "cle4ar", "co6ph1o3n", "cous2ti", "cri3tie", "croc1o1d", "cro5e2co", "c2tro3me6c", + "1cu2r1ance", "2d3alone", "data1b", "dd5a5b", "d2d5ib", "de4als.", "de5clar1", "de2c5lina", "de3fin3iti", + "de2mos", "des3ic", "de2tic", "dic1aid", "dif5fra", "3di1methy", "di2ren", "di2rer", "2d1lead", "2d1li2e", + "3do5word", "dren1a5l", "drif2t1a", "d1ri3pleg5", "drom3e5d", "d3tab", "du2al.", "du1op1o1l", "ea4n3ies", + "e3chas", "edg1l", "ed1uling", "eli2t1is", "e1loa", "en1dix", "eo3grap", "1e6p3i3neph1", "e2r3i4an.", + "e3spac6i", "eth1y6l1ene", "5eu2clid1", "feb1rua", "fermi1o", "3fich", "fit5ted.", "fla1g6el", "flow2er.", + "3fluor", "gen2cy.", "ge3o1d", "ght1we", "g1lead", "get2ic.", "4g1lish", "5glo5bin", "1g2nac", "gnet1ism", + "gno5mo", "g2n1or.", "g2noresp", "2g1o4n3i1za", "graph5er.", "griev1", "g1utan", "hair1s", "ha2p3ar5r", + "hatch1", "hex2a3", "hite3sid", "h3i5pel1a4", "hnau3z", "ho6r1ic.", "h2t1eou", "hypo1tha", "id4ios", + "ifac1et", "ign4it", "ignit1er", "i4jk", "im3ped3a", "infra1s2", "i5nitely.", "irre6v3oc", "i1tesima", + "ith5i2l", "itin5er5ar", "janu3a", "japan1e2s", "je1re1m", "1ke6ling", "1ki5netic", "1kovian", "k3sha", + "la4c3i5e", "lai6n3ess", "lar5ce1n", "l3chai", "l3chil6d1", "lead6er.", "lea4s1a", "1lec3ta6b", + "le3g6en2dre", "1le1noid", "lith1o5g", "ll1fl", "l2l3ish", "l5mo3nell", "lo1bot1o1", "lo2ges.", "load4ed.", + "load6er.", "l3tea", "lth5i2ly", "lue1p", "1lunk3er", "1lum5bia.", "3lyg1a1mi", "ly5styr", "ma1la1p", "m2an.", + "man3u1sc", "mar1gin1", "medi2c", "med3i3cin", "medio6c1", "me3gran3", "m2en.", "3mi3da5b", "3milita", + "mil2l1ag", "mil5li5li", "mi6n3is.", "mi1n2ut1er", "mi1n2ut1est", "m3ma1b", "5maph1ro1", "5moc1ra1t", + "mo5e2las", "mol1e5c", "mon4ey1l", "mono3ch", "mo4no1en", "moro6n5is", "mono1s6", "moth4et2", "m1ou3sin", + "m5shack2", "mu2dro", "mul2ti5u", "n3ar4chs.", "n3ch2es1t", "ne3back", "2ne1ski", "n1dieck", "nd3thr", + "nfi6n3ites", "4n5i4an.", "nge5nes", "ng1ho", "ng1spr", "nk3rup", "n5less", "5noc3er1os", "nom1a6l", + "nom5e1no", "n1o1mist", "non1eq", "non1i4so", "5nop1oly.", "no1vemb", "ns5ceiv", "ns4moo", "ntre1p", + "obli2g1", "o3chas", "odel3li", "odit1ic", "oerst2", "oke1st", "o3les3ter", "oli3gop1o1", "o1lo3n4om", + "o3mecha6", "onom1ic", "o3norma", "o3no2t1o3n", "o3nou", "op1ism.", "or4tho3ni4t", "orth1ri", "or5tively", + "o4s3pher", "o5test1er", "o5tes3tor", "oth3e1o1s", "ou3ba3do", "o6v3i4an.", "oxi6d1ic", "pal6mat", + "parag6ra4", "par4a1le", "param4", "para3me", "pee2v1", "phi2l3ant", "phi5lat1e3l", "pi2c1a3d", "pli2c1ab", + "pli5nar", "poin3ca", "1pole.", "poly1e", "po3lyph1ono", "1prema3c", "pre1neu", "pres2pli", "pro2cess", + "proc3i3ty.", "pro2g1e", "3pseu2d", "pseu3d6o3d2", "pseu3d6o3f2", "pto3mat4", "p5trol3", "pu5bes5c", + "quain2t1e", "qu6a3si3", "quasir6", "quasis6", "quin5tes5s", "qui3v4ar", "r1abolic", "3rab1o1loi", + "ra3chu", "r3a3dig", "radi1o6g", "r2amen", "3ra4m5e1triz", "ra3mou", "ra5n2has", "ra1or", "r3bin1ge", + "re2c3i1pr", "rec5t6ang", "re4t1ribu", "r3ial.", "riv1o1l", "6rk.", "rk1ho", "r1krau", "6rks.", "r5le5qu", + "ro1bot1", "ro5e2las", "ro5epide1", "ro3mesh", "ro1tron", "r3pau5li", "rse1rad1i", "r1thou", "r1treu", + "r1veil", "rz1sc", "sales3c", "sales5w", "5sa3par5il", "sca6p1er", "sca2t1ol", "s4chitz", "schro1ding1", + "1sci2utt", "scrap4er.", "scy4th1", "sem1a1ph", "se3mes1t", "se1mi6t5ic", "sep3temb", "shoe1st", "sid2ed.", + "side5st", "side5sw", "si5resid", "sky1sc", "3slova1kia", "3s2og1a1my", "so2lute", "3s2pace", "1s2pacin", + "spe3cio", "spher1o", "spi2c1il", "spokes5w", "sports3c", "sports3w", "s3qui3to", "s2s1a3chu1", "ss3hat", + "s2s3i4an.", "s5sign5a3b", "1s2tamp", "s2t1ant5shi", "star3tli", "sta1ti", "st5b", "1stor1ab", "strat1a1g", + "strib5ut", "st5scr", "stu1pi4d1", "styl1is", "su2per1e6", "1sync", "1syth3i2", "swimm6", "5tab1o1lism", + "ta3gon.", "talk1a5", "t1a1min", "t6ap6ath", "5tar2rh", "tch1c", "tch3i1er", "t1cr", "teach4er.", "tele2g", + "tele1r6o", "3ter1gei", "ter2ic.", "t3ess2es", "tha4l1am", "tho3don", "th1o5gen1i", "tho1k2er", "thy4l1an", + "thy3sc", "2t3i4an.", "ti2n3o1m", "t1li2er", "tolo2gy", "tot3ic", "trai3tor1", "tra1vers", "travers3a3b", + "treach1e", "tr4ial.", "3tro1le1um", "trof4ic.", "tro3fit", "tro1p2is", "3trop1o5les", "3trop1o5lis", + "t1ro1pol3it", "tsch3ie", "ttrib1ut1", "turn3ar", "t1wh", "ty2p5al", "ua3drati", "uad1ratu", "u5do3ny", + "uea1m", "u2r1al.", "uri4al.", "us2er.", "v1ativ", "v1oir5du1", "va6guer", "vaude3v", "1verely.", "v1er1eig", + "ves1tite", "vi1vip3a3r", "voice1p", "waste3w6a2", "wave1g4", "w3c", "week1n", "wide5sp", "wo4k1en", + "wrap3aro", "writ6er.", "x1q", "xquis3", "y5che3d", "ym5e5try", "y1stro", "yes5ter1y", "z3ian.", "z3o1phr", + "z2z3w" + ] addfile ./Graphics/PDF/Hyphenate/LowLevel.hs hunk ./Graphics/PDF/Hyphenate/LowLevel.hs 1 - +--------------------------------------------------------- +-- | +-- Copyright : (c) alpha 2006 +-- License : BSD-style +-- +-- Maintainer : misc@NOSPAMalpheccar.org +-- Stability : experimental +-- Portability : portable +-- +-- Low level functions for hyphenation +--------------------------------------------------------- +-- #hide +module Graphics.PDF.Hyphenate.LowLevel ( + HyphenationDatabase(..) + , mkExceptions + , mkPatterns + , mkCustomLanguage + ) + where + +import qualified Graphics.PDF.Data.Trie as T +import Graphics.PDF.Data.Trie(MapString) +import Data.Char(isDigit) +import Data.List(unfoldr) + +-- | Hyphenation databases +data HyphenationDatabase = English (Maybe (MapString [Int])) + | CustomLanguage (MapString [Int]) (MapString [Int]) + + + +mkExceptions :: [String] -> T.MapString [Int] +mkExceptions = T.fromList . map createException + where + createException x = (removeHyphen x,exceptionPoints x) + +mkPatterns :: [String] -> T.MapString [Int] +mkPatterns = T.fromList . map convertPattern + +-- | Create a custom language for hyphenation +mkCustomLanguage :: [String] -- ^ Exceptions + -> [String] -- ^ Patterns + -> HyphenationDatabase +mkCustomLanguage e p = CustomLanguage (mkExceptions e) (mkPatterns p) + +-- | Is it a char used in hyphenation pattern +isChar :: Char -> Bool +isChar = not . isDigit + +-- | Get numerical value for a char +fromDigit :: Char -> Int +fromDigit c = fromEnum c - fromEnum '0' + +-- | Convert a char from an hyphenation pattern to a number +toNumber :: Char -> Int +toNumber x = if isChar x then 0 else fromDigit x + +-- | Remove 0 contained between numbers +simplify :: [Int] -> [Int] +simplify (a:b:c:l) | a /= 0 && b == 0 && c /= 0 = a:simplify (c:l) + | otherwise = a:simplify (b:c:l) +simplify a = a + +-- | Split a patterns into a list of numbers +split :: (Char -> Bool) -> String -> [Int] +split f = simplify . map toNumber . unfoldr (split' f) + +split' :: (Char -> Bool) -> String -> Maybe (Char, String) +split' f l | null l = Nothing + | otherwise = if null h then Just (' ', drop 1 t) else Just (head h, t) + where (h, t) = span f l + +-- | Convert a pattern into a list of number and a normal word +convertPattern :: String -> (String,[Int]) +convertPattern s = + let s' = filter isChar s + p = split isDigit s + in + (s',p) + +-- | Remove hyphens from an excepyion word +removeHyphen :: String -> String +removeHyphen = filter ((/=) '-') + +-- | Get exception points +exceptionPoints :: String -> [Int] +exceptionPoints s = 0 : map onlyHyphen s + where + onlyHyphen '-' = 1 + onlyHyphen _ = 0 hunk ./HPDF.cabal 46 + Graphics.PDF.Hyphenate hunk ./HPDF.cabal 50 + Graphics.PDF.Data.Trie hunk ./HPDF.cabal 54 + Graphics.PDF.Hyphenate.English + Graphics.PDF.Hyphenate.LowLevel hunk ./LICENSE 27 - +* +* For hyphenation see files in Graphics/PDF/Hyphenate +* +* Extra patterns, from ushyphmax.tex, dated 2005-05-30. +* -- Copyright (C) 1990, 2004, 2005 Gerard D.C. Kuiken. hunk ./Graphics/PDF/Hyphenate.hs 79 - cutFromList [] (zip s p) + if length s <= 4 then [s] else cutFromList [] (zip s p) hunk ./Graphics/PDF/Typesetting/Breaking.hs 46 +import Graphics.PDF.Hyphenate hunk ./Graphics/PDF/Typesetting/Breaking.hs 226 + , hyphenation :: !HyphenationDatabase -- ^ Default value English hunk ./Graphics/PDF/Typesetting/Breaking.hs 230 -defaultBreakingSettings = BRState 100 200 50 10000 10000 10 FullJustification +defaultBreakingSettings = BRState 100 200 50 10000 10000 10 FullJustification (English Nothing) hunk ./Graphics/PDF/Typesetting/Breaking.hs 305 --- | Create an hyphen penalty -hyphenPenalty :: BRState - -> s -- ^ Style of future hyphen - -> PDFFloat -- ^ Size of hyphen taking into account the kerning that was perturbed by the hyphen introduction. The char before the hyphen is now bigger - -> Letter s -hyphenPenalty settings s w = FlaggedPenalty w (hyphenPenaltyValue settings) s hunk ./Graphics/PDF/Typesetting/Breaking.hs 489 - error "Breakpoint marked as flagged but detected as not flagged ! Send a bug report !" + error $ "Breakpoint marked as flagged but detected as not flagged ! Send a bug report ! " ++ show theLine ++ " " ++ show t' hunk ./Graphics/PDF/Typesetting/Breaking.hs 589 -createLetterBoxes settings s ((wa,'.'):b@(_,bc):l') | bc /= ' ' = (createChar s wa '.') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s (b:l') )) - | otherwise = (createChar s wa '.') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s l')) -createLetterBoxes settings s ((wa,','):b@(_,bc):l') | bc /= ' ' = (createChar s wa ',') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s (b:l') )) - | otherwise = (createChar s wa ',') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s l')) -createLetterBoxes settings s ((wa,';'):b@(_,bc):l') | bc /= ' ' = (createChar s wa ';') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s (b:l') )) - | otherwise = (createChar s wa ';') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s l')) -createLetterBoxes settings s ((wa,'!'):b@(_,bc):l') | bc /= ' ' = (createChar s wa '!') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s (b:l') )) - | otherwise = (createChar s wa '!') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s l')) -createLetterBoxes settings s ((wa,'?'):b@(_,bc):l') | bc /= ' ' = (createChar s wa '?') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s (b:l') )) - | otherwise = (createChar s wa '?') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s l')) -createLetterBoxes settings s ((wa,':'):b@(_,bc):l') | bc /= ' ' = (createChar s wa ':') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s (b:l') )) - | otherwise = (createChar s wa ':') : ((spaceGlueBox settings s 2.0) ++ (createLetterBoxes settings s l')) - hunk ./Graphics/PDF/Typesetting/Breaking.hs 593 --- | split a line into boxes +-- | split a line into boxes and add hyphen where needed hunk ./Graphics/PDF/Typesetting/Breaking.hs 595 -splitText settings f t = createLetterBoxes settings f . ripText (textFont . textStyle $ f) $ t +splitText settings f t = wordToLetters t + where + wordToLetters = createLetterBoxes settings f . ripText (textFont . textStyle $ f) + +-- | Create an hyphen penalty +hyphenPenalty :: BRState + -> s -- ^ Style of future hyphen + -> PDFFloat -- ^ Size of hyphen taking into account the kerning that was perturbed by the hyphen introduction. The char before the hyphen is now bigger + -> Letter s +hyphenPenalty settings s w = FlaggedPenalty w (hyphenPenaltyValue settings) s hunk ./Graphics/PDF/Typesetting.hs 101 +import Graphics.PDF.Hyphenate +import Data.List(unfoldr,intersperse) +import Data.Char(isSpace) hunk ./Graphics/PDF/Typesetting.hs 320 + +myWords' :: String -> Maybe (String, String) +myWords' l | null l = Nothing + | otherwise = if null h then Just (h', t') else Just (" ", t) + where + (h, t) = span isSpace l + (h', t') = span (not . isSpace) l + +-- | Split a sentence into words keeping the space but shortening them to 1 space +myWords :: String -> [String] +myWords = unfoldr myWords' + +addHyphens :: HyphenationDatabase -> String -> PDFString +addHyphens db f = toPDFString . concat . map (concat . intersperse "/-" . hyphenate db) . myWords $ f hunk ./Graphics/PDF/Typesetting.hs 340 - tell $ splitText settings f (toPDFString t) + tell $ splitText settings f (addHyphens (hyphenation settings) t) hunk ./Test/test.hs 306 +blogText :: TM StandardParagraphStyle StandardStyle () +blogText = do + paragraph $ do + txt $ "Photos and video courtesy of " + txt $ "www.cutsewandblog.com" + txt $ "." + hunk ./Test/test.hs 315 - let c = mkContainer 10 300 200 90 - (d,c',r) = fillContainer (defaultVerState NormalParagraph) c . getBoxes NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ testText - cb = mkContainer 10 210 200 210 + let c = mkContainer 10 300 100 90 + (d,c',r) = fillContainer (defaultVerState NormalParagraph) c . getBoxes NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ blogText + cb = mkContainer 10 210 100 210 hunk ./Test/test.hs 377 - txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor " + txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor" hunk ./Test/test.hs 379 - txt $ "incididunt ut labore et dolore magna aliqua. " + txt $ " incididunt ut labore et dolore magna aliqua. " hunk ./Graphics/PDF/Typesetting/Breaking.hs 221 - , hyphenPenaltyValue :: !Int -- ^ Default value 50 + , hyphenPenaltyValue :: !Int -- ^ Default value 10 hunk ./Graphics/PDF/Typesetting/Breaking.hs 230 -defaultBreakingSettings = BRState 100 200 50 10000 10000 10 FullJustification (English Nothing) +defaultBreakingSettings = BRState 100 200 10 10000 10000 10 FullJustification (English Nothing) hunk ./Graphics/PDF/Typesetting/Breaking.hs 467 -cutList :: Style s => [Letter s] -> Int -> [(PDFFloat,Int,Bool)] -> [(PDFFloat,[Letter s],[Letter s])] -cutList [] _ _ = [] -cutList t _ [] = [(0.0,[],t)] -cutList t c ((ra,ba,fa):l) = +cutList :: Style s => Justification -> [Letter s] -> Int -> [(PDFFloat,Int,Bool)] -> [(PDFFloat,[Letter s],[Letter s])] +cutList _ [] _ _ = [] +cutList _ t _ [] = [(0.0,[],t)] +cutList j t c ((ra,ba,fa):l) = hunk ./Graphics/PDF/Typesetting/Breaking.hs 486 - (ra,theLine ++ [hyphenBox s],t) : cutList t' ba l + (ra,theLine ++ hyphenForJustification j s,t) : cutList j t' ba l hunk ./Graphics/PDF/Typesetting/Breaking.hs 491 - (ra,theLine,t) : cutList t' ba l + (ra,theLine,t) : cutList j t' ba l hunk ./Graphics/PDF/Typesetting/Breaking.hs 501 - cutList boxes 1 theBreaks + cutList (centered settings) boxes 1 theBreaks hunk ./Graphics/PDF/Typesetting/Breaking.hs 552 - FullJustification -> [Glue (ws*h) (h*sy*ws/2.0*f) (h*sz*ws/3.0) (Just s)] + FullJustification -> [Glue normalW (normalW*sy/2.0*f) (normalW*sz/3.0) (Just s)] hunk ./Graphics/PDF/Typesetting/Breaking.hs 569 +spaceSize :: Style s => s -- ^ The style + -> PDFFloat +spaceSize s = + let ws = (textWidth (textFont . textStyle $ s) (toPDFString " ") ) + h = scaleSpace . textStyle $ s + in ws * h + + +hyphenForJustification :: Style s => Justification -> s -> [Letter s] +hyphenForJustification Centered s = [hyphenBox s,Glue 0 (centeredDilatationFactor*spaceSize s) 0 (Just s)] +hyphenForJustification LeftJustification s = [hyphenBox s,Glue 0 (leftDilatationFactor*spaceSize s) 0 (Just s)] +hyphenForJustification _ s = [hyphenBox s] + hunk ./Test/test.hs 306 -blogText :: TM StandardParagraphStyle StandardStyle () -blogText = do - paragraph $ do - txt $ "Photos and video courtesy of " - txt $ "www.cutsewandblog.com" - txt $ "." hunk ./Test/test.hs 310 - (d,c',r) = fillContainer (defaultVerState NormalParagraph) c . getBoxes NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ blogText + (d,c',r) = fillContainer (defaultVerState NormalParagraph) c . getBoxes NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ testText hunk ./Graphics/PDF/Hyphenate.hs 69 - let p = drop 1 . lastPointIsNull . getWordPoints db $ s - lastPointIsNull l = let (h,t) = splitAt 1 (reverse l) in reverse (head h:0:drop 1 t) + let p = 0:0:(drop 2. drop 1 . lastPointIsNull . getWordPoints db $ s) + lastPointIsNull l = let (_,t) = splitAt 2 (reverse l) in reverse (0:0:t) hunk ./Graphics/PDF/Typesetting/Breaking.hs 38 + , simplify hunk ./Graphics/PDF/Typesetting/Breaking.hs 221 - , secondPassTolerance :: !PDFFloat -- ^ Default value 200 - , hyphenPenaltyValue :: !Int -- ^ Default value 10 - , fitness_demerit :: !PDFFloat -- ^ Default value 10000 - , flagged_demerit :: !PDFFloat -- ^ Default value 10000 + , secondPassTolerance :: !PDFFloat -- ^ Default value 100 + , hyphenPenaltyValue :: !Int -- ^ Default value 50 + , fitness_demerit :: !PDFFloat -- ^ Default value 1000 + , flagged_demerit :: !PDFFloat -- ^ Default value 1000 hunk ./Graphics/PDF/Typesetting/Breaking.hs 231 -defaultBreakingSettings = BRState 100 200 10 10000 10000 10 FullJustification (English Nothing) +defaultBreakingSettings = BRState 100 100 50 1000 1000 10 FullJustification (English Nothing) hunk ./Graphics/PDF/Typesetting/Breaking.hs 235 -computeDemerit :: BRState +computeDemerit :: Bool + -> BRState hunk ./Graphics/PDF/Typesetting/Breaking.hs 242 -computeDemerit settings sndPass r a z = +computeDemerit force settings sndPass r a z = hunk ./Graphics/PDF/Typesetting/Breaking.hs 248 - if (b <= tolerance) || sndPass + if (b <= tolerance) || force -- || sndPass hunk ./Graphics/PDF/Typesetting/Breaking.hs 252 - dem = max 1000.0 $ if p >= 0 + dem = min 100000.0 $ if p >= 0 hunk ./Graphics/PDF/Typesetting/Breaking.hs 271 ---currentLetter :: ZList s -> [Letter s] ---currentLetter (ZList (OneCB (_,_,_,_,s)) (_,_,_,_,a) _) = [s,a] ---currentLetter (ZList _ (_,_,_,_,a) _) = [a] +-- Used for debugging only +--currentLetter :: ZList s -> Letter s +--currentLetter (ZList _ (_,_,_,_,a) _) = a hunk ./Graphics/PDF/Typesetting/Breaking.hs 354 - -> (PDFFloat -> ActiveNodes -> (PossibleBreak,ActiveNodes)) + -> (Bool -> PDFFloat -> ActiveNodes -> (PossibleBreak,ActiveNodes)) hunk ./Graphics/PDF/Typesetting/Breaking.hs 357 - if r < -1 - then - --if Map.size newmap > 1 then (newbreak,Map.delete key newmap) else f (-0.99) (Map.delete key newmap) - if sndPass - then - f (-0.99) (Map.delete key newmap) - else - (newbreak,Map.delete key newmap) - else if isForcedBreak z - then - f r (Map.delete key newmap) - else - f r newmap + if isForcedBreak z + then + f True r (Map.delete key newmap) + else + if r < -1 + then let m' = Map.delete key newmap + in + if Map.null m' && sndPass then f True (-0.99) m' else (newbreak,m') + else + f False r newmap hunk ./Graphics/PDF/Typesetting/Breaking.hs 373 ---breakTrace b z r' p = trace (debug b z ++ " " ++ show r' ++ " " ++ show (currentLetter z) ++ " " ++ show (position z) ++ " -> " ++ show p) +--breakTrace sndPass b z r' p = trace ("SndPass :" ++ show sndPass ++ " " ++ debug b z ++ " " ++ show r' ++ " " ++ show (currentLetter z) ++ " " ++ show (position z) ++ " -> " ++ show p) hunk ./Graphics/PDF/Typesetting/Breaking.hs 381 - in + in -- breakTrace sndPass b z r' p $ hunk ./Graphics/PDF/Typesetting/Breaking.hs 383 - \r newmap -> let dem' = computeDemerit settings sndPass r b z in + \force r newmap -> let dem' = computeDemerit force settings sndPass r b z in hunk ./Graphics/PDF/Typesetting/Breaking.hs 410 -analyzeBoxes :: BRState -> Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList s -> [(PDFFloat,Int,Bool)] -analyzeBoxes settings pass fmaxw actives z = +analyzeBoxes :: BRState -> Bool -> (Int -> PDFFloat) -> ActiveNodes -> ZList s -> ZList s -> [(PDFFloat,Int,Bool)] +analyzeBoxes settings pass fmaxw actives lastz z = hunk ./Graphics/PDF/Typesetting/Breaking.hs 428 - analyzeBoxes settings True fmaxw actives z + analyzeBoxes settings True fmaxw actives lastz lastz hunk ./Graphics/PDF/Typesetting/Breaking.hs 440 - someNewBreaks ++ analyzeBoxes settings pass fmaxw (Map.insert (getKey minBreak) (getNode minBreak) Map.empty) (moveRight z) + let z' = moveRight z in + someNewBreaks ++ analyzeBoxes settings pass fmaxw (Map.insert (getKey minBreak) (getNode minBreak) Map.empty) z' z' hunk ./Graphics/PDF/Typesetting/Breaking.hs 450 - analyzeBoxes settings pass fmaxw actives' (moveRight z) + analyzeBoxes settings pass fmaxw actives' lastz (moveRight z) hunk ./Graphics/PDF/Typesetting/Breaking.hs 460 - analyzeBoxes settings pass fmaxw newActives (moveRight z) + analyzeBoxes settings pass fmaxw newActives lastz (moveRight z) hunk ./Graphics/PDF/Typesetting/Breaking.hs 499 - theBreaks = analyzeBoxes settings False maxw active (createZList boxes) + z = createZList boxes + theBreaks = analyzeBoxes settings False maxw active z z hunk ./Graphics/PDF/Typesetting/Breaking.hs 576 - + +-- | When a paragraph is full and we start a new one we must clean the beginning paragraph and remove what has been left by the +-- broken space +simplify :: [Letter s] + -> [Letter s] +simplify [] = [] +simplify ((Glue _ _ _ _):l) = simplify l +simplify ((FlaggedPenalty _ _ _):l) = simplify l +simplify ((Penalty _):l) = simplify l +simplify l = l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 73 - --- Remove glues and penalties at the beginning of a line -simplify :: ComparableStyle s => PDFFloat -- ^ Adjustement ratio - -> [Letter s] -- ^ List of letters - -> [HBox s] -- ^ List of words or sentence -simplify r ((Glue _ _ _ _):l) = simplify r l -simplify r ((FlaggedPenalty _ _ _):l) = simplify r l -simplify r ((Penalty _):l) = simplify r l -simplify r l = createWords r Nothing l hunk ./Graphics/PDF/Typesetting/Horizontal.hs 78 -horizontalPostProcess ((r,l',r'):l) = let l'' = simplify r l' in +horizontalPostProcess ((r,l',r'):l) = let l'' = createWords r Nothing . simplify $ l' in hunk ./Graphics/PDF/Typesetting/Vertical.hs 102 -createPara lineOffset style paraSettings l = [Paragraph lineOffset l style paraSettings] +createPara lineOffset style paraSettings l = [Paragraph lineOffset (simplify l) style paraSettings] hunk ./Test/test.hs 20 - hunk ./Test/test.hs 306 -containerTest :: PDFReference PDFPage -> PDF () -containerTest p = - let c = mkContainer 10 300 100 90 - (d,c',r) = fillContainer (defaultVerState NormalParagraph) c . getBoxes NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ testText - cb = mkContainer 10 210 100 210 +containerTest :: PDFReference PDFPage -> Rectangle ->( TM StandardParagraphStyle StandardStyle ()) -> PDF () +containerTest p (Rectangle xa ya xb yb) theText = + let c = mkContainer xa ya xb yb + (d,c',r) = fillContainer (defaultVerState NormalParagraph) c . getBoxes NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + theText + cb = mkContainer xa (ya-100) xb yb hunk ./Test/test.hs 319 - h = containerHeight c' + --h = containerHeight c' hunk ./Test/test.hs 321 - stroke $ Rectangle x y (x+w) (y-h) + stroke $ Rectangle x y (x+w) (ya-100-yb) hunk ./Test/test.hs 340 + --txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit" hunk ./Test/test.hs 487 + fillColor blue hunk ./Test/test.hs 549 - + hunk ./Test/test.hs 551 + hunk ./Test/test.hs 553 - containerTest page3c + containerTest page3c (Rectangle 10 300 100 100) testText + containerTest page3c (Rectangle 210 300 200 100) $ do + setJustification Centered + testText hunk ./Graphics/PDF/Typesetting/Breaking.hs 252 - dem = min 100000.0 $ if p >= 0 + dem = max 1000.0 $ if p >= 0 hunk ./Graphics/PDF/Typesetting/Breaking.hs 365 - else + else hunk ./Graphics/PDF/Typesetting/Breaking.hs 414 - newActives = Map.union breaks' actives' - getRightOrderNodeList = tail . reverse . genNodeList + newActives = Map.union (breaks') (actives') + getRightOrderNodeList = reverse . genNodeList hunk ./Graphics/PDF/Typesetting/Breaking.hs 447 - then + then hunk ./Graphics/PDF/Typesetting/Breaking.hs 500 - theBreaks = analyzeBoxes settings False maxw active z z + theBreaks = tail $ analyzeBoxes settings False maxw active z z hunk ./Graphics/PDF/Typesetting/Breaking.hs 502 - cutList (centered settings) boxes 1 theBreaks + cutList (centered settings) boxes 1 (theBreaks) hunk ./Test/test.hs 475 - strokeColor red - stroke $ Rectangle 10 200 (10+maxw) 300 - displayFormattedText ((Rectangle 10 200 (10+maxw) 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do - setJustification LeftJustification - testText - - strokeColor red - stroke $ Rectangle 10 100 (10+maxw) 200 - displayFormattedText ((Rectangle 10 100 (10+maxw) 200)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do - setJustification RightJustification - testText - strokeColor red - fillColor blue - stroke $ Rectangle 10 0 (10+maxw) 100 - drawText $ text (PDFFont Helvetica_Bold 24) 10 100 (toPDFString "Lorem ipsum") - stroke $ Line 10 120 (10 + textWidth (PDFFont Helvetica_Bold 24) (toPDFString "Lorem ipsum") ) 120 - displayFormattedText ((Rectangle 10 0 (10+maxw) 100)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do - setJustification LeftJustification - paragraph $ do - setStyle (Font (PDFFont Helvetica_Bold 24) black black) - txt $ "Lorem ipsum" + --strokeColor red + --stroke $ Rectangle 10 200 (10+maxw) 300 + --displayFormattedText ((Rectangle 10 200 (10+maxw) 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + -- setJustification LeftJustification + -- testText + -- + --strokeColor red + --stroke $ Rectangle 10 100 (10+maxw) 200 + --displayFormattedText ((Rectangle 10 100 (10+maxw) 200)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + -- setJustification RightJustification + -- testText + --strokeColor red + --fillColor blue + --stroke $ Rectangle 10 0 (10+maxw) 100 + --drawText $ text (PDFFont Helvetica_Bold 24) 10 100 (toPDFString "Lorem ipsum") + --stroke $ Line 10 120 (10 + textWidth (PDFFont Helvetica_Bold 24) (toPDFString "Lorem ipsum") ) 120 + --displayFormattedText ((Rectangle 10 0 (10+maxw) 100)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + -- setJustification LeftJustification + -- paragraph $ do + -- setStyle (Font (PDFFont Helvetica_Bold 24) black black) + -- txt $ "Lorem ipsum" hunk ./Test/test.hs 551 - + hunk ./Graphics/PDF/Typesetting/Breaking.hs 415 - getRightOrderNodeList = reverse . genNodeList + getRightOrderNodeList = tail . reverse . genNodeList hunk ./Graphics/PDF/Typesetting/Breaking.hs 500 - theBreaks = tail $ analyzeBoxes settings False maxw active z z + theBreaks = analyzeBoxes settings False maxw active z z hunk ./Graphics/PDF/Typesetting/Breaking.hs 502 - cutList (centered settings) boxes 1 (theBreaks) + cutList (centered settings) boxes 1 theBreaks hunk ./Test/test.hs 475 - --strokeColor red - --stroke $ Rectangle 10 200 (10+maxw) 300 - --displayFormattedText ((Rectangle 10 200 (10+maxw) 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do - -- setJustification LeftJustification - -- testText - -- - --strokeColor red - --stroke $ Rectangle 10 100 (10+maxw) 200 - --displayFormattedText ((Rectangle 10 100 (10+maxw) 200)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do - -- setJustification RightJustification - -- testText - --strokeColor red - --fillColor blue - --stroke $ Rectangle 10 0 (10+maxw) 100 - --drawText $ text (PDFFont Helvetica_Bold 24) 10 100 (toPDFString "Lorem ipsum") - --stroke $ Line 10 120 (10 + textWidth (PDFFont Helvetica_Bold 24) (toPDFString "Lorem ipsum") ) 120 - --displayFormattedText ((Rectangle 10 0 (10+maxw) 100)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do - -- setJustification LeftJustification - -- paragraph $ do - -- setStyle (Font (PDFFont Helvetica_Bold 24) black black) - -- txt $ "Lorem ipsum" + strokeColor red + stroke $ Rectangle 10 200 (10+maxw) 300 + displayFormattedText ((Rectangle 10 200 (10+maxw) 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + setJustification LeftJustification + testText + + strokeColor red + stroke $ Rectangle 10 100 (10+maxw) 200 + displayFormattedText ((Rectangle 10 100 (10+maxw) 200)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + setJustification RightJustification + testText + strokeColor red + fillColor blue + stroke $ Rectangle 10 0 (10+maxw) 100 + drawText $ text (PDFFont Helvetica_Bold 24) 10 100 (toPDFString "Lorem ipsum") + stroke $ Line 10 120 (10 + textWidth (PDFFont Helvetica_Bold 24) (toPDFString "Lorem ipsum") ) 120 + displayFormattedText ((Rectangle 10 0 (10+maxw) 100)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + setJustification LeftJustification + paragraph $ do + setStyle (Font (PDFFont Helvetica_Bold 24) black black) + txt $ "Lorem ipsum" hunk ./Test/test.hs 508 - + hunk ./Test/test.hs 551 - hunk ./Graphics/PDF/Shapes.hs 144 - addShape (Circle x0 y0 r) = stroke (Ellipse (x0-r) (y0-r) (x0+r) (y0+r) ) + addShape (Circle x0 y0 r) = addShape (Ellipse (x0-r) (y0-r) (x0+r) (y0+r) ) hunk ./Graphics/PDF/Typesetting/Breaking.hs 294 -createBreaknode prev z = createBreaknode prev (moveRight z) +createBreaknode prev z = + let BreakNode a b c d _ e f g = createBreaknode prev (moveRight z) in + BreakNode a b c d False e f g hunk ./Graphics/PDF/Typesetting/Breaking.hs 375 ---breakTrace sndPass b z r' p = trace ("SndPass :" ++ show sndPass ++ " " ++ debug b z ++ " " ++ show r' ++ " " ++ show (currentLetter z) ++ " " ++ show (position z) ++ " -> " ++ show p) +--breakTrace sndPass b z r' p = trace ("SndPass :" ++ show sndPass ++ " " +-- ++ debug b z ++ " " ++ show r' ++ " " +-- ++ show (currentLetter z) ++ " " +-- ++ show (position z) ++ " -> " +-- ++ show p +-- ++ if isFlagged z then " (Flagged)" else "" +-- ) hunk ./Graphics/PDF/Typesetting/Breaking.hs 497 - error $ "Breakpoint marked as flagged but detected as not flagged ! Send a bug report ! " ++ show theLine ++ " " ++ show t' + error $ "Breakpoint marked as flagged but detected as not flagged ! Send a bug report ! " ++ show (ra,ba,fa) ++ " " ++ show theLine ++ " " ++ show t' hunk ./Test/test.hs 394 - par :: Para MyParaStyles () hunk ./Test/test.hs 395 - txt $ "Lor/-em ip/-sum do/-lor sit am/-et, con/-se/-cte/-tur adi/-pi/-si/-cing el/-it, sed do eius/-mod tem/-por inci/-di/-dunt ut lab/-ore et do/-lo/-re ma/-gna ali/-qua. " - txt $ "Ut en/-im ad mi/-nim ven/-iam, quis no/-strud ex/-er/-ci/-ta/-tion ul/-lam/-co labo/-ris ni/-si ut ali/-quip ex ea com/-mo/-do con/-se/-quat. Duis au/-te ir/-ure " - txt $ "do/-lor in re/-pre/-hen/-der/-it in vo/-lup/-ta/-te ve/-lit es/-se cil/-lum do/-lo/-re eu fu/-giat nul/-la pa/-ria/-tur. Ex/-cep/-teur sint oc/-cae/-cat cu/-pi/-da/-tat non " - txt $ "pro/-id/-ent, sunt in cul/-pa qui of/-fi/-cia de/-se/-runt mol/-lit anim id est la/-bo/-rum." + txt $ "Despite the trip to a rather unseemly part of " + txt $ "Paris, it was well worth it. I bumped into Guido, Parisian " + txt $ "boutique L'Eclaireur's most stylish salesperson, whose " + txt $ "presence confirmed the ultra hip factor of the crowd in " + txt $ "attendance. The performances were strong and varied, " + txt $ "and the experience of tapping into the Burlesque " + txt $ "renaissance /--/-- mixed in with a little business of " + txt $ "fashion /--/-- was a great lesson learned on how to throw " + txt $ "an authentic fashion event. " + hunk ./Test/test.hs 447 - stroke $ Line 10 300 (10+maxw) 300 - displayFormattedText (Rectangle 10 0 (10+maxw) 300) NormalPara Normal simpleText + stroke $ Line 10 300 (10+100) 300 + displayFormattedText (Rectangle 10 0 (10+100) 300) NormalPara Normal simpleText + hunk ./Graphics/PDF/Typesetting/Layout.hs 35 + , containerParaTolerance hunk ./Graphics/PDF/Typesetting/Layout.hs 121 --- | Container for vboxes (x,y,width,maxheight,height,currenty,current z) -data Container ps s = Container PDFFloat PDFFloat Width PDFFloat PDFFloat PDFFloat PDFFloat [VBox ps s] +-- | Container for vboxes (x,y,width,maxheight,height,currenty,current z, tolerance para) +-- tolerance para means a paragraph is not started if too close from the bottom edge of the box +data Container ps s = Container PDFFloat PDFFloat Width PDFFloat PDFFloat PDFFloat PDFFloat PDFFloat [VBox ps s] hunk ./Graphics/PDF/Typesetting/Layout.hs 130 + -> PDFFloat -- ^ Pargraph tolerance hunk ./Graphics/PDF/Typesetting/Layout.hs 132 -mkContainer x y width height = Container x y width height 0 0 0 [] +mkContainer x y width height tol = Container x y width height 0 0 0 tol [] hunk ./Graphics/PDF/Typesetting/Layout.hs 136 -containerWidth (Container _ _ w _ _ _ _ _) = w +containerWidth (Container _ _ w _ _ _ _ _ _) = w + +-- | Get the width of the container +containerParaTolerance :: Container ps s -> PDFFloat +containerParaTolerance (Container _ _ _ _ _ _ _ t _) = t hunk ./Graphics/PDF/Typesetting/Layout.hs 144 -containerHeight (Container _ _ _ h _ _ _ _) = h +containerHeight (Container _ _ _ h _ _ _ _ _) = h hunk ./Graphics/PDF/Typesetting/Layout.hs 148 -containerCurrentHeight (Container _ _ _ _ ch _ _ _) = ch +containerCurrentHeight (Container _ _ _ _ ch _ _ _ _) = ch hunk ./Graphics/PDF/Typesetting/Layout.hs 152 -containerContentHeight (Container _ _ _ maxh h y z _) = let r = min (dilatationRatio maxh h y z) 2.0 in +containerContentHeight (Container _ _ _ maxh h y z _ _) = let r = min (dilatationRatio maxh h y z) 2.0 in hunk ./Graphics/PDF/Typesetting/Layout.hs 157 -containerContentLeftBorder (Container _ _ _ _ _ _ _ []) = 0.0 -containerContentLeftBorder (Container _ _ _ _ _ _ _ l) = minimum . map getBoxDelta $ l +containerContentLeftBorder (Container _ _ _ _ _ _ _ _ []) = 0.0 +containerContentLeftBorder (Container _ _ _ _ _ _ _ _ l) = minimum . map getBoxDelta $ l hunk ./Graphics/PDF/Typesetting/Layout.hs 162 -containerContentRightBorder (Container _ _ _ _ _ _ _ []) = 0.0 -containerContentRightBorder (Container _ _ _ _ _ _ _ l) = +containerContentRightBorder (Container _ _ _ _ _ _ _ _ []) = 0.0 +containerContentRightBorder (Container _ _ _ _ _ _ _ _ l) = hunk ./Graphics/PDF/Typesetting/Layout.hs 171 -containerX (Container x _ _ _ _ _ _ _) = x +containerX (Container x _ _ _ _ _ _ _ _) = x hunk ./Graphics/PDF/Typesetting/Layout.hs 175 -containerY (Container _ y _ _ _ _ _ _) = y +containerY (Container _ y _ _ _ _ _ _ _) = y hunk ./Graphics/PDF/Typesetting/Layout.hs 228 -addTo _ line (Container px py w maxh h y z []) = Container px py w maxh ((boxHeight line)+h) y z [line] -addTo settings line (Container px py w maxh h y z l@(a:_)) = +addTo _ line (Container px py w maxh h y z t []) = Container px py w maxh ((boxHeight line)+h) y z t [line] +addTo settings line (Container px py w maxh h y z t l@(a:_)) = hunk ./Graphics/PDF/Typesetting/Layout.hs 236 - Container px py w maxh h' y' z' (line:l) + Container px py w maxh h' y' z' t (line:l) hunk ./Graphics/PDF/Typesetting/Layout.hs 242 - Container px py w maxh h' y' z' (line:v:l) + Container px py w maxh h' y' z' t (line:v:l) hunk ./Graphics/PDF/Typesetting/Layout.hs 245 -isOverfull (Container _ _ _ maxh h y z _) = let r = dilatationRatio maxh h y z +isOverfull (Container _ _ _ maxh h y z _ _) = let r = dilatationRatio maxh h y z hunk ./Graphics/PDF/Typesetting/Layout.hs 274 + -> Int -- ^ Line offset different from 0 when a paragraph has been broken hunk ./Graphics/PDF/Typesetting/Layout.hs 277 - paragraphChange a l = (a,l) + paragraphChange a _ l = (a,l) hunk ./Graphics/PDF/Typesetting/Vertical.hs 88 -drawContainer (Container px py _ maxh h y z oldl) = +drawContainer (Container px py _ maxh h y z _ oldl) = hunk ./Graphics/PDF/Typesetting/Vertical.hs 127 -fillContainer verstate c (Paragraph lineOffset l style paraSettings:l') = - let (fl,newStyle) = case style of - Nothing -> (formatList paraSettings (const $ containerWidth c) l,Nothing) - Just aStyle -> let (style',nl) = paragraphChange aStyle l - in - (formatList paraSettings (\nb -> (lineWidth style') (containerWidth c) (nb+lineOffset) ) nl,Just style') - newLines = horizontalPostProcess fl - r = addParaLine verstate newStyle paraSettings c (zip newLines [1..]) - in - case r of - Left (d,c',remPara) -> (d,c',remPara ++ l') - Right c' -> fillContainer verstate c' l' +fillContainer verstate c para@(Paragraph lineOffset l style paraSettings:l') = + if containerContentHeight c > containerHeight c - containerParaTolerance c + then + (drawContainer c,c,para) + else + let (fl,newStyle) = case style of + Nothing -> (formatList paraSettings (const $ containerWidth c) l,Nothing) + Just aStyle -> let (style',nl) = paragraphChange aStyle lineOffset l + in + (formatList paraSettings (\nb -> (lineWidth style') (containerWidth c) (nb+lineOffset) ) nl,Just style') + newLines = horizontalPostProcess fl + r = addParaLine verstate newStyle paraSettings c (zip newLines [1..]) + in + case r of + Left (d,c',remPara) -> (d,c',remPara ++ l') + Right c' -> fillContainer verstate c' l' hunk ./Graphics/PDF/Typesetting.hs 119 - c = mkContainer xa yb (xb-xa) (yb-ya) + c = mkContainer xa yb (xb-xa) (yb-ya) 0 hunk ./Test/test.hs 273 - paragraphChange (BluePara _) (AChar st c _:l) = + paragraphChange (BluePara _) _ (AChar st c _:l) = hunk ./Test/test.hs 293 - paragraphChange s l = (s,l) + paragraphChange s _ l = (s,l) hunk ./Test/test.hs 308 - let c = mkContainer xa ya xb yb + let c = mkContainer xa ya xb yb 0 hunk ./Test/test.hs 311 - cb = mkContainer xa (ya-100) xb yb + cb = mkContainer xa (ya-100) xb yb 0 hunk ./Graphics/PDF/Typesetting.hs 103 -import Data.Char(isSpace) +import Data.Char(isSpace,isAlpha) hunk ./Graphics/PDF/Typesetting.hs 330 -myWords = unfoldr myWords' +myWords l = concatMap onlyWord . unfoldr myWords' $ l + where + onlyWord s = let (w,p) = span isAlpha s in + case (null w,null p) of + (True,True) -> [] + (False,True) -> [w] + (True,False) -> [p] + (False,False) -> [w,p] hunk ./Graphics/PDF/Image.hs 32 +#if __GLASGOW_HASKELL__ >= 608 +import System.IO hiding(withFile) +#else hunk ./Graphics/PDF/Image.hs 36 +#endif hunk ./Graphics/PDF/LowLevel/Serializer.hs 25 -import Data.ByteString.Base +import Data.ByteString.Internal +import qualified Data.ByteString.Lazy.Internal as L(ByteString(..)) hunk ./Graphics/PDF/LowLevel/Serializer.hs 53 - serialize a = LPS [inlinePerformIO (createAndTrim 12 (cshortToString a))] + serialize a = L.Chunk (inlinePerformIO (createAndTrim 12 (cshortToString a))) L.Empty hunk ./Graphics/PDF/LowLevel/Serializer.hs 56 - serialize a = LPS [inlinePerformIO (createAndTrim 12 (cfloatToString a))] + serialize a = L.Chunk (inlinePerformIO (createAndTrim 12 (cfloatToString a))) L.Empty hunk ./Graphics/PDF/LowLevel/Types.hs 29 -import qualified Data.ByteString.Lazy as B hunk ./Graphics/PDF/LowLevel/Types.hs 30 -import Data.ByteString.Base(LazyByteString(..)) +import qualified Data.ByteString.Lazy.Internal as L(ByteString(..)) + hunk ./Graphics/PDF/LowLevel/Types.hs 89 -instance SerializeValue B.ByteString PDFString where - serialize (PDFString t) = LPS [t] +instance SerializeValue L.ByteString PDFString where + serialize (PDFString t) = L.Chunk t L.Empty hunk ./Graphics/PDF/Text.hs 59 -import Data.ByteString.Base(w2c,c2w) +import Data.ByteString.Internal(w2c,c2w) hunk ./Graphics/PDF/Typesetting/Breaking.hs 248 - if (b <= tolerance) || force -- || sndPass + if (b <= tolerance) || force -- sndPass hunk ./HPDF.cabal 3 +cabal-version: >=1.2 hunk ./HPDF.cabal 10 -tested-with: GHC==6.6 +tested-with: GHC==6.8.1 hunk ./HPDF.cabal 12 -build-depends: base, haskell98,mtl,encoding >= 0.2 ,zlib >= 0.3, binary >= 0.3 -ghc-options: -Wall -funbox-strict-fields -fglasgow-exts -O2 -extensions: ForeignFunctionInterface, CPP hunk ./HPDF.cabal 23 -C-Sources: - c/metrics.c - c/conversion.c -Include-Dirs: c -Install-Includes: - ctext.h - conversion.h -exposed-Modules: - Graphics.PDF - Graphics.PDF.Colors - Graphics.PDF.Coordinates - Graphics.PDF.Document - Graphics.PDF.Shapes - Graphics.PDF.Text - Graphics.PDF.Navigation - Graphics.PDF.Image - Graphics.PDF.Action - Graphics.PDF.Annotation - Graphics.PDF.Pattern - Graphics.PDF.Shading - Graphics.PDF.Typesetting - Graphics.PDF.Hyphenate -Other-Modules: - Graphics.PDF.LowLevel.Types - Graphics.PDF.Data.PDFTree - Graphics.PDF.Data.Trie - Graphics.PDF.Pages - Graphics.PDF.Resources - Graphics.PDF.Draw - Graphics.PDF.Hyphenate.English - Graphics.PDF.Hyphenate.LowLevel - Graphics.PDF.LowLevel.Kern - Graphics.PDF.Typesetting.Breaking - Graphics.PDF.Typesetting.Horizontal - Graphics.PDF.Typesetting.Vertical - Graphics.PDF.Typesetting.Box - Graphics.PDF.Typesetting.Layout - Graphics.PDF.LowLevel.Serializer - Graphics.PDF.Typesetting.StandardStyle + +flag splitBase + description: Choose the new smaller, split-up base package. + +library + if flag(splitBase) + build-depends: base >= 3, containers, random >= 1.0, bytestring >= 0.9, array >= 0.1, encoding >= 0.2 , zlib >= 0.3, binary >= 0.3, mtl + else + build-depends: base, haskell98, mtl,encoding >= 0.2 ,zlib >= 0.3, binary >= 0.3, bytestring >= 0.9 + ghc-options: -Wall -funbox-strict-fields -O2 + extensions: + FlexibleInstances, + ForeignFunctionInterface, + CPP, + MultiParamTypeClasses, + BangPatterns, + ExistentialQuantification, + ScopedTypeVariables, + GeneralizedNewtypeDeriving, + FlexibleContexts, + EmptyDataDecls, + TypeSynonymInstances, + FunctionalDependencies + + C-Sources: + c/metrics.c + c/conversion.c + Include-Dirs: c + Install-Includes: + ctext.h + conversion.h + exposed-Modules: + Graphics.PDF + Graphics.PDF.Colors + Graphics.PDF.Coordinates + Graphics.PDF.Document + Graphics.PDF.Shapes + Graphics.PDF.Text + Graphics.PDF.Navigation + Graphics.PDF.Image + Graphics.PDF.Action + Graphics.PDF.Annotation + Graphics.PDF.Pattern + Graphics.PDF.Shading + Graphics.PDF.Typesetting + Graphics.PDF.Hyphenate + Other-Modules: + Graphics.PDF.LowLevel.Types + Graphics.PDF.Data.PDFTree + Graphics.PDF.Data.Trie + Graphics.PDF.Pages + Graphics.PDF.Resources + Graphics.PDF.Draw + Graphics.PDF.Hyphenate.English + Graphics.PDF.Hyphenate.LowLevel + Graphics.PDF.LowLevel.Kern + Graphics.PDF.Typesetting.Breaking + Graphics.PDF.Typesetting.Horizontal + Graphics.PDF.Typesetting.Vertical + Graphics.PDF.Typesetting.Box + Graphics.PDF.Typesetting.Layout + Graphics.PDF.LowLevel.Serializer + Graphics.PDF.Typesetting.StandardStyle hunk ./Graphics/PDF/LowLevel/Serializer.hs 25 +#if __GLASGOW_HASKELL__ >= 608 hunk ./Graphics/PDF/LowLevel/Serializer.hs 28 +#else +import Data.ByteString.Base +import qualified Data.ByteString.Base as L(LazyByteString(..)) +#endif hunk ./Graphics/PDF/LowLevel/Serializer.hs 57 +#if __GLASGOW_HASKELL__ >= 608 hunk ./Graphics/PDF/LowLevel/Serializer.hs 63 +#else +instance SerializeValue L.LazyByteString Int where + serialize a = L.LPS [inlinePerformIO (createAndTrim 12 (cshortToString a))] hunk ./Graphics/PDF/LowLevel/Serializer.hs 67 +instance SerializeValue L.LazyByteString Double where + serialize a = L.LPS [inlinePerformIO (createAndTrim 12 (cfloatToString a))] +#endif hunk ./Graphics/PDF/LowLevel/Types.hs 30 +#if __GLASGOW_HASKELL__ >= 608 hunk ./Graphics/PDF/LowLevel/Types.hs 32 - +#else +import qualified Data.ByteString.Base as L(LazyByteString(..)) +#endif hunk ./Graphics/PDF/LowLevel/Types.hs 92 +#if __GLASGOW_HASKELL__ >= 608 hunk ./Graphics/PDF/LowLevel/Types.hs 95 +#else +instance SerializeValue L.LazyByteString PDFString where + serialize (PDFString t) = L.LPS [t] +#endif hunk ./Graphics/PDF/Text.hs 59 +#if __GLASGOW_HASKELL__ >= 608 hunk ./Graphics/PDF/Text.hs 61 +#else +import Data.ByteString.Base(w2c,c2w) +#endif hunk ./HPDF.cabal 31 - build-depends: base, haskell98, mtl,encoding >= 0.2 ,zlib >= 0.3, binary >= 0.3, bytestring >= 0.9 + build-depends: base, haskell98, mtl,encoding >= 0.2 ,zlib >= 0.3, binary >= 0.3 hunk ./Test/test.hs 615 + --print $ charWidth (PDFFont Times_Roman 1) '(' hunk ./Graphics/PDF/LowLevel/Serializer.hs 21 -import Data.Encoding -import Data.Encoding.UTF8 hunk ./Graphics/PDF/LowLevel/Serializer.hs 50 - serialize = encodeLazy UTF8 + serialize = C.pack hunk ./Graphics/PDF/LowLevel/Types.hs 21 - -import Data.Encoding -import Data.Encoding.ISO88591 - +import Data.Word hunk ./Graphics/PDF/LowLevel/Types.hs 87 -toPDFString = PDFString . encode ISO88591 . escapeString +toPDFString = PDFString . S.pack . map encodeISO88591 . escapeString + +encodeISO88591 :: Char -> Word8 +encodeISO88591 a = + let c = fromEnum a in + if c < 32 || c >= 256 then 32 else fromIntegral c hunk ./HPDF.cabal 23 + NEWS.txt + hunk ./HPDF.cabal 31 - build-depends: base >= 3, containers, random >= 1.0, bytestring >= 0.9, array >= 0.1, encoding >= 0.2 , zlib >= 0.3, binary >= 0.3, mtl + build-depends: base >= 3, containers, random >= 1.0, bytestring >= 0.9, array >= 0.1, zlib >= 0.3, binary >= 0.3, mtl hunk ./HPDF.cabal 33 - build-depends: base, haskell98, mtl,encoding >= 0.2 ,zlib >= 0.3, binary >= 0.3 + build-depends: base, haskell98, mtl ,zlib >= 0.3, binary >= 0.3 addfile ./NEWS.txt hunk ./NEWS.txt 1 +WHAT'S NEW IN HPDF 1.3 +====================== +1 - Can be built with ghc 6.8.1 and ghc 6.6 if you have the most recent Cabal and update a few libraries ; +2 - Bug corrections in the line breaking algorithm ; +3 - Automatic hyphenation algorithm (default Language is English). To add new language you have to use hyphenation patterns like in TeX. +Look at Graphics/PDF/Hyphenate.hs and Graphics/PDF/Hyphenate/English.hs hunk ./HPDF.cabal 11 -homepage: http://www.alpheccar.org/en/posts/show/84 +homepage: http://www.alpheccar.org addfile ./TODO.txt hunk ./TODO.txt 1 - +BUGS TO CORRECT +=============== + +* Line formatting sometimes broken when there is a break on an hyphen in all modes except the fully justified one ; +* Break on - will generate two hyphens (end of line and start of next line) ; +* Wrong metric for ( and ) ; + +FEATURES TO ADD +=============== +* Constraint programming ; +* Combinator interface to specify the layout of complex documents ; +* Support for other fonts an encoding ; +* Support for PNG ; +* Support for inclusion of other PDF files ; hunk ./HPDF.cabal 24 - + TODO.txt hunk ./Graphics/PDF/Document.hs 38 - , PDFXObject(drawXObject,bounds) + , PDFXObject(drawXObject) + , PDFGlobals(..) hunk ./Graphics/PDF/Document.hs 135 - let (a,state',w') = runDrawing draw (emptyEnvironment {streamId = streamRef, xobjectb = myBounds}) oldState + let (a,state',w') = runDrawing draw (emptyEnvironment {streamId = streamRef, xobjectBoundD = myBounds}) oldState hunk ./Graphics/PDF/Draw.hs 30 - , getBound hunk ./Graphics/PDF/Draw.hs 69 + , PDFGlobals(..) hunk ./Graphics/PDF/Draw.hs 162 - , xobjectb :: IM.IntMap (PDFFloat,PDFFloat) + , xobjectBoundD :: IM.IntMap (PDFFloat,PDFFloat) hunk ./Graphics/PDF/Draw.hs 167 - - hunk ./Graphics/PDF/Draw.hs 168 +class PDFGlobals m where + bounds :: PDFXObject a => PDFReference a -> m (PDFFloat,PDFFloat) + hunk ./Graphics/PDF/Draw.hs 266 +instance PDFGlobals Draw where + bounds (PDFReference r) = getBoundInDraw r + +instance PDFGlobals PDF where + bounds (PDFReference r) = getBoundInPDF r + hunk ./Graphics/PDF/Draw.hs 275 - bounds :: PDFReference a -> Draw (PDFFloat,PDFFloat) hunk ./Graphics/PDF/Draw.hs 287 - bounds (PDFReference r) = getBound r - hunk ./Graphics/PDF/Draw.hs 306 -getBound :: Int -- ^ Reference +getBoundInDraw :: Int -- ^ Reference hunk ./Graphics/PDF/Draw.hs 308 -getBound ref = do - theBounds <- asks xobjectb +getBoundInDraw ref = do + theBounds <- asks xobjectBoundD hunk ./Graphics/PDF/Draw.hs 311 - + +-- | Get the bounds for an xobject +getBoundInPDF :: Int -- ^ Reference + -> PDF (PDFFloat,PDFFloat) +getBoundInPDF ref = do + theBounds <- gets xobjectBound + return $ IM.findWithDefault (0.0,0.0) ref theBounds + hunk ./Graphics/PDF/Pages.hs 82 - let (_,state',w') = runDrawing d (emptyEnvironment {streamId = streamref, xobjectb = myBounds}) (emptyDrawState streamref) + let (_,state',w') = runDrawing d (emptyEnvironment {streamId = streamref, xobjectBoundD = myBounds}) (emptyDrawState streamref) hunk ./HPDF.cabal 2 -Version: 1.3 +Version: 1.4 hunk ./Graphics/PDF/LowLevel/Serializer.hs 1 +{-# OPTIONS_GHC -fno-cse #-} hunk ./Graphics/PDF/LowLevel/Serializer.hs 31 +import System.IO.Unsafe hunk ./Graphics/PDF/LowLevel/Serializer.hs 57 +convertShort :: Int -> ByteString +convertShort a = unsafePerformIO (createAndTrim 12 (cshortToString a)) +{-# NOINLINE convertShort #-} + +convertFloat :: Double -> ByteString +convertFloat a = unsafePerformIO (createAndTrim 12 (cfloatToString a)) +{-# NOINLINE convertFloat #-} + hunk ./Graphics/PDF/LowLevel/Serializer.hs 67 - serialize a = L.Chunk (inlinePerformIO (createAndTrim 12 (cshortToString a))) L.Empty + serialize a = L.Chunk (convertShort a) L.Empty hunk ./Graphics/PDF/LowLevel/Serializer.hs 70 - serialize a = L.Chunk (inlinePerformIO (createAndTrim 12 (cfloatToString a))) L.Empty + serialize a = L.Chunk (convertFloat a) L.Empty hunk ./Graphics/PDF/LowLevel/Serializer.hs 73 - serialize a = L.LPS [inlinePerformIO (createAndTrim 12 (cshortToString a))] + serialize a = L.LPS [convertShort a] hunk ./Graphics/PDF/LowLevel/Serializer.hs 76 - serialize a = L.LPS [inlinePerformIO (createAndTrim 12 (cfloatToString a))] + serialize a = L.LPS [convertFloat a] hunk ./Graphics/PDF/LowLevel/Types.hs 87 -toPDFString = PDFString . S.pack . map encodeISO88591 . escapeString +toPDFString = PDFString . S.pack . map encodeISO88591 -- . escapeString hunk ./Graphics/PDF/LowLevel/Types.hs 106 -escapeString :: String -> String -escapeString [] = [] -escapeString ('(':l) = '\\':'(':escapeString l -escapeString (')':l) = '\\':')':escapeString l -escapeString ('\\':l) = '\\':'\\':escapeString l -escapeString (a:l) = a:escapeString l +escapeString :: PDFString -> PDFString +escapeString (PDFString t) = PDFString . S.pack . escapeOnWords8 . S.unpack $ t + +pc2w :: Char -> Word8 +pc2w = fromIntegral . fromEnum + +escapeOnWords8 :: [Word8] -> [Word8] +escapeOnWords8 [] = [] +escapeOnWords8 (a:l) | a == pc2w '(' = (pc2w '\\'):(pc2w '('):escapeOnWords8 l + | a == pc2w ')' = (pc2w '\\'):(pc2w ')'):escapeOnWords8 l + | a == pc2w '\\' = (pc2w '\\'):(pc2w '\\'):escapeOnWords8 l + | otherwise = a:escapeOnWords8 l hunk ./Graphics/PDF/LowLevel/Types.hs 150 - , serialize a + , serialize . escapeString $ a hunk ./Graphics/PDF/Text.hs 129 + , currentFont :: PDFFont hunk ./Graphics/PDF/Text.hs 132 -defaultParameters = TextParameter 0 0 100 0 0 (Set.empty) +defaultParameters = TextParameter 0 0 100 0 0 (Set.empty) (PDFFont Times_Roman 12) hunk ./Graphics/PDF/Text.hs 138 - deriving(Monad,Functor,MonadWriter Builder) + deriving(Monad,Functor,MonadWriter Builder,MonadState TextParameter) hunk ./Graphics/PDF/Text.hs 143 +instance MonadState TextParameter PDFText hunk ./Graphics/PDF/Text.hs 164 -setFont (PDFFont n size) = PDFText $ do - lift (modifyStrict $ \s -> s {fontState = Set.insert n (fontState s)}) +setFont f@(PDFFont n size) = PDFText $ do + lift (modifyStrict $ \s -> s {fontState = Set.insert n (fontState s), currentFont = f}) hunk ./Graphics/PDF/Text.hs 205 +-- 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 hunk ./Test/test.hs 122 - fontDebug (PDFFont Times_Roman 48) (toPDFString "This is a test (éèçàù)!") + fontDebug (PDFFont Times_Roman 48) (toPDFString "This is a \\test (éèçàù)!") hunk ./Graphics/PDF/Draw.hs 350 - !(Maybe (PDFReference PDFPages)) -- ^ Reference to parent - !PDFRect -- ^ Media box - !(PDFReference PDFStream) -- ^ Reference to content - !(Maybe (PDFReference PDFResource)) -- ^ Reference to resources - !(Maybe PDFFloat) -- ^ Optional duration - !(Maybe PDFTransition) -- ^ Optional transition - ![AnyPdfObject] -- ^ Annotation array + !(Maybe (PDFReference PDFPages)) -- Reference to parent + !(PDFRect) -- Media box + !(PDFReference PDFStream) -- Reference to content + !(Maybe (PDFReference PDFResource)) -- Reference to resources + !(Maybe PDFFloat) -- Optional duration + !(Maybe PDFTransition) -- Optional transition + ![AnyPdfObject] -- Annotation array hunk ./Graphics/PDF/Draw.hs 371 - !(Maybe (PDFReference PDFPages)) -- ^ Reference to parent + !(Maybe (PDFReference PDFPages)) -- Reference to parent hunk ./Graphics/PDF/Typesetting.hs 35 + , Orientation(..) hunk ./Graphics/PDF/Typesetting.hs 67 + , drawTextBox hunk ./Graphics/PDF/Typesetting.hs 97 +import Graphics.PDF.Coordinates hunk ./Graphics/PDF/Typesetting.hs 418 +------------------------------- +-- +-- Tools to ease tech drawings +-- +------------------------------- + +data Orientation = E | W | N | S | NE | NW | SE | SW deriving(Eq,Show) + +-- | Draw a text box with relative position. Useful for labels +drawTextBox :: (ParagraphStyle ps s, Style s) + => PDFFloat -- ^ x + -> PDFFloat -- ^ y + -> PDFFloat -- ^ width limit + -> PDFFloat -- ^ height limit + -> Orientation + -> ps -- ^ default vertical style + -> s -- ^ Default horizontal style + -> TM ps s a -- ^ Typesetting monad + -> (Rectangle,Draw ()) +drawTextBox x y w h ori ps p t = + let b = getBoxes ps p t + sh = styleHeight p + c = mkContainer 0 0 w h sh + (d,c',_) = fillContainer (defaultVerState ps) c b + Rectangle xa ya xb yb = containerContentRectangle c' + wc = xb - xa + hc = yb - ya + (dx,dy) = case ori of + NE -> (x,y) + NW -> (x - wc,y) + SE -> (x,y + hc) + SW -> (x - wc,y + hc) + E -> (x,y + hc / 2.0) + W -> (x - wc,y + hc / 2.0) + N -> (x - wc/2.0,y) + S -> (x - wc/2.0,y + hc) + _ -> (x,y) + box = withNewContext $ do + applyMatrix $ translate dx dy + d + r = Rectangle (xa + dx) (ya + dy) (xb + dx) (yb + dy) + in + (r,box) + hunk ./Graphics/PDF.hs 164 - !Int -- ^ Number of PDF objects in the document - !(PDFReference PDFCatalog) -- ^ Reference to the PDf catalog + !Int -- Number of PDF objects in the document + !(PDFReference PDFCatalog) -- Reference to the PDf catalog hunk ./Test/test.hs 528 - +textBoxes :: Draw () +textBoxes = do + let x = 230 + y = 200 + w = 220 + h = 200 + fillColor blue + fill $ Circle x y 5 + let (r,b) = drawTextBox x y w h S NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + setJustification FullJustification + paragraph $ do + txt $ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor " + txt $ "incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud " + txt $ "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute " + txt $ "irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla " + txt $ "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia " + txt $ "deserunt mollit anim id est laborum." + b + strokeColor red + stroke r + return () + hunk ./Test/test.hs 552 - page1 <- addPage Nothing - newSection (toPDFString "Typesetting") Nothing Nothing $ do - newSection (toPDFString "Normal text") Nothing Nothing $ do - typesetTest 1 page1 - - page2 <- addPage Nothing - newSection (toPDFString "Debug text") Nothing Nothing $ do - typesetTest 2 page2 - - page3 <- addPage Nothing - newSection (toPDFString "Circle text") Nothing Nothing $ do - typesetTest 3 page3 - - page3a <- addPage Nothing - newSection (toPDFString "Standard styles") Nothing Nothing $ do - typesetTest 4 page3a - - page3b <- addPage Nothing - newSection (toPDFString "Justifications") Nothing Nothing $ do - typesetTest 5 page3b - - page3d <- addPage Nothing - newSection (toPDFString "New lines") Nothing Nothing $ do - typesetTest 6 page3d - - page3c <- addPage Nothing - newSection (toPDFString "Container") Nothing Nothing $ do - containerTest page3c (Rectangle 10 300 100 100) testText - containerTest page3c (Rectangle 210 300 200 100) $ do - setJustification Centered - testText - - page4 <- addPage Nothing - newSection (toPDFString "Shapes") Nothing Nothing $ do - - newSection (toPDFString "Geometry") Nothing Nothing $ do - drawWithPage page4 $ do - geometryTest - - page5 <- addPage Nothing - newSection (toPDFString "Line style") Nothing Nothing $ do - drawWithPage page5 $ do - lineStyle - - page6 <- addPage Nothing - newSection (toPDFString "Object reuse") Nothing Nothing $ do - r <- createPDFXForm 0 0 200 200 lineStyle - drawWithPage page6 $ do - drawXObject r - - page7 <- addPage Nothing - newSectionWithPage (toPDFString "Painting") Nothing Nothing page7 $ do - newSection (toPDFString "Patterns") Nothing Nothing $ do - patternTest page7 - - page8 <- addPage Nothing - newSection (toPDFString "Shading") Nothing Nothing $ do - drawWithPage page8 $ do - shadingTest - - page9 <- addPage Nothing - newSection (toPDFString "Media") Nothing Nothing $ do - newSection (toPDFString "image") Nothing Nothing $ do - testImage jpg page9 - - page10 <- addPage Nothing - newSection (toPDFString "Annotations") Nothing Nothing $ do - testAnnotation page10 - - page11 <- addPage Nothing - newSection (toPDFString "Text encoding") Nothing Nothing $ do - drawWithPage page11 $ do - textTest - newSection (toPDFString "Fun") Nothing Nothing $ do - penrose - + --page1 <- addPage Nothing + --newSection (toPDFString "Typesetting") Nothing Nothing $ do + -- newSection (toPDFString "Normal text") Nothing Nothing $ do + -- typesetTest 1 page1 + -- + -- page2 <- addPage Nothing + -- newSection (toPDFString "Debug text") Nothing Nothing $ do + -- typesetTest 2 page2 + -- + -- page3 <- addPage Nothing + -- newSection (toPDFString "Circle text") Nothing Nothing $ do + -- typesetTest 3 page3 + -- + -- page3a <- addPage Nothing + -- newSection (toPDFString "Standard styles") Nothing Nothing $ do + -- typesetTest 4 page3a + -- + -- page3b <- addPage Nothing + -- newSection (toPDFString "Justifications") Nothing Nothing $ do + -- typesetTest 5 page3b + -- + -- page3d <- addPage Nothing + -- newSection (toPDFString "New lines") Nothing Nothing $ do + -- typesetTest 6 page3d + -- + -- page3c <- addPage Nothing + -- newSection (toPDFString "Container") Nothing Nothing $ do + -- containerTest page3c (Rectangle 10 300 100 100) testText + -- containerTest page3c (Rectangle 210 300 200 100) $ do + -- setJustification Centered + -- testText + -- + --page4 <- addPage Nothing + --newSection (toPDFString "Shapes") Nothing Nothing $ do + -- + -- newSection (toPDFString "Geometry") Nothing Nothing $ do + -- drawWithPage page4 $ do + -- geometryTest + -- + -- page5 <- addPage Nothing + -- newSection (toPDFString "Line style") Nothing Nothing $ do + -- drawWithPage page5 $ do + -- lineStyle + -- + -- page6 <- addPage Nothing + -- newSection (toPDFString "Object reuse") Nothing Nothing $ do + -- r <- createPDFXForm 0 0 200 200 lineStyle + -- drawWithPage page6 $ do + -- drawXObject r + -- + --page7 <- addPage Nothing + --newSectionWithPage (toPDFString "Painting") Nothing Nothing page7 $ do + -- newSection (toPDFString "Patterns") Nothing Nothing $ do + -- patternTest page7 + -- + -- page8 <- addPage Nothing + -- newSection (toPDFString "Shading") Nothing Nothing $ do + -- drawWithPage page8 $ do + -- shadingTest + -- + --page9 <- addPage Nothing + --newSection (toPDFString "Media") Nothing Nothing $ do + -- newSection (toPDFString "image") Nothing Nothing $ do + -- testImage jpg page9 + -- + --page10 <- addPage Nothing + --newSection (toPDFString "Annotations") Nothing Nothing $ do + -- testAnnotation page10 + -- + --page11 <- addPage Nothing + --newSection (toPDFString "Text encoding") Nothing Nothing $ do + -- drawWithPage page11 $ do + -- textTest + --newSection (toPDFString "Fun") Nothing Nothing $ do + -- penrose + page12 <- addPage Nothing + newSection (toPDFString "Text box") Nothing Nothing $ do + drawWithPage page12 $ do + textBoxes hunk ./Graphics/PDF/Typesetting.hs 454 - _ -> (x,y) hunk ./Test/test.hs 552 - --page1 <- addPage Nothing - --newSection (toPDFString "Typesetting") Nothing Nothing $ do - -- newSection (toPDFString "Normal text") Nothing Nothing $ do - -- typesetTest 1 page1 - -- - -- page2 <- addPage Nothing - -- newSection (toPDFString "Debug text") Nothing Nothing $ do - -- typesetTest 2 page2 - -- - -- page3 <- addPage Nothing - -- newSection (toPDFString "Circle text") Nothing Nothing $ do - -- typesetTest 3 page3 - -- - -- page3a <- addPage Nothing - -- newSection (toPDFString "Standard styles") Nothing Nothing $ do - -- typesetTest 4 page3a - -- - -- page3b <- addPage Nothing - -- newSection (toPDFString "Justifications") Nothing Nothing $ do - -- typesetTest 5 page3b - -- - -- page3d <- addPage Nothing - -- newSection (toPDFString "New lines") Nothing Nothing $ do - -- typesetTest 6 page3d - -- - -- page3c <- addPage Nothing - -- newSection (toPDFString "Container") Nothing Nothing $ do - -- containerTest page3c (Rectangle 10 300 100 100) testText - -- containerTest page3c (Rectangle 210 300 200 100) $ do - -- setJustification Centered - -- testText - -- - --page4 <- addPage Nothing - --newSection (toPDFString "Shapes") Nothing Nothing $ do - -- - -- newSection (toPDFString "Geometry") Nothing Nothing $ do - -- drawWithPage page4 $ do - -- geometryTest - -- - -- page5 <- addPage Nothing - -- newSection (toPDFString "Line style") Nothing Nothing $ do - -- drawWithPage page5 $ do - -- lineStyle - -- - -- page6 <- addPage Nothing - -- newSection (toPDFString "Object reuse") Nothing Nothing $ do - -- r <- createPDFXForm 0 0 200 200 lineStyle - -- drawWithPage page6 $ do - -- drawXObject r - -- - --page7 <- addPage Nothing - --newSectionWithPage (toPDFString "Painting") Nothing Nothing page7 $ do - -- newSection (toPDFString "Patterns") Nothing Nothing $ do - -- patternTest page7 - -- - -- page8 <- addPage Nothing - -- newSection (toPDFString "Shading") Nothing Nothing $ do - -- drawWithPage page8 $ do - -- shadingTest - -- - --page9 <- addPage Nothing - --newSection (toPDFString "Media") Nothing Nothing $ do - -- newSection (toPDFString "image") Nothing Nothing $ do - -- testImage jpg page9 - -- - --page10 <- addPage Nothing - --newSection (toPDFString "Annotations") Nothing Nothing $ do - -- testAnnotation page10 - -- - --page11 <- addPage Nothing - --newSection (toPDFString "Text encoding") Nothing Nothing $ do - -- drawWithPage page11 $ do - -- textTest - --newSection (toPDFString "Fun") Nothing Nothing $ do - -- penrose + page1 <- addPage Nothing + newSection (toPDFString "Typesetting") Nothing Nothing $ do + newSection (toPDFString "Normal text") Nothing Nothing $ do + typesetTest 1 page1 + + page2 <- addPage Nothing + newSection (toPDFString "Debug text") Nothing Nothing $ do + typesetTest 2 page2 + + page3 <- addPage Nothing + newSection (toPDFString "Circle text") Nothing Nothing $ do + typesetTest 3 page3 + + page3a <- addPage Nothing + newSection (toPDFString "Standard styles") Nothing Nothing $ do + typesetTest 4 page3a + + page3b <- addPage Nothing + newSection (toPDFString "Justifications") Nothing Nothing $ do + typesetTest 5 page3b + + page3d <- addPage Nothing + newSection (toPDFString "New lines") Nothing Nothing $ do + typesetTest 6 page3d + + page3c <- addPage Nothing + newSection (toPDFString "Container") Nothing Nothing $ do + containerTest page3c (Rectangle 10 300 100 100) testText + containerTest page3c (Rectangle 210 300 200 100) $ do + setJustification Centered + testText + + page4 <- addPage Nothing + newSection (toPDFString "Shapes") Nothing Nothing $ do + + newSection (toPDFString "Geometry") Nothing Nothing $ do + drawWithPage page4 $ do + geometryTest + + page5 <- addPage Nothing + newSection (toPDFString "Line style") Nothing Nothing $ do + drawWithPage page5 $ do + lineStyle + + page6 <- addPage Nothing + newSection (toPDFString "Object reuse") Nothing Nothing $ do + r <- createPDFXForm 0 0 200 200 lineStyle + drawWithPage page6 $ do + drawXObject r + + page7 <- addPage Nothing + newSectionWithPage (toPDFString "Painting") Nothing Nothing page7 $ do + newSection (toPDFString "Patterns") Nothing Nothing $ do + patternTest page7 + + page8 <- addPage Nothing + newSection (toPDFString "Shading") Nothing Nothing $ do + drawWithPage page8 $ do + shadingTest + + page9 <- addPage Nothing + newSection (toPDFString "Media") Nothing Nothing $ do + newSection (toPDFString "image") Nothing Nothing $ do + testImage jpg page9 + + page10 <- addPage Nothing + newSection (toPDFString "Annotations") Nothing Nothing $ do + testAnnotation page10 + + page11 <- addPage Nothing + newSection (toPDFString "Text encoding") Nothing Nothing $ do + drawWithPage page11 $ do + textTest + newSection (toPDFString "Fun") Nothing Nothing $ do + penrose hunk ./Graphics/PDF/Typesetting/Breaking.hs 561 - FullJustification -> [Glue normalW (normalW*sy/2.0*f) (normalW*sz/3.0) (Just s)] + FullJustification -> [Glue (normalW) (normalW*sy/2.0*f) (normalW*sz/3.0) (Just s)] hunk ./Graphics/PDF/Typesetting/Breaking.hs 564 - , Glue normalW (-2*centeredDilatationFactor*normalW) 0 (Just s) + , Glue (normalW) (-2*centeredDilatationFactor*normalW) 0 (Just s) hunk ./Graphics/PDF/Typesetting/Breaking.hs 621 +createLetterBoxes settings s ((w',','):(_,' '):l) = (createChar s w' ',') : ((spaceGlueBox settings s 2.0) ++ createLetterBoxes settings s l) +createLetterBoxes settings s ((w',';'):(_,' '):l) = (createChar s w' ';') : ((spaceGlueBox settings s 2.0) ++ createLetterBoxes settings s l) +createLetterBoxes settings s ((w','.'):(_,' '):l) = (createChar s w' '.') : ((spaceGlueBox settings s 2.0) ++ createLetterBoxes settings s l) +createLetterBoxes settings s ((w',':'):(_,' '):l) = (createChar s w' ':') : ((spaceGlueBox settings s 2.0) ++ createLetterBoxes settings s l) +createLetterBoxes settings s ((w','!'):(_,' '):l) = (createChar s w' '!') : ((spaceGlueBox settings s 2.0) ++ createLetterBoxes settings s l) +createLetterBoxes settings s ((w','?'):(_,' '):l) = (createChar s w' '?') : ((spaceGlueBox settings s 2.0) ++ createLetterBoxes settings s l) hunk ./Graphics/PDF/Draw.hs 15 - Draw(..) + Draw hunk ./Graphics/PDF/Draw.hs 72 -import Graphics.PDF.LowLevel.Types -import Control.Monad.RWS -import Control.Monad.Writer -import Control.Monad.Reader -import Control.Monad.State +import Data.Maybe +import Data.Monoid + hunk ./Graphics/PDF/Draw.hs 76 -import Graphics.PDF.Resources hunk ./Graphics/PDF/Draw.hs 77 -import Graphics.PDF.Data.PDFTree(PDFTree) -import Data.Maybe hunk ./Graphics/PDF/Draw.hs 78 + +import Control.Monad.ST +import Data.STRef + +import Control.Monad.Writer.Class +import Control.Monad.Reader.Class +import Control.Monad.State + +import Graphics.PDF.LowLevel.Types hunk ./Graphics/PDF/Draw.hs 88 -import Data.Monoid +import Graphics.PDF.Resources +import Graphics.PDF.Data.PDFTree(PDFTree) + hunk ./Graphics/PDF/Draw.hs 170 + +data DrawTuple s + = DrawTuple { drawEnvironment :: DrawEnvironment + , drawStateRef :: STRef s DrawState + , builderRef :: STRef s BU.Builder + } hunk ./Graphics/PDF/Draw.hs 184 -newtype Draw a = Draw {unDraw :: RWS DrawEnvironment BU.Builder DrawState a} -#ifndef __HADDOCK__ - deriving(Monad,MonadWriter BU.Builder, MonadReader DrawEnvironment, MonadState DrawState, Functor) -#else -instance Monad Draw -instance MonadWriter BU.Builder Draw -instance MonadReader DrawEnvironment Draw -instance MonadState DrawState Draw -instance Functor Draw -#endif +newtype Draw a = Draw {unDraw :: forall s. DrawTuple s -> ST s a } + +instance Monad Draw where + m >>= f = Draw $ \env -> do + a <- unDraw m env + unDraw (f a) env + return x = Draw $ \_env -> return x + +instance MonadReader DrawEnvironment Draw where + ask = Draw $ \env -> return (drawEnvironment env) + local f m = Draw $ \env -> let drawenv' = f (drawEnvironment env) + env' = env { drawEnvironment = drawenv' } + in unDraw m env' + +instance MonadState DrawState Draw where + get = Draw $ \env -> readSTRef (drawStateRef env) + put st = Draw $ \env -> writeSTRef (drawStateRef env) st + +instance MonadWriter BU.Builder Draw where + tell bu = Draw $ \env -> modifySTRef (builderRef env) (`mappend` bu) + listen m = Draw $ \env -> do + a <- unDraw m env + w <- readSTRef (builderRef env) + return (a,w) + pass m = Draw $ \env -> do + (a, f) <- unDraw m env + modifySTRef (builderRef env) f + return a + +instance Functor Draw where + fmap f = \m -> do { a <- m; return (f a) } hunk ./Graphics/PDF/Draw.hs 257 -runDrawing drawing environment state = (runRWS . unDraw $ drawing) environment state +runDrawing drawing environment state + = runST $ do + dRef <- newSTRef state + bRef <- newSTRef mempty + let tuple = DrawTuple { drawEnvironment = environment + , drawStateRef = dRef + , builderRef = bRef + } + a <- unDraw drawing tuple + drawSt <- readSTRef (drawStateRef tuple) + builder <- readSTRef (builderRef tuple) + return (a, drawSt, builder) hunk ./Graphics/PDF/Shapes.hs 172 -data JoinStyle = MilterJoin +data JoinStyle = MiterJoin hunk ./Graphics/PDF.hs 20 - , PDFFloat(..) + , PDFFloat hunk ./Graphics/PDF/Draw.hs 664 - toPDF (Rgb r g b) = toPDF . map (AnyPdfObject . PDFFloat) $ [r,g,b] + toPDF (Rgb r g b) = toPDF . map AnyPdfObject $ [r,g,b] hunk ./Graphics/PDF/Draw.hs 666 - in toPDF . map (AnyPdfObject . PDFFloat) $ [r,g,b] + in toPDF . map AnyPdfObject $ [r,g,b] hunk ./Graphics/PDF/Draw.hs 694 -getRgbColor (Rgb r g b) = (PDFFloat r,PDFFloat g,PDFFloat b) -getRgbColor (Hsv h s v) = let (r,g,b) = hsvToRgb (h,s,v) in (PDFFloat r,PDFFloat g,PDFFloat b) +getRgbColor (Rgb r g b) = (r, g, b) +getRgbColor (Hsv h s v) = let (r,g,b) = hsvToRgb (h,s,v) in (r, g, b) hunk ./Graphics/PDF/Draw.hs 701 - , (PDFName "Domain", AnyPdfObject . map AnyPdfObject $ [PDFFloat 0,PDFFloat 1]) + , (PDFName "Domain", AnyPdfObject . map AnyPdfObject $ ([0,1] :: [PDFFloat])) hunk ./Graphics/PDF/LowLevel/Types.hs 58 -newtype PDFFloat = PDFFloat Double deriving(Eq,Ord,Num,Fractional,Floating,RealFrac,Real,Random) - -instance Show PDFFloat where - show (PDFFloat x) = printf "%.5f" x +type PDFFloat = Double hunk ./Graphics/PDF/LowLevel/Types.hs 70 - toPDF (PDFFloat a) = serialize a - -instance PdfObject Double where hunk ./Graphics/PDF/Resources.hs 81 - toRsrc (StrokeAlpha a) = AnyPdfObject . PDFDictionary . M.fromList $ [(PDFName "CA",AnyPdfObject . PDFFloat $ a)] + toRsrc (StrokeAlpha a) = AnyPdfObject . PDFDictionary . M.fromList $ [(PDFName "CA",AnyPdfObject a)] hunk ./Graphics/PDF/Resources.hs 85 - toRsrc (FillAlpha a) = AnyPdfObject . PDFDictionary . M.fromList $ [(PDFName "ca",AnyPdfObject . PDFFloat $ a)] + toRsrc (FillAlpha a) = AnyPdfObject . PDFDictionary . M.fromList $ [(PDFName "ca",AnyPdfObject a)] hunk ./Graphics/PDF/Coordinates.hs 13 -module Graphics.PDF.Coordinates( +module Graphics.PDF.Coordinates + ( module Data.Complex hunk ./Graphics/PDF/Coordinates.hs 17 - Angle(..) + , Angle(..) + , Point hunk ./Graphics/PDF/Coordinates.hs 21 - , rotate, translate, scale, identity + , toRadian + , dot, scalePt + , project, projectX, projectY + , pointMatrix + , transform + , identity, rotate, translate, scale, spiral hunk ./Graphics/PDF/Coordinates.hs 32 +import Data.Complex hunk ./Graphics/PDF/Coordinates.hs 44 +toRadian :: Angle -> PDFFloat +toRadian (Degree x) = (pi / 180) * x +toRadian (Radian x) = x hunk ./Graphics/PDF/Coordinates.hs 48 +type Point = Complex PDFFloat hunk ./Graphics/PDF/Coordinates.hs 50 +-- | Dot product of two points +-- 'dot (x :+ y) (a :+ b) == x * a + y * b' +-- 'dot z w == magnitude z * magnitude w * cos (phase z - phase w)' +dot :: (RealFloat t) => Complex t -> Complex t -> t +dot (x0 :+ y0) (x1 :+ y1) = x0 * x1 + y0 * y1 hunk ./Graphics/PDF/Coordinates.hs 56 +scalePt :: (RealFloat t) => t -> Complex t -> Complex t +scalePt a (x :+ y) = a*x :+ a*y hunk ./Graphics/PDF/Coordinates.hs 59 +-- | projects the first point onto the second +project :: (RealFloat t) => Complex t -> Complex t -> Complex t +project z w = scalePt (dot z w / dot w w) w + +-- | projects a point onto the x-axis +projectX :: (RealFloat t) => Complex t -> Complex t +projectX (x :+ _) = (x :+ 0) + +-- | projects a point onto the y-axis +projectY :: (RealFloat t) => Complex t -> Complex t +projectY (_ :+ y) = (0 :+ y) + +-- | Applies a matrix to a point +transform :: Matrix -> Point -> Point +transform (Matrix x0 y0 x1 y1 x2 y2) (x :+ y) = (x*x0 + y*x1 + x2) :+ (x*y0 + y*y1 + y2) hunk ./Graphics/PDF/Coordinates.hs 93 + +-- | Specifies a matrix as three points +pointMatrix :: Point -- ^ X component + -> Point -- ^ Y component + -> Point -- ^ translation component + -> Matrix +pointMatrix (x0 :+ y0) (x1 :+ y1) (x2 :+ y2) = Matrix x0 y0 x1 y1 x2 y2 hunk ./Graphics/PDF/Coordinates.hs 104 -rotate r = Matrix ( (cos radian)) ( (sin radian)) (- ( (sin radian))) ( (cos radian)) 0 0 - where - radian = case r of - Degree angle -> angle / 180 * pi - Radian angle -> angle +rotate r = spiral (cis (toRadian r)) hunk ./Graphics/PDF/Coordinates.hs 106 - --- | Translation matrix -translate :: PDFFloat -- ^ Horizontal translation - -> PDFFloat -- ^ Vertical translation +-- | Translation matrix +-- 'transform (translate z) w == z + w' +translate :: Point hunk ./Graphics/PDF/Coordinates.hs 110 -translate tx ty = Matrix 1 0 0 1 tx ty +translate (tx :+ ty) = Matrix 1 0 0 1 tx ty + +-- | 'Spiral z' rotates by 'phase z' and scales by 'magnitude z' +-- 'transform (spiral z) w == z * w' +spiral :: Point + -> Matrix +spiral (x :+ y) = Matrix x y (-y) x 0 0 hunk ./Graphics/PDF/Image.hs 309 - applyMatrix (translate 0 0) hunk ./Graphics/PDF/Shapes.hs 55 +import Graphics.PDF.Coordinates hunk ./Graphics/PDF/Shapes.hs 97 - let poly = [(x0,y0),(x1,y0),(x1,y1),(x0,y1)] + let poly = [(x0 :+ y0),(x1 :+ y0),(x1 :+ y1),(x0 :+ y1)] hunk ./Graphics/PDF/Shapes.hs 280 - - --- | A point -type Point = (PDFFloat,PDFFloat) hunk ./Graphics/PDF/Shapes.hs 284 -addPolygonToPath l = do - (uncurry moveto) . head $ l - mapM_ (\(x,y) -> addLineToPath x y) (tail l) +addPolygonToPath [] = return () +addPolygonToPath ((x0 :+ y0) : ls) = do + moveto x0 y0 + mapM_ (\(x :+ y) -> addLineToPath x y) ls hunk ./Graphics/PDF/Typesetting.hs 455 - applyMatrix $ translate dx dy + applyMatrix $ translate (dx :+ dy) hunk ./Graphics/PDF/Typesetting/Box.hs 47 - applyMatrix $ translate x y + applyMatrix $ translate (x :+ y) hunk ./Test/Penrose.hs 26 - applyMatrix (translate width 0) + applyMatrix (translate (width :+ 0)) hunk ./Test/Penrose.hs 34 - applyMatrix (translate (width*golden) 0) + applyMatrix (translate ((width*golden) :+ 0)) hunk ./Test/Penrose.hs 69 - let pol = [ (0,0) - , ((s*cos(phi)),(s*sin(phi))) - , ((s*golden),0) + let pol = [ 0 + , mkPolar s phi + , ((s*golden) :+ 0) hunk ./Test/Penrose.hs 89 - let pol = [ (0,0) - , ((s*cos(phi)),(s*sin(phi))) - , (s,0) + let pol = [ 0 + , mkPolar s phi + , (s :+ 0) hunk ./Test/Penrose.hs 107 - applyMatrix (translate 20 5) + applyMatrix (translate (20 :+ 5)) hunk ./Test/test.hs 85 - applyMatrix $ translate 50 0 + applyMatrix $ translate (50 :+ 0) hunk ./Test/test.hs 91 - applyMatrix $ translate 100 0 + applyMatrix $ translate (100 :+ 0) hunk ./Test/test.hs 98 - applyMatrix $ translate 50 50 + applyMatrix $ translate (50 :+ 50) hunk ./Test/test.hs 134 - applyMatrix $ translate 200 200 + applyMatrix $ translate (200 :+ 200) hunk ./Test/test.hs 196 - p = Polygon [ (xa-a,ya+b) - , (xb+c,ya+d) - , (xb+e,yb-f) - , (xa-g,yb-h) - , (xa-a,ya+b) + p = Polygon [ (xa-a) :+ (ya+b) + , (xb+c) :+ (ya+d) + , (xb+e) :+ (yb-f) + , (xa-g) :+ (yb-h) + , (xa-a) :+ (ya+b) hunk ./Test/test.hs 279 - applyMatrix $ translate (-w') (getDescent f - getHeight f + styleHeight st - styleDescent st) + applyMatrix $ translate ((-w') :+ (getDescent f - getHeight f + styleHeight st - styleDescent st)) hunk ./Graphics/PDF.hs 33 + , applyMatrix hunk ./Graphics/PDF/Coordinates.hs 27 - -- ** Frame of reference operators - , applyMatrix hunk ./Graphics/PDF/Coordinates.hs 31 -import Graphics.PDF.LowLevel.Types -import Graphics.PDF.Draw -import Control.Monad.Writer - -import Graphics.PDF.LowLevel.Serializer -import Data.Monoid +import Graphics.PDF.LowLevel.Types(PDFFloat) hunk ./Graphics/PDF/Coordinates.hs 64 --- | Applies a matrix to a point -transform :: Matrix -> Point -> Point -transform (Matrix x0 y0 x1 y1 x2 y2) (x :+ y) = (x*x0 + y*x1 + x2) :+ (x*y0 + y*y1 + y2) +-- | A transformation matrix. An affine transformation a b c d e f +-- +-- @ +-- a b 0 +-- c d 0 +-- e f 1 +-- @ + +data Matrix = Matrix !PDFFloat !PDFFloat !PDFFloat !PDFFloat !PDFFloat !PDFFloat deriving (Eq, Show) + +instance Num Matrix where + -- Matrix addition + (+) (Matrix ma mb mc md me mf ) (Matrix na nb nc nd ne nf) = + Matrix (ma+na) (mb+nb) (mc+nc) (md+nd) (me+ne) (mf+nf) + (*) (Matrix ma mb mc md me mf) (Matrix na nb nc nd ne nf) = + Matrix (ma*na+mb*nc) (ma*nb+mb*nd) (mc*na+md*nc) (mc*nb +md*nd) (me*na+mf*nc+ne) (me*nb+mf*nd+nf) + negate (Matrix ma mb mc md me mf ) = + Matrix (-ma) (-mb) (-mc) (-md) (-me) (-mf) + abs m = m + signum _ = identity + fromInteger i = Matrix r 0 0 r 0 0 + where + r = fromInteger i hunk ./Graphics/PDF/Coordinates.hs 88 --- | Apply a transformation matrix to the current coordinate frame -applyMatrix :: Matrix -> Draw () -applyMatrix m@(Matrix a b c d e f) = do - multiplyCurrentMatrixWith m - tell . mconcat $[ serialize '\n' - , toPDF a - , serialize ' ' - , toPDF b - , serialize ' ' - , toPDF c - , serialize ' ' - , toPDF d - , serialize ' ' - , toPDF e - , serialize ' ' - , toPDF f - , serialize " cm" - ] +-- | Identity matrix +identity :: Matrix +identity = Matrix 1 0 0 1 0 0 hunk ./Graphics/PDF/Coordinates.hs 98 + +-- | Applies a matrix to a point +transform :: Matrix -> Point -> Point +transform (Matrix x0 y0 x1 y1 x2 y2) (x :+ y) = (x*x0 + y*x1 + x2) :+ (x*y0 + y*y1 + y2) + hunk ./Graphics/PDF/Draw.hs 67 + , applyMatrix hunk ./Graphics/PDF/Draw.hs 87 +import Graphics.PDF.Coordinates hunk ./Graphics/PDF/Draw.hs 93 - --- | A transformation matrix. An affine transformation a b c d e f --- --- @ --- a b 0 --- c d 0 --- e f 1 --- @ - -data Matrix = Matrix !PDFFloat !PDFFloat !PDFFloat !PDFFloat !PDFFloat !PDFFloat deriving (Eq) - --- | Identity matrix -identity :: Matrix -identity = Matrix 1.0 0 0 1.0 0 0 - -instance Show Matrix where - show (Matrix ma mb mc md me mf) = "Matrix " ++ (unwords [(show ma),(show mb),(show mc),(show md),(show me),(show mf)]) - -instance Num Matrix where - -- Matrix addition - (+) (Matrix ma mb mc md me mf ) (Matrix na nb nc nd ne nf) = - Matrix (ma+na) (mb+nb) (mc+nc) (md+nd) (me+ne) (mf+nf) - (*) (Matrix ma mb mc md me mf) (Matrix na nb nc nd ne nf) = - Matrix (ma*na+mb*nc) (ma*nb+mb*nd) (mc*na+md*nc) (mc*nb +md*nd) (me*na+mf*nc+ne) (me*nb+mf*nd+nf) - negate (Matrix ma mb mc md me mf ) = - Matrix (-ma) (-mb) (-mc) (-md) (-me) (-mf) - abs m = m - signum _ = identity - fromInteger i = Matrix r 0 0 r 0 0 - where - r = fromInteger i - hunk ./Graphics/PDF/Draw.hs 701 + + +-- | Apply a transformation matrix to the current coordinate frame +applyMatrix :: Matrix -> Draw () +applyMatrix m@(Matrix a b c d e f) = do + multiplyCurrentMatrixWith m + tell . mconcat $[ serialize '\n' + , toPDF a + , serialize ' ' + , toPDF b + , serialize ' ' + , toPDF c + , serialize ' ' + , toPDF d + , serialize ' ' + , toPDF e + , serialize ' ' + , toPDF f + , serialize " cm" + ] hunk ./Graphics/PDF/LowLevel/Types.hs 18 -import Text.Printf hunk ./Graphics/PDF/LowLevel/Types.hs 21 -import System.Random hunk ./Graphics/PDF/Shapes.hs 15 - -- ** Types - Point hunk ./Graphics/PDF/Shapes.hs 16 - , moveto + moveto hunk ./Test/Makefile 8 - ./test +RTS -p + ./test +RTS -p -hc hunk ./Test/Penrose.hs 109 - divide 4 B - divide 4 B' + let r = 4 + divide r B + divide r B' hunk ./Graphics/PDF/Draw.hs 1 +{-# OPTIONS_GHC -fglasgow-exts #-} hunk ./Graphics/PDF/LowLevel/Types.hs 24 +import Data.Complex hunk ./Graphics/PDF/LowLevel/Types.hs 70 + +instance PdfObject (Complex PDFFloat) where + toPDF (x :+ y) = mconcat [ serialize x + , serialize ' ' + , serialize y + ] hunk ./Graphics/PDF/Shapes.hs 85 - moveto x0 y0 - lineto x1 y1 + moveto (x0 :+ y0) + lineto (x1 :+ y1) hunk ./Graphics/PDF/Shapes.hs 105 - beginPath x0 y0 - addBezierCubic (x0+width*kappa) y0 x1 (y1-height*kappa) x1 y1 + beginPath (x0 :+ y0) + addBezierCubic ((x0+width*kappa) :+ y0) (x1 :+ (y1-height*kappa)) (x1 :+ y1) hunk ./Graphics/PDF/Shapes.hs 117 - beginPath xm y0 - addBezierCubic (xm + w) y0 x1 (ym - h) x1 ym - addBezierCubic x1 (ym + h) (xm + w) y1 xm y1 - addBezierCubic (xm - w) y1 x0 (ym + h) x0 ym - addBezierCubic x0 (ym - h) (xm - w) y0 xm y0 + beginPath (xm :+ y0) + addBezierCubic ((xm + w) :+ y0) (x1 :+ (ym - h)) (x1 :+ ym) + addBezierCubic (x1 :+ (ym + h)) ((xm + w) :+ y1) (xm :+ y1) + addBezierCubic ((xm - w) :+ y1) (x0 :+ (ym + h)) (x0 :+ ym) + addBezierCubic (x0 :+ (ym - h)) ((xm - w) :+ y0) (xm :+ y0) hunk ./Graphics/PDF/Shapes.hs 130 - beginPath (x0+rw) y0 - addLineToPath (x1-rw) y0 - addBezierCubic ((x1-rw) + w) y0 x1 (y0+rh - h) x1 (y0+rh) - addLineToPath x1 (y1-rh) - addBezierCubic x1 ((y1-rh) + h) (x1-rw + w) y1 (x1-rw) y1 - addLineToPath (x0+rw) y1 - addBezierCubic (x0 + rw - w) y1 x0 (y1-rh + h) x0 (y1-rh) - addLineToPath x0 (y0+rh) - addBezierCubic x0 (y0 + rh - h) (x0 + rw - w) y0 (x0 + rw) y0 - addLineToPath (x1-rw) y0 + beginPath ((x0+rw) :+ y0) + addLineToPath ((x1-rw) :+ y0) + addBezierCubic ((x1-rw + w) :+ y0) (x1 :+ (y0+rh - h)) (x1 :+ (y0+rh)) + addLineToPath (x1 :+ (y1-rh)) + addBezierCubic (x1 :+ (y1-rh + h)) ((x1-rw + w) :+ y1) ((x1-rw) :+ y1) + addLineToPath ((x0+rw) :+ y1) + addBezierCubic ((x0+rw - w) :+ y1) (x0 :+ (y1-rh + h)) (x0 :+ (y1-rh)) + addLineToPath (x0 :+ (y0+rh)) + addBezierCubic (x0 :+ (y0+rh - h)) ((x0+rw - w) :+ y0) ((x0+rw) :+ y0) + addLineToPath ((x1-rw) :+ y0) hunk ./Graphics/PDF/Shapes.hs 206 --- | Begin a new path at position x y -beginPath :: PDFFloat -- ^ Horizontal coordinate - -> PDFFloat -- ^ Vertical coordinate +-- | Begin a new path at a position +beginPath :: Point hunk ./Graphics/PDF/Shapes.hs 217 --- from the current point to the point (x3 , y3 ), using (x1 , y1 ) and +-- from the current point to the point (x3 , y3), using (x1 , y1 ) and hunk ./Graphics/PDF/Shapes.hs 219 -addBezierCubic :: PDFFloat -- ^ x1 - -> PDFFloat -- ^ y1 - -> PDFFloat -- ^ x2 - -> PDFFloat -- ^ y2 - -> PDFFloat -- ^ x3 - -> PDFFloat -- ^ y3 +addBezierCubic :: Point + -> Point + -> Point hunk ./Graphics/PDF/Shapes.hs 223 -addBezierCubic x1 y1 x2 y2 x3 y3 = +addBezierCubic b c d = hunk ./Graphics/PDF/Shapes.hs 225 - , toPDF x1 + , toPDF b hunk ./Graphics/PDF/Shapes.hs 227 - , toPDF y1 + , toPDF c hunk ./Graphics/PDF/Shapes.hs 229 - , toPDF x2 - , serialize ' ' - , toPDF y2 - , serialize ' ' - , toPDF x3 - , serialize ' ' - , toPDF y3 + , toPDF d hunk ./Graphics/PDF/Shapes.hs 234 -moveto :: PDFFloat -- ^ Horizontal coordinate - -> PDFFloat -- ^ Vertical coordinate +moveto :: Point hunk ./Graphics/PDF/Shapes.hs 236 -moveto x y = +moveto a = hunk ./Graphics/PDF/Shapes.hs 238 - , toPDF x - , serialize ' ' - , toPDF y + , toPDF a hunk ./Graphics/PDF/Shapes.hs 243 -lineto :: PDFFloat -- ^ Horizontal coordinate - -> PDFFloat -- ^ Vertical coordinate - -> Draw () -lineto x y = +lineto :: Point + -> Draw () +lineto a = hunk ./Graphics/PDF/Shapes.hs 247 - , toPDF x - , serialize ' ' - , toPDF y + , toPDF a hunk ./Graphics/PDF/Shapes.hs 252 -addLineToPath :: PDFFloat -- ^ Horizontal coordinate - -> PDFFloat -- ^ Vertical coordinate +addLineToPath :: Point hunk ./Graphics/PDF/Shapes.hs 254 -addLineToPath x y = +addLineToPath a = hunk ./Graphics/PDF/Shapes.hs 256 - , toPDF x - , serialize ' ' - , toPDF y + , toPDF a hunk ./Graphics/PDF/Shapes.hs 264 -addPolygonToPath ((x0 :+ y0) : ls) = do - moveto x0 y0 - mapM_ (\(x :+ y) -> addLineToPath x y) ls +addPolygonToPath (l : ls) = do + moveto l + mapM_ addLineToPath ls hunk ./Graphics/PDF/Shapes.hs 295 - hunk ./Graphics/PDF/Coordinates.hs 34 -data Angle = Degree PDFFloat -- ^ Angle in degrees - | Radian PDFFloat -- ^ Angle in radians +data Angle = Degree !PDFFloat -- ^ Angle in degrees + | Radian !PDFFloat -- ^ Angle in radians hunk ./Graphics/PDF/Draw.hs 21 + , readDrawST + , writeDrawST + , modifyDrawST + , DrawTuple() + , penPosition hunk ./Graphics/PDF/Draw.hs 150 - , builderRef :: STRef s BU.Builder + , builderRef :: STRef s BU.Builder + , penPosition :: STRef s Point hunk ./Graphics/PDF/Draw.hs 195 +readDrawST :: (forall s. DrawTuple s -> STRef s a) -> Draw a +readDrawST f = Draw $ \env -> readSTRef (f env) + +writeDrawST :: (forall s. DrawTuple s -> STRef s a) -> a -> Draw () +writeDrawST f x = Draw $ \env -> writeSTRef (f env) x + +modifyDrawST :: (forall s. DrawTuple s -> STRef s a) -> (a -> a) -> Draw () +modifyDrawST f g = Draw $ \env -> modifySTRef (f env) g + hunk ./Graphics/PDF/Draw.hs 247 + posRef <- newSTRef 0 hunk ./Graphics/PDF/Draw.hs 251 + , penPosition = posRef hunk ./Graphics/PDF/Shapes.hs 18 + , arcto + , curveto hunk ./Graphics/PDF/Shapes.hs 94 -data Rectangle = Rectangle PDFFloat PDFFloat PDFFloat PDFFloat deriving(Eq) +data Rectangle = Rectangle !Point !Point deriving (Eq) hunk ./Graphics/PDF/Shapes.hs 96 - addShape (Rectangle x0 y0 x1 y1) = do - let poly = [(x0 :+ y0),(x1 :+ y0),(x1 :+ y1),(x0 :+ y1)] - addPolygonToPath poly - closePath + addShape (Rectangle a b) + = tell . mconcat $ [ serialize '\n' + , toPDF a + , serialize ' ' + , toPDF (b - a) + , serialize " re" ] hunk ./Graphics/PDF/Shapes.hs 154 +currentPosition = readDrawST penPosition + hunk ./Graphics/PDF/Shapes.hs 229 -addBezierCubic b c d = - tell . mconcat $[ serialize "\n" - , toPDF b - , serialize ' ' - , toPDF c - , serialize ' ' - , toPDF d - , serialize " c" - ] +addBezierCubic b c d = do + tell . mconcat $ [ serialize "\n" + , toPDF b + , serialize ' ' + , toPDF c + , serialize ' ' + , toPDF d + , serialize " c" + ] + writeDrawST penPosition d hunk ./Graphics/PDF/Shapes.hs 243 -moveto a = - tell . mconcat $[ serialize "\n" - , toPDF a - , serialize " m" - ] +moveto a = do + tell . mconcat $ [ serialize "\n" + , toPDF a + , serialize " m" + ] + writeDrawST penPosition a hunk ./Graphics/PDF/Shapes.hs 253 -lineto a = +lineto a = do hunk ./Graphics/PDF/Shapes.hs 256 - , serialize " l s" + , serialize " l" hunk ./Graphics/PDF/Shapes.hs 258 - --- | Add a line from current point to the one specified by lineto + writeDrawST penPosition a + +curveto :: Point -> Point -> Point -> Draw () +curveto = addBezierCubic + +-- | Approximate a circular arc by one cubic bezier curve. +-- larger extents mean larger distortions +arcto :: Angle -- ^ Extent of arc + -> Point -- ^ Center of arc + -> Draw () +arcto extent + = let theta = toRadian extent + kappa = - 4 / 3 * tan (theta / 4) + cis_theta = cis theta + in if theta == 0 + then \_center -> return () + else \center -> do + a <- readDrawST penPosition + let delta = center - a + delta' = scalePt kappa (rot90 delta) + d = center + delta * cis_theta + c = d - delta' + b = a + delta' + curveto b c d + +rot90 (x :+ y) = ((-y) :+ x) + hunk ./Graphics/PDF/Shapes.hs 287 -addLineToPath a = - tell . mconcat $[ serialize "\n" - , toPDF a - , serialize " l" - ] +addLineToPath = lineto hunk ./Graphics/PDF/Typesetting/Horizontal.hs 23 +import Graphics.PDF.Coordinates hunk ./Graphics/PDF/Typesetting/Horizontal.hs 213 - (fromJust . sentenceStyle $ style) (Rectangle x (y - hl) (x+w') (y)) (drawTextLine style l' x y') + (fromJust . sentenceStyle $ style) (Rectangle (x :+ (y - hl)) ((x+w') :+ y)) (drawTextLine style l' x y') hunk ./Graphics/PDF/Typesetting/Horizontal.hs 315 - (fromJust . wordStyle $ style) (Rectangle x (y' - de) (x+w) (y' - de + he)) DrawGlue (return ()) + (fromJust . wordStyle $ style) (Rectangle (x :+ (y' - de)) ((x+w) :+ (y' - de + he))) DrawGlue (return ()) hunk ./Graphics/PDF/Typesetting/Horizontal.hs 327 - (fromJust . wordStyle $ style) (Rectangle x (y' - de) (x+w) (y' - de + he)) DrawWord (drawText $ drawTheTextBox OneBlock style x y' (Just t)) + (fromJust . wordStyle $ style) (Rectangle (x :+ (y' - de)) ((x+w) :+ (y' - de + he))) DrawWord (drawText $ drawTheTextBox OneBlock style x y' (Just t)) hunk ./Graphics/PDF/Typesetting/Layout.hs 41 +import Graphics.PDF.Coordinates hunk ./Graphics/PDF/Typesetting/Layout.hs 112 - (fromJust . interline $ style) $ Rectangle (x+delta) (y-h) (x+w+delta) y + (fromJust . interline $ style) $ Rectangle ((x+delta) :+ (y-h)) ((x+w+delta) :+ y) hunk ./Graphics/PDF/Typesetting/Layout.hs 180 -containerContentRectangle c = Rectangle (x+l) (y-th) (x+r) y +containerContentRectangle c = Rectangle ((x+l) :+ (y-th)) ((x+r) :+ y) hunk ./Graphics/PDF/Typesetting/Layout.hs 323 - (fromJust . paragraphStyle $ style) (Rectangle xleft (y'- h') xright (y')) (recurseStrokeVBoxes 1 l' xa y') + (fromJust . paragraphStyle $ style) (Rectangle (xleft :+ (y'- h')) (xright :+ y')) (recurseStrokeVBoxes 1 l' xa y') hunk ./Graphics/PDF/Typesetting.hs 115 -displayFormattedText (Rectangle xa ya xb yb) defaultVStyle defaultHStyle t = +displayFormattedText (Rectangle (xa :+ ya) (xb :+ yb)) defaultVStyle defaultHStyle t = hunk ./Graphics/PDF/Typesetting.hs 442 - Rectangle xa ya xb yb = containerContentRectangle c' + Rectangle (xa :+ ya) (xb :+ yb) = containerContentRectangle c' hunk ./Graphics/PDF/Typesetting.hs 457 - r = Rectangle (xa + dx) (ya + dy) (xb + dx) (yb + dy) + r = Rectangle ((xa + dx) :+ (ya + dy)) ((xb + dx) :+ (yb + dy)) hunk ./Test/test.hs 1 +{-# OPTIONS_GHC -fglasgow-exts #-} hunk ./Test/test.hs 35 - stroke $ Rectangle 10 (200.0 - (getDescent f)) (10.0 + textWidth f t) (200.0 - getDescent f + getHeight f) + stroke $ Rectangle (10 :+ (200.0 - (getDescent f))) ((10.0 + textWidth f t) :+ (200.0 - getDescent f + getHeight f)) hunk ./Test/test.hs 41 - stroke $ Rectangle 0 0 200 100 + stroke $ Rectangle 0 (200 :+ 100) hunk ./Test/test.hs 56 - paintWithShading (RadialShading 0 0 50 0 0 600 (Rgb 1 0 0) (Rgb 0 0 1)) (addShape $ Rectangle 0 0 300 300) + paintWithShading (RadialShading 0 0 50 0 0 600 (Rgb 1 0 0) (Rgb 0 0 1)) (addShape $ Rectangle 0 (300 :+ 300)) hunk ./Test/test.hs 116 - stroke $ Rectangle 0 0 200 100 + stroke $ Rectangle 0 (200 :+ 100) hunk ./Test/test.hs 194 - ws (Rectangle xa ya xb yb) DrawWord drawWord = do + ws (Rectangle (xa :+ ya) (xb :+ yb)) DrawWord drawWord = do hunk ./Test/test.hs 226 -crazyWord r@(Rectangle xa ya xb yb) DrawWord d = do +crazyWord r@(Rectangle (xa :+ ya) (xb :+ yb)) DrawWord d = do hunk ./Test/test.hs 233 -crazyWord (Rectangle xa ya xb yb) DrawGlue _ = do +crazyWord (Rectangle (xa :+ ya) (xb :+ yb)) DrawGlue _ = do hunk ./Test/test.hs 277 - charRect = Rectangle 0 (- getDescent f) w' (getHeight f - getDescent f) + charRect = Rectangle (0 :+ (- getDescent f)) (w' :+ (getHeight f - getDescent f)) hunk ./Test/test.hs 296 - paragraphStyle (BluePara _) = Just $ \(Rectangle xa ya xb yb) b -> do - let f = Rectangle (xa-3) (ya-3) (xb+3) (yb+3) + paragraphStyle (BluePara _) = Just $ \(Rectangle (xa :+ ya) (xb :+ yb)) b -> do + let f = Rectangle ((xa-3) :+ (ya-3)) ((xb+3) :+ (yb+3)) hunk ./Test/test.hs 308 -containerTest p (Rectangle xa ya xb yb) theText = +containerTest p (Rectangle (xa :+ ya) (xb :+ yb)) theText = hunk ./Test/test.hs 322 - stroke $ Rectangle x y (x+w) (ya-100-yb) + stroke $ Rectangle (x :+ y) ((x+w) :+ (ya-100-yb)) hunk ./Test/test.hs 449 - displayFormattedText (Rectangle 10 0 (10+100) 300) NormalPara Normal simpleText + displayFormattedText (Rectangle (10 :+ 0) ((10+100) :+ 300)) NormalPara Normal simpleText hunk ./Test/test.hs 454 - displayFormattedText (Rectangle 10 0 (10+maxw) 400) NormalPara Normal myText + displayFormattedText (Rectangle (10 :+ 0) ((10+maxw) :+ 400)) NormalPara Normal myText hunk ./Test/test.hs 458 - displayFormattedText (Rectangle 10 0 (10+maxw) 300) NormalPara Normal debugText + displayFormattedText (Rectangle (10 :+ 0) ((10+maxw) :+ 300)) NormalPara Normal debugText hunk ./Test/test.hs 460 - let r = (Rectangle 10 200 (10+maxw) 300) + let r = (Rectangle (10 :+ 200) ((10+maxw) :+ 300)) hunk ./Test/test.hs 474 - 4 -> displayFormattedText ((Rectangle 10 0 (10+maxw) 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) standardStyleTest + 4 -> displayFormattedText (Rectangle (10 :+ 0) ((10+maxw) :+ 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) standardStyleTest hunk ./Test/test.hs 477 - stroke $ Rectangle 10 300 (10+maxw) 400 - displayFormattedText ((Rectangle 10 300 (10+maxw) 400)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + stroke $ Rectangle (10 :+ 300) ((10+maxw) :+ 400) + displayFormattedText (Rectangle (10 :+ 300) ((10+maxw) :+ 400)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do hunk ./Test/test.hs 483 - stroke $ Rectangle 10 200 (10+maxw) 300 - displayFormattedText ((Rectangle 10 200 (10+maxw) 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + stroke $ Rectangle (10 :+ 200) ((10+maxw) :+ 300) + displayFormattedText (Rectangle (10 :+ 200) ((10+maxw) :+ 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do hunk ./Test/test.hs 489 - stroke $ Rectangle 10 100 (10+maxw) 200 - displayFormattedText ((Rectangle 10 100 (10+maxw) 200)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + stroke $ Rectangle (10 :+ 100) ((10+maxw) :+ 200) + displayFormattedText (Rectangle (10 :+ 100) ((10+maxw) :+ 200)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do hunk ./Test/test.hs 495 - stroke $ Rectangle 10 0 (10+maxw) 100 + stroke $ Rectangle (10 :+ 0) ((10+maxw) :+ 100) hunk ./Test/test.hs 498 - displayFormattedText ((Rectangle 10 0 (10+maxw) 100)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + displayFormattedText (Rectangle (10 :+ 0) ((10+maxw) :+ 100)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do hunk ./Test/test.hs 505 - stroke $ Rectangle 10 300 (10+maxw) 400 - displayFormattedText ((Rectangle 10 300 (10+maxw) 400)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + stroke $ Rectangle (10 :+ 300) ((10+maxw) :+ 400) + displayFormattedText (Rectangle (10 :+ 300) ((10+maxw) :+ 400)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do hunk ./Test/test.hs 511 - stroke $ Rectangle 10 200 (10+maxw) 300 - displayFormattedText ((Rectangle 10 200 (10+maxw) 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + stroke $ Rectangle (10 :+ 200) ((10+maxw) :+ 300) + displayFormattedText (Rectangle (10 :+ 200) ((10+maxw) :+ 300)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do hunk ./Test/test.hs 517 - stroke $ Rectangle 10 100 (10+maxw) 200 - displayFormattedText ((Rectangle 10 100 (10+maxw) 200)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + stroke $ Rectangle (10 :+ 100) ((10+maxw) :+ 200) + displayFormattedText (Rectangle (10 :+ 100) ((10+maxw) :+ 200)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do hunk ./Test/test.hs 523 - stroke $ Rectangle 10 0 (10+maxw) 100 - displayFormattedText ((Rectangle 10 0 (10+maxw) 100)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do + stroke $ Rectangle (10 :+ 0) ((10+maxw) :+ 100) + displayFormattedText (Rectangle (10 :+ 0) ((10+maxw) :+ 100)) NormalParagraph (Font (PDFFont Times_Roman 10) black black) $ do hunk ./Test/test.hs 527 - _ -> displayFormattedText ((Rectangle 0 300 (10+maxw) 300)) NormalPara Normal myText + _ -> displayFormattedText (Rectangle (0 :+ 300) ((10+maxw) :+ 300)) NormalPara Normal myText hunk ./Test/test.hs 580 - containerTest page3c (Rectangle 10 300 100 100) testText - containerTest page3c (Rectangle 210 300 200 100) $ do + containerTest page3c (Rectangle (10 :+ 300) (100 :+ 100)) testText + containerTest page3c (Rectangle (210 :+ 300) (200 :+ 100)) $ do hunk ./Graphics/PDF/Shapes.hs 15 - -- ** Lines + -- ** Paths hunk ./Graphics/PDF/Shapes.hs 20 - -- ** Paths hunk ./Graphics/PDF/Shapes.hs 153 -currentPosition = readDrawST penPosition - hunk ./Graphics/PDF/Shapes.hs 261 --- larger extents mean larger distortions +-- larger arc angles mean larger distortions hunk ./Graphics/PDF/Shapes.hs 267 - kappa = - 4 / 3 * tan (theta / 4) + kappa = 4 / 3 * tan (theta / 4) hunk ./Graphics/PDF/Shapes.hs 269 + rot90 (x :+ y) = ((-y) :+ x) hunk ./Graphics/PDF/Shapes.hs 274 - let delta = center - a + let delta = a - center hunk ./Graphics/PDF/Shapes.hs 277 - c = d - delta' + c = d - delta' * cis_theta hunk ./Graphics/PDF/Shapes.hs 281 -rot90 (x :+ y) = ((-y) :+ x) - hunk ./NEWS.txt 1 -WHAT'S NEW IN HPDF 1.3 +WHAT'S NEW IN HPDF 1.4 hunk ./NEWS.txt 3 -1 - Can be built with ghc 6.8.1 and ghc 6.6 if you have the most recent Cabal and update a few libraries ; -2 - Bug corrections in the line breaking algorithm ; -3 - Automatic hyphenation algorithm (default Language is English). To add new language you have to use hyphenation patterns like in TeX. -Look at Graphics/PDF/Hyphenate.hs and Graphics/PDF/Hyphenate/English.hs +Lot's of contributions from Leon Smith ! Thank you. Here is a summary: hunk ./NEWS.txt 5 +A - Changes by Leon +=================== +1 - Huge speed improvement of the draw monad ; +2 - New implementation of shapes (Rectangle, curveto, arcto, point datatype) ; +3 - Cleaning of the API (coordinates, shapes) ; + +B - Changes by alpheccar +========================= +1 - Lots of bug corrections for typesetting ; +2 - An API to draw text boxes hunk ./HPDF.cabal 6 -Copyright: Copyright (c) 2007, alpheccar +Copyright: Copyright (c) 2007-2008, alpheccar hunk ./HPDF.cabal 10 +build-type: Simple hunk ./HPDF.cabal 2 -Version: 1.4 +Version: 1.5 hunk ./Graphics/PDF/Data/PDFTree.hs 1 -{-# OPTIONS -cpp -fglasgow-exts -fno-bang-patterns #-} +{-# OPTIONS -cpp -fglasgow-exts -XNoBangPatterns #-} hunk ./Graphics/PDF/Data/Trie.hs 28 +#if __GLASGOW_HASKELL__ >= 610 +myLookup :: Ord k => k -> M.Map k a ->[a] +myLookup k d = case M.lookup k d of + Just r -> [r] + _ -> [] +#endif + hunk ./Graphics/PDF/Data/Trie.hs 46 +#if __GLASGOW_HASKELL__ >= 610 +lookup (c:s) (Trie Nothing tc) = (myLookup c tc >>= lookup s) +lookup (c:s) (Trie (Just tn) tc) = tn:(myLookup c tc >>= lookup s) +#else hunk ./Graphics/PDF/Data/Trie.hs 52 +#endif hunk ./Graphics/PDF/Image.hs 43 + +#if __GLASGOW_HASKELL__ >= 610 +import Control.OldException(ioErrors) +#endif hunk ./Test/Makefile 2 - ghc -o test -ffi -cpp -Wall -funbox-strict-fields -fglasgow-exts -O2 -hidir interfaces -odir bin -optc-I../c -i.. ../c/metrics.c ../c/conversion.c --make test.hs + ghc -o test -XForeignFunctionInterface -cpp -Wall -funbox-strict-fields -fglasgow-exts -O2 -hidir interfaces -odir bin -optc-I../c -i.. ../c/metrics.c ../c/conversion.c --make test.hs hunk ./Test/Makefile 5 - ghc -o test -prof -auto-all -ffi -cpp -Wall -funbox-strict-fields -fglasgow-exts -O2 -hidir interfaces -odir bin -optc-I../c -i.. ../c/metrics.c ../c/conversion.c --make test.hs + ghc -o test -prof -auto-all -XForeignFunctionInterface -cpp -Wall -funbox-strict-fields -fglasgow-exts -O2 -hidir interfaces -odir bin -optc-I../c -i.. ../c/metrics.c ../c/conversion.c --make test.hs hunk ./HPDF.cabal 2 -Version: 1.5 -cabal-version: >=1.2 +Version: 1.4.1 +cabal-version: >=1.6 hunk ./HPDF.cabal 11 -tested-with: GHC==6.8.1 +tested-with: GHC==6.8.1, GHC==6.10.1 hunk ./HPDF.cabal 32 - build-depends: base >= 3, containers, random >= 1.0, bytestring >= 0.9, array >= 0.1, zlib >= 0.3, binary >= 0.3, mtl + build-depends: base >= 4 , containers, random >= 1.0, bytestring >= 0.9, array >= 0.1, zlib >= 0.5, binary >= 0.4, mtl hunk ./HPDF.cabal 34 - build-depends: base, haskell98, mtl ,zlib >= 0.3, binary >= 0.3 + build-depends: base >= 3, haskell98, mtl ,zlib >= 0.5, binary >= 0.4 hunk ./HPDF.cabal 2 -Version: 1.4.1 +Version: 1.4.2 hunk ./HPDF.cabal 32 - build-depends: base >= 4 , containers, random >= 1.0, bytestring >= 0.9, array >= 0.1, zlib >= 0.5, binary >= 0.4, mtl + build-depends: base >= 3 && < 5 , containers, random >= 1.0, bytestring >= 0.9, array >= 0.1, zlib >= 0.5, binary >= 0.4, mtl hunk ./HPDF.cabal 34 - build-depends: base >= 3, haskell98, mtl ,zlib >= 0.5, binary >= 0.4 + build-depends: base >= 2 && < 3, haskell98, mtl ,zlib >= 0.5, binary >= 0.4 + if impl(ghc >= 6.10) + build-depends: base >= 4 hunk ./HPDF.cabal 91 +