diagrams-rasterific 1.3.1.9 → 1.4
raw patch · 7 files changed
+231/−137 lines, 7 filesdep +file-embeddep −splitdep −unixdep ~Rasterificdep ~basedep ~diagrams-corePVP ok
version bump matches the API change (PVP)
Dependencies added: file-embed
Dependencies removed: split, unix
Dependency ranges changed: Rasterific, base, diagrams-core, diagrams-lib, lens, optparse-applicative
API changes (from Hackage documentation)
+ Diagrams.Backend.Rasterific: LoopingForever :: GifLooping
+ Diagrams.Backend.Rasterific: LoopingNever :: GifLooping
+ Diagrams.Backend.Rasterific: LoopingRepeat :: Word16 -> GifLooping
+ Diagrams.Backend.Rasterific: PaletteOptions :: PaletteCreationMethod -> Bool -> Int -> PaletteOptions
+ Diagrams.Backend.Rasterific: [enableImageDithering] :: PaletteOptions -> Bool
+ Diagrams.Backend.Rasterific: [paletteColorCount] :: PaletteOptions -> Int
+ Diagrams.Backend.Rasterific: [paletteCreationMethod] :: PaletteOptions -> PaletteCreationMethod
+ Diagrams.Backend.Rasterific: animatedGif :: TypeableFloat n => FilePath -> SizeSpec V2 n -> GifLooping -> GifDelay -> [QDiagram Rasterific V2 n Any] -> IO ()
+ Diagrams.Backend.Rasterific: data GifLooping :: *
+ Diagrams.Backend.Rasterific: data PaletteOptions :: *
+ Diagrams.Backend.Rasterific: defaultPaletteOptions :: PaletteOptions
+ Diagrams.Backend.Rasterific: rasterGif :: TypeableFloat n => SizeSpec V2 n -> GifLooping -> PaletteOptions -> [(QDiagram Rasterific V2 n Any, Int)] -> Either String ByteString
+ Diagrams.Backend.Rasterific: rasterRgb8 :: TypeableFloat n => SizeSpec V2 n -> QDiagram Rasterific V2 n Any -> Image PixelRGB8
+ Diagrams.Backend.Rasterific: renderPdf :: TypeableFloat n => Int -> Int -> FilePath -> SizeSpec V2 n -> QDiagram Rasterific V2 n Any -> IO ()
+ Diagrams.Backend.Rasterific: type GifDelay = Int
+ Diagrams.Backend.Rasterific.CmdLine: instance Diagrams.Backend.CmdLine.ToResult [(Diagrams.Core.Types.QDiagram Diagrams.Backend.Rasterific.Rasterific Linear.V2.V2 n Data.Monoid.Any, Codec.Picture.Gif.GifDelay)]
+ Diagrams.Backend.Rasterific.CmdLine: uniformGifMain :: GifDelay -> [Diagram Rasterific] -> IO ()
Files
- CHANGELOG.md +30/−0
- LICENSE +5/−3
- README.md +6/−4
- diagrams-rasterific.cabal +8/−11
- src/Diagrams/Backend/Rasterific.hs +94/−14
- src/Diagrams/Backend/Rasterific/CmdLine.hs +70/−92
- src/Diagrams/Backend/Rasterific/Text.hs +18/−13
CHANGELOG.md view
@@ -1,3 +1,19 @@+## [v1.4](https://github.com/diagrams/diagrams-rasterific/tree/v1.4) (2016-10-26)++* **New features**++ - Can now output PDFs.++ - Font files are now embedded with `file-embed`.++ - Various functions for better GIF support.++ - Support for group opacity.++* **New instances**++ - `ToResult` instance for animated GIFs.+ ## [v1.3.1.9](https://github.com/diagrams/diagrams-rasterific/tree/v1.3.1.9) (2016-08-19) - Require `optparse-applicative-0.13`@@ -43,6 +59,20 @@ ## [v1.3.1.2](https://github.com/diagrams/diagrams-rasterific/tree/v1.3.1.2) (2015-05-26) [Full Changelog](https://github.com/diagrams/diagrams-rasterific/compare/v1.3.1.1...v1.3.1.2)++## [v1.3.1.1](http://github.com/diagrams/diagrams-rasterific/tree/v1.3.1.1)+(2015-04-25)++- New module `Diagrams.Backend.Rasterific.Text`+- New `texterific` function exported from+ `Diagrams.Backend.Rasterific`+- Fixes:+ - Fix bounding box calculation for text+ - Fix `BoxAlignedText` positioning++## [v1.3.1](http://github.com/diagrams/diagrams-rasterific/tree/v1.3.1.0) (2015-04-25)++- group opacity ## [v1.3](http://github.com/diagrams/diagrams-rasterific/tree/v1.3) (2015-04-19)
LICENSE view
@@ -1,11 +1,13 @@-Copyright (c) 2014 diagrams-rasterific team:+Copyright (c) 2014-2016 diagrams-rasterific team: Daniel Bergey <bergey@alum.mit.edu> Vincent Berthoux <vincent.berthoux@gmail.com> Christopher Chalmers <c.chalmers@me.com>- Anthony Cowley+ Anthony Cowley <acowley@gmail.com>+ Sylvain HENRY <hsyl20@gmail.com> Jeffrey Rosenbluth <jeffrey.rosenbluth@gmail.com>- Ryan Scott+ Ryan Scott <ryan.gl.scott@ku.edu>+ Robert Vollmert <rfvollmert@gmail.com> Ryan Yates <fryguybob@gmail.com> Brent Yorgey <byorgey@ciss.upenn.edu>
README.md view
@@ -1,10 +1,12 @@ diagrams-rasterific =================== -_diagrams-rasterific_ is a an Rasterific backend for [diagrams]. Diagrams is a powerful,-flexible, declarative domain-specific language for creating vector graphics,-using the [Haskell programming language][haskell]. It supports png, tif, bmp,-jpg and animated GIF output.+_diagrams-rasterific_ is a [Rasterific][rasterific] backend for [diagrams].+It supports png, tif, bmp, jpg, pdf, and animated GIF output. +Diagrams is a powerful, flexible, declarative domain-specific language+for creating vector graphics, using the [Haskell programming language][haskell].++[rasterific]: https://github.com/Twinside/Rasterific [diagrams]: http://projects.haskell.org/diagrams/ [haskell]: http://www.haskell.org/haskellwiki/Haskell
diagrams-rasterific.cabal view
@@ -1,5 +1,5 @@ name: diagrams-rasterific-version: 1.3.1.9+version: 1.4 synopsis: Rasterific backend for diagrams. description: A full-featured backend for rendering diagrams using the Rasterific rendering engine.@@ -13,7 +13,7 @@ build-type: Simple data-files: fonts/*.ttf extra-source-files: README.md, CHANGELOG.md-tested-with: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.1+tested-with: GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.2, GHC == 8.0.1 cabal-version: >=1.10 Source-repository head type: git@@ -26,23 +26,20 @@ hs-source-dirs: src other-modules: Paths_diagrams_rasterific build-depends: base >= 4.2 && < 4.10,- diagrams-core >= 1.3 && < 1.4,- diagrams-lib >= 1.3 && < 1.4,+ diagrams-core >= 1.4 && < 1.5,+ diagrams-lib >= 1.4 && < 1.5, hashable >= 1.1 && < 1.3,- Rasterific >= 0.6.1 && < 0.7,+ Rasterific >= 0.6.1 && < 0.8, FontyFruity >= 0.5 && < 0.6, JuicyPixels >= 3.1.5 && < 3.3,- lens >= 4.0 && < 4.15,+ lens >= 4.0 && < 4.16, mtl >= 2.1 && < 2.3, data-default-class >= 0.0 && < 0.2, containers >= 0.5 && < 0.6, filepath >= 1.2 && < 1.5, optparse-applicative >= 0.13 && < 0.14, bytestring >= 0.9 && < 0.11,- split >= 0.1 && < 1.3-- if !os(windows)- cpp-options: -DCMDLINELOOP- Build-depends: unix >= 2.4 && < 2.8+ file-embed >= 0.0 && < 0.1 default-language: Haskell2010+ ghc-options: -Wall
src/Diagrams/Backend/Rasterific.hs view
@@ -7,6 +7,7 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE ViewPatterns #-}@@ -20,7 +21,7 @@ -- -- A full-featured rendering backend for diagrams using Rasterific, -- implemented natively in Haskell (making it easy to use on any--- platform). Can create png, tif, bmp, jpg, and animated GIFs.+-- platform). Can create png, tif, bmp, jpg, pdf, and animated GIFs. -- -- To invoke the Rasterific backend, you have three options. --@@ -67,35 +68,53 @@ -- ------------------------------------------------------------------------------- module Diagrams.Backend.Rasterific- ( Rasterific(..)+ ( -- * Rasterific backend+ Rasterific(..) , B -- rendering token , Options(..) + -- * Rendering , renderRasterific+ , renderPdf , size , writeJpeg+ , GifDelay+ , GifLooping (..)+ , animatedGif + -- * Text with envelopes , texterific , texterific' + -- * Internals+ -- | These are low level functions whose implimentaion may change in+ -- the future. They're exported because they can sometimes be+ -- useful.+ , PaletteOptions (..)+ , defaultPaletteOptions+ , rasterGif+ , rasterRgb8+ ) where import Diagrams.Core.Compile import Diagrams.Core.Transform (matrixHomRep) import Diagrams.Core.Types --import Diagrams.Prelude hiding (local, opacity)+import Diagrams.Prelude hiding (height, local,+ opacity, output, width) import Diagrams.TwoD.Adjust (adjustDia2D) import Diagrams.TwoD.Text hiding (Font) import Codec.Picture+import Codec.Picture.ColorQuant (defaultPaletteOptions) import Codec.Picture.Types (convertImage, convertPixel, dropTransparency, promoteImage) + import qualified Graphics.Rasterific as R import Graphics.Rasterific.Texture (Gradient, linearGradientTexture, radialGradientWithFocusTexture,@@ -108,6 +127,7 @@ import Control.Monad.Reader import Diagrams.Backend.Rasterific.Text +import Data.ByteString.Lazy (ByteString) import qualified Data.ByteString.Lazy as L (writeFile) import qualified Data.Foldable as F import Data.Hashable (Hashable (..))@@ -380,6 +400,8 @@ trl = moveOriginBy (r2 (fromIntegral w / 2, fromIntegral h / 2 :: n)) mempty p = rasterificPtTransf trl (R.V2 0 0) +-- Saving files --------------------------------------------------------+ -- | Render a 'Rasterific' diagram to a jpeg file with given quality -- (between 0 and 100). writeJpeg :: Word8 -> FilePath -> Result Rasterific V2 n -> IO ()@@ -387,17 +409,75 @@ where bs = encodeJpegAtQuality quality (pixelMap (convertPixel . dropTransparency) img) +-- | Render a 'Rasterific' diagram to a pdf file with given width and height+renderPdf :: TypeableFloat n => Int -> Int -> FilePath -> SizeSpec V2 n+ -> QDiagram Rasterific V2 n Any -> IO ()+renderPdf w h outFile spec d = L.writeFile outFile bs+ where+ bs = R.renderDrawingAtDpiToPDF w h 96 (runRenderM . runR . fromRTree $ rtree)+ rtree = rTree spec d++rTree :: TypeableFloat n => SizeSpec V2 n -> QDiagram Rasterific V2 n Any+ -> RTree Rasterific V2 n Annotation+rTree spec d = toRTree g2o d'+ where+ (_, g2o, d') = adjustDia Rasterific (RasterificOptions spec) d+ -- | Render a 'Rasterific' diagram to a file with the given size. The--- format is determined by the extension (@.png@, @.tif@, @.bmp@ and--- @.jpg@ supported. (jpeg quality is 80, use 'writeJpeg' to choose+-- format is determined by the extension (@.png@, @.tif@, @.bmp@, @.jpg@ and+-- @.pdf@ supported. (jpeg quality is 80, use 'writeJpeg' to choose -- quality).-renderRasterific :: TypeableFloat n => FilePath -> SizeSpec V2 n -> QDiagram Rasterific V2 n Any -> IO ()-renderRasterific outFile spec d = writer outFile img+renderRasterific :: TypeableFloat n => FilePath -> SizeSpec V2 n+ -> QDiagram Rasterific V2 n Any -> IO ()+renderRasterific outFile spec d =+ case takeExtension outFile of+ ".png" -> writePng outFile img+ ".tif" -> writeTiff outFile img+ ".bmp" -> writeBitmap outFile img+ ".jpg" -> writeJpeg 80 outFile img+ -- pdfs need to be handle separately since rasterific makes them+ -- directely from drawings. i.e. they don't need to be converted to images.+ ".pdf" -> renderPdf (round w) (round h) outFile spec d+ _ -> writePng outFile img where- writer = case takeExtension outFile of- ".png" -> writePng- ".tif" -> writeTiff- ".bmp" -> writeBitmap- ".jpg" -> writeJpeg 80- _ -> writePng img = renderDia Rasterific (RasterificOptions spec) d+ V2 w h = specToSize 100 spec++-- | Render a 'Rasterific' diagram to an animated gif with the given+-- size and uniform delay. Diagrams should be the same size.+animatedGif+ :: TypeableFloat n+ => FilePath+ -> SizeSpec V2 n+ -> GifLooping+ -> GifDelay -- ^ Delay in 100th of seconds ('Int')+ -> [QDiagram Rasterific V2 n Any] -> IO ()+animatedGif outFile sz gOpts i ds =+ case rasterGif sz gOpts defaultPaletteOptions (map (,i) ds) of+ Right bs -> L.writeFile outFile bs+ Left e -> putStrLn e++-- Gifs ----------------------------------------------------------------++-- | Turn a list of diagrams into a gif.+rasterGif+ :: TypeableFloat n+ => SizeSpec V2 n -- ^ Size of output (in pixels)+ -> GifLooping -- ^ looping options+ -> PaletteOptions -- ^ palette options+ -> [(QDiagram Rasterific V2 n Any, Int)] -- ^ Diagram zipped with its delay (100th of seconds)+ -> Either String ByteString+rasterGif sz gOpts pOpts ds = encodeGifImages gOpts (map pal imgs)+ where+ imgs = over (each . _1) (rasterRgb8 sz) ds+ pal (palettize pOpts -> (img,p), d) = (p, d, img)++-- | Render a 'Rasterific' diagram without an alpha channel.+rasterRgb8 :: TypeableFloat n+ => SizeSpec V2 n+ -> QDiagram Rasterific V2 n Any+ -> Image PixelRGB8+rasterRgb8 sz+ = pixelMap dropTransparency+ . renderDia Rasterific (RasterificOptions sz)+
src/Diagrams/Backend/Rasterific/CmdLine.hs view
@@ -1,19 +1,21 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-}+ {-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE CPP #-} ----------------------------------------------------------------------------- -- | -- Module : Diagrams.Backend.Rasterific.CmdLine--- Copyright : (c) 2014 Diagrams team (see LICENSE)+-- Copyright : (c) 2014-2015 Diagrams team (see LICENSE) -- License : BSD-style (see LICENSE) -- Maintainer : diagrams-discuss@googlegroups.com -- -- Convenient creation of command-line-driven executables for -- rendering diagrams using the Rasterific backend. Create--- png, tif, bmp, jpg or animated GIF files.+-- png, tif, bmp, jpg, pdf, or animated GIF files. -- -- * 'defaultMain' creates an executable which can render a single -- diagram at various options.@@ -57,69 +59,57 @@ -- ----------------------------------------------------------------------------- module Diagrams.Backend.Rasterific.CmdLine- (- -- * General form of @main@- -- $mainwith- mainWith+ (+ -- * General form of @main@+ -- $mainwith+ mainWith - -- * Supported forms of @main@- , defaultMain- , multiMain- , animMain- , gifMain+ -- * Supported forms of @main@+ , defaultMain+ , multiMain+ , animMain+ , gifMain+ , uniformGifMain - -- * GIF support- , GifOpts(..)+ -- * GIF support+ , GifOpts(..) - -- * Backend tokens- , Rasterific- , B- ) where+ -- * Backend tokens+ , Rasterific+ , B+ ) where import Diagrams.Backend.CmdLine import Diagrams.Backend.Rasterific import Diagrams.Prelude hiding (height, interval, option, output, width) -import Codec.Picture-import Codec.Picture.ColorQuant (defaultPaletteOptions)-import Codec.Picture.Types (dropTransparency)--import qualified Data.ByteString.Lazy as L (ByteString, writeFile)+import qualified Data.ByteString.Lazy as L (writeFile) import Options.Applicative -import Data.List.Split--+-- | 'mainWith' specialised to 'Diagram' 'Rasterific'. defaultMain :: Diagram Rasterific -> IO () defaultMain = mainWith instance TypeableFloat n => Mainable (QDiagram Rasterific V2 n Any) where- type MainOpts (QDiagram Rasterific V2 n Any) = (DiagramOpts, DiagramLoopOpts)+ type MainOpts (QDiagram Rasterific V2 n Any) = (DiagramOpts, DiagramLoopOpts) - mainRender (opts,loopOpts) d = do- chooseRender opts d- defaultLoopRender loopOpts+ mainRender (opts,loopOpts) d = do+ chooseRender opts d+ defaultLoopRender loopOpts chooseRender :: TypeableFloat n => DiagramOpts -> QDiagram Rasterific V2 n Any -> IO ()-chooseRender opts d =- case splitOn "." (opts ^. output) of- [""] -> putStrLn "No output file given."- ps | last ps `elem` ["png", "tif", "bmp", "jpg"] -> do- let img = renderDia Rasterific- ( RasterificOptions- (fromIntegral <$> mkSizeSpec2D (opts^.width) (opts^.height))- )- d- case last ps of- "png" -> writePng (opts^.output) img- "tif" -> writeTiff (opts^.output) img- "bmp" -> writeBitmap (opts^.output) img- "jpg" -> writeJpeg 80 (opts^.output) img- _ -> writePng (opts^.output) img- | otherwise -> putStrLn $ "Unknown file type: " ++ last ps+chooseRender opts d+ | null path = noFileError+ | otherwise = renderRasterific path sz d+ where+ path = opts^.output+ sz = fromIntegral <$> mkSizeSpec2D (opts^.width) (opts^.height) +noFileError :: IO ()+noFileError = putStrLn "No output file given. Specify output file with -o"+ -- | @multiMain@ is like 'defaultMain', except instead of a single -- diagram it takes a list of diagrams paired with names as input. -- The generated executable then takes a @--selection@ option@@ -143,10 +133,10 @@ multiMain = mainWith instance TypeableFloat n => Mainable [(String,QDiagram Rasterific V2 n Any)] where- type MainOpts [(String,QDiagram Rasterific V2 n Any)]- = (MainOpts (QDiagram Rasterific V2 n Any), DiagramMultiOpts)+ type MainOpts [(String,QDiagram Rasterific V2 n Any)]+ = (MainOpts (QDiagram Rasterific V2 n Any), DiagramMultiOpts) - mainRender = defaultMultiMainRender+ mainRender = defaultMultiMainRender -- | @animMain@ is like 'defaultMain', but renders an animation -- instead of a diagram. It takes as input an animation and produces@@ -168,15 +158,22 @@ animMain = mainWith instance TypeableFloat n => Mainable (Animation Rasterific V2 n) where- type MainOpts (Animation Rasterific V2 n) =- ((DiagramOpts, DiagramAnimOpts), DiagramLoopOpts)-- mainRender (opts, l) d = defaultAnimMainRender chooseRender output opts d >> defaultLoopRender l+ type MainOpts (Animation Rasterific V2 n) =+ ((DiagramOpts, DiagramAnimOpts), DiagramLoopOpts) + mainRender (opts, l) d = do+ defaultAnimMainRender chooseRender output opts d+ defaultLoopRender l +-- | Make an animated gif main by pairing diagrams with a delay ('Int'+-- measured in 100th seconds). gifMain :: [(Diagram Rasterific, GifDelay)] -> IO () gifMain = mainWith +-- | Make an animated gif main with the same delay for each diagram.+uniformGifMain :: GifDelay -> [Diagram Rasterific] -> IO ()+uniformGifMain i = mainWith . map (,i)+ -- | Extra options for animated GIFs. data GifOpts = GifOpts { _dither :: Bool , _noLooping :: Bool@@ -200,46 +197,27 @@ ( long "loop-repeat" <> help "Number of times to repeat" ) -instance TypeableFloat n => Mainable [(QDiagram Rasterific V2 n Any, GifDelay)] where- type MainOpts [(QDiagram Rasterific V2 n Any, GifDelay)] = (DiagramOpts, GifOpts)+-- | An animated GIF can be a result.+instance ToResult [(QDiagram Rasterific V2 n Any, GifDelay)] where+ type Args [(QDiagram Rasterific V2 n Any, GifDelay)] = ()+ type ResultOf [(QDiagram Rasterific V2 n Any, GifDelay)] = [(QDiagram Rasterific V2 n Any, GifDelay)] - mainRender = gifRender+ toResult ds _ = ds -encodeGifAnimation' :: [GifDelay] -> GifLooping -> Bool- -> [Image PixelRGB8] -> Either String L.ByteString-encodeGifAnimation' delays looping dithering lst =- encodeGifImages looping triples- where- triples = zipWith (\(x,z) y -> (x, y, z)) doubles delays- doubles = [(pal, img)- | (img, pal) <- palettize- defaultPaletteOptions {enableImageDithering=dithering} <$> lst]+instance TypeableFloat n => Mainable [(QDiagram Rasterific V2 n Any, GifDelay)] where+ type MainOpts [(QDiagram Rasterific V2 n Any, GifDelay)] = (DiagramOpts, GifOpts) -writeGifAnimation' :: FilePath -> [GifDelay] -> GifLooping -> Bool- -> [Image PixelRGB8] -> Either String (IO ())-writeGifAnimation' path delays looping dithering img =- L.writeFile path <$> encodeGifAnimation' delays looping dithering img+ mainRender (dOpts, gOpts) ids+ | null path = noFileError+ | otherwise = case rasterGif sz lOpts pOpts ids of+ Right bs -> L.writeFile path bs+ Left e -> putStrLn e+ where+ sz = fromIntegral <$> mkSizeSpec2D (dOpts^.width) (dOpts^.height)+ path = dOpts^.output+ lOpts+ | gOpts^.noLooping = LoopingNever+ | otherwise = maybe LoopingForever (LoopingRepeat . fromIntegral)+ (gOpts^.loopRepeat)+ pOpts = defaultPaletteOptions {enableImageDithering=gOpts^.dither} -gifRender :: TypeableFloat n => (DiagramOpts, GifOpts) -> [(QDiagram Rasterific V2 n Any, GifDelay)] -> IO ()-gifRender (dOpts, gOpts) lst =- case splitOn "." (dOpts^.output) of- [""] -> putStrLn "No output file given"- ps | last ps == "gif" -> do- let looping = if gOpts^.noLooping- then LoopingNever- else case gOpts^.loopRepeat of- Nothing -> LoopingForever- Just n -> LoopingRepeat (fromIntegral n)- dias = map fst lst- delays = map snd lst- spec = fromIntegral <$> mkSizeSpec2D (dOpts^.width) (dOpts^.height)- opts = RasterificOptions spec- imageRGB8s = map (pixelMap dropTransparency- . renderDia Rasterific opts) dias- result = writeGifAnimation' (dOpts^.output) delays- looping (gOpts^.dither)- imageRGB8s- case result of- Left s -> putStrLn s- Right io -> io- | otherwise -> putStrLn "File name must end with .gif"
src/Diagrams/Backend/Rasterific/Text.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TemplateHaskell #-} ------------------------------------------------------------------------------- -- |@@ -27,8 +28,9 @@ import Diagrams.Prelude import Diagrams.TwoD.Text hiding (Font) -import Paths_diagrams_rasterific (getDataFileName)-import System.IO.Unsafe (unsafePerformIO)+import Data.FileEmbed (embedDir)+import Data.ByteString (ByteString)+import Data.ByteString.Lazy (fromStrict) -- | Get the 'BoundingBox' for some font with the origin at the start of -- the baseline.@@ -51,7 +53,7 @@ (getEnvelope bb) (getTrace bb) mempty- (boundingBoxQuery bb)+ (getQuery bb) where bb = textBoundingBox fnt (PointSize 1) s fnt = fromFontStyle fs fw@@ -72,23 +74,26 @@ fromFontStyle FontSlantOblique FontWeightNormal = openSansItalic fromFontStyle _ _ = openSansRegular --- Read a static font file which is included with the package. This--- should be safe as long as it will installed properly.+fonts :: [(FilePath,ByteString)]+fonts = $(embedDir "fonts")++-- Read a static font file which is included with the package. staticFont :: String -> Font-staticFont nm =- case unsafePerformIO $ getDataFileName nm >>= loadFontFile of- Right f -> f- Left e -> error e+staticFont nm = case lookup nm fonts of+ Nothing -> error ("Font not found: " ++ nm)+ Just f -> case decodeFont (fromStrict f) of+ Right r -> r+ Left e -> error e openSansRegular :: Font-openSansRegular = staticFont "fonts/OpenSans-Regular.ttf"+openSansRegular = staticFont "OpenSans-Regular.ttf" openSansBold :: Font-openSansBold = staticFont "fonts/OpenSans-Bold.ttf"+openSansBold = staticFont "OpenSans-Bold.ttf" openSansItalic :: Font-openSansItalic = staticFont "fonts/OpenSans-Italic.ttf"+openSansItalic = staticFont "OpenSans-Italic.ttf" openSansBoldItalic :: Font-openSansBoldItalic = staticFont "fonts/OpenSans-BoldItalic.ttf"+openSansBoldItalic = staticFont "OpenSans-BoldItalic.ttf"