diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,28 @@
+Rasterific-svg
+==============
+
+[![Build Status](https://travis-ci.org/Twinside/rasterific-svg.png?branch=master)](https://travis-ci.org/Twinside/rasterific-svg)
+[![Hackage](https://img.shields.io/hackage/v/rasterific-svg.svg)](http://hackage.haskell.org/package/rasterific-svg)
+SVGTiny loader/renderer/serializer based on Rasterific.
+
+The library is available on [Hackage](http://hackage.haskell.org/package/rasterific-svg)
+
+Current capabilities
+--------------------
+
+The current version implements SVG Tiny1.2 with the exception of:
+
+ * non-scaling stroke.
+ * textArea element.
+
+The implementation also implements feature from SVG 1.1 like:
+
+ * Advanced text handling (text on path, dx/dy), but with
+   low support for Unicode, right to left and vertical text.
+ * CSS Styling, using CSS2 styling engine.
+ * `pattern` element handling
+ * `marker` element hadnling
+ * Path arcs.
+
+This package can render SVG to an image or transform it to a PDF.
+
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,31 +1,56 @@
--*-change-log-*-
+Change log
+==========
 
-v0.2.2.1
+v0.2.3 May 2015
+---------------
+
+ * Adding: PDF output
+ * Fix: font cache created in temp dir
+
+v0.2.2.1 May 2015
+-----------------
+
  * Fix: GHC < 7.10 compilation
 
-v0.2.2
+v0.2.2 May 2015
+---------------
+
  * Fix: lens upper bound, and removing it.
 
-v0.2.1
+v0.2.1 May 2015
+---------------
+
  * Adding: support for arc in path
 
 v0.2 April 2015
+---------------
+
  * Bumping: using svg-tree 0.3
 
 v0.1.1 April 2015
+-----------------
+
  * Fix: Fixing GHC 7.10.1 related warnings
  * Fix: Group transparency.
 
 v0.1.0.3 March 2015
+-------------------
+
  * Fix: Bumping lens dependency
 
 v0.1.0.2 February 2015
+----------------------
+
  * Fix: Removing all test suites from distribution package.
  * Fix: Lowering some low version bounds.
 
 v0.1.0.1 February 2015
+----------------------
+
  * Fix: Removing bench from test suite.
 
 v0.1 February 2015
+------------------
+
  * Initial release
 
diff --git a/exec-src/svgrender.hs b/exec-src/svgrender.hs
--- a/exec-src/svgrender.hs
+++ b/exec-src/svgrender.hs
@@ -8,7 +8,8 @@
 import Control.Monad( when )
 import Data.Monoid( (<>) )
 import Codec.Picture( writePng )
-import System.FilePath( replaceExtension )
+import System.Directory( getTemporaryDirectory )
+import System.FilePath( (</>), replaceExtension )
 
 import Options.Applicative( Parser
                           , ParserInfo
@@ -91,7 +92,8 @@
 
 runConversion :: Options -> IO ()
 runConversion options = do
-  cache <- loadCreateFontCache "rasterific-svg-font-cache"
+  tempDir <- getTemporaryDirectory 
+  cache <- loadCreateFontCache $ tempDir </> "rasterific-svg-font-cache"
   let filename = _inputFile options
       whenVerbose = when (_verbose options) . putStrLn
   whenVerbose $ "Loading: " ++ filename 
diff --git a/rasterific-svg.cabal b/rasterific-svg.cabal
--- a/rasterific-svg.cabal
+++ b/rasterific-svg.cabal
@@ -1,7 +1,7 @@
 -- Initial svg.cabal generated by cabal init.  For further documentation, 
 -- see http://haskell.org/cabal/users-guide/
 name:                rasterific-svg
-version:             0.2.2.1
+version:             0.2.3
 synopsis:            SVG renderer based on Rasterific.
 description:         SVG renderer that will let you render svg-tree parsed
                      SVG file to a JuicyPixel image or Rasterific Drawing.
@@ -10,7 +10,7 @@
 author:              Vincent Berthoux
 maintainer:          Vincent Berthoux
 -- copyright:           
-extra-source-files:  changelog
+extra-source-files:  changelog, README.md
 category:            Graphics, Svg
 build-type:          Simple
 cabal-version:       >=1.10
@@ -22,7 +22,7 @@
 Source-Repository this
     Type:      git
     Location:  git://github.com/Twinside/rasterific-svg.git
-    Tag:       v0.2.2.1
+    Tag:       v0.2.3
 
 library
   hs-source-dirs: src
@@ -44,9 +44,9 @@
                , scientific >= 0.3
                , JuicyPixels >= 3.2 && < 3.3
                , containers >= 0.5
-               , Rasterific >= 0.5.2.1 && < 0.6
+               , Rasterific >= 0.6 && < 0.7
                , FontyFruity >= 0.5 && < 0.6
-               , svg-tree   >= 0.3 && < 0.4
+               , svg-tree   >= 0.3.1 && < 0.4
                , lens >= 4.5 && < 5
                , linear >= 1.16
                , vector >= 0.10
@@ -62,6 +62,7 @@
   ghc-prof-options: -rtsopts -Wall -prof
   Build-Depends: base >= 4.6
                , optparse-applicative >= 0.11 && < 0.12
+               , directory >= 1.0
                , rasterific-svg
                , Rasterific
                , JuicyPixels
diff --git a/src/Graphics/Rasterific/Svg.hs b/src/Graphics/Rasterific/Svg.hs
--- a/src/Graphics/Rasterific/Svg.hs
+++ b/src/Graphics/Rasterific/Svg.hs
@@ -1,138 +1,144 @@
--- | Svg renderer based on Rasterific.
---
--- Here is a simple example of loading a SVG file (using svg-tree)
--- rendering it to a picture, and saving it to a PNG (using Juicy.Pixels)
---
--- @
--- import Codec.Picture( writePng )
--- import Graphics.Svg( loadSvgFile )
--- import Graphics.Rasterific.Svg( loadCreateFontCache
---                               , renderSvgDocument
---                               )
--- loadRender :: FilePath -> FilePath -> IO ()
--- loadRender svgfilename pngfilename = do
---   f <- loadSvgFile svgfilename
---   case f of
---     Nothing -> putStrLn "Error while loading SVG"
---     Just doc -> do
---       cache <- loadCreateFontCache "fonty-texture-cache"
---       (finalImage, _) <- renderSvgDocument cache Nothing 96 doc
---       writePng pngfilename finalImage
--- @
---
-module Graphics.Rasterific.Svg
-                    ( -- * Main functions
-                      drawingOfSvgDocument
-                    , renderSvgDocument
-                    , loadCreateFontCache
-                      -- * Types
-                    , LoadedElements( .. )
-                    , Result( .. )
-                    , DrawResult( .. )
-                    , Dpi
-                      -- * Other helper functions
-                    , renderSvgFile
-                    ) where
-
-import qualified Data.ByteString.Lazy as B
-import Graphics.Rasterific.Svg.RasterificRender( DrawResult( .. ) )
-import qualified Graphics.Rasterific.Svg.RasterificRender as RR
-import Data.Binary( encodeFile, decodeOrFail )
-import Graphics.Svg.Types hiding ( Dpi )
-import Graphics.Svg hiding ( Dpi )
-import Graphics.Rasterific.Svg.RenderContext
-
-import System.Directory( doesFileExist )
-import Graphics.Text.TrueType
-
-
-import qualified Codec.Picture as CP
-import Codec.Picture( PixelRGBA8( .. )
-                    , writePng )
-
-{-import Graphics.Svg.CssParser-}
-
--- | Render an svg document to an image.
--- If you provide a size, the document will be stretched to
--- match the provided size.
---
--- The DPI parameter really should depend of your screen, but
--- a good default value is 96
---
--- The use of the IO Monad is there to allow loading of fonts
--- and referenced images.
-renderSvgDocument :: FontCache          -- ^ Structure used to access fonts
-                  -> Maybe (Int, Int)   -- ^ Optional document size
-                  -> Dpi                -- ^ Current resolution for text and elements
-                  -> Document           -- ^ Svg document
-                  -> IO (CP.Image PixelRGBA8, LoadedElements)
-renderSvgDocument cache size dpi =
-    RR.renderSvgDocument cache size dpi . applyCSSRules . resolveUses
-
--- | Render an svg document to a Rasterific Drawing.
--- If you provide a size, the document will be stretched to
--- match the provided size.
---
--- The DPI parameter really should depend of your screen, but
--- a good default value is 96
---
--- The use of the IO Monad is there to allow loading of fonts
--- and referenced images.
-drawingOfSvgDocument :: FontCache          -- ^ Structure used to access fonts
-                     -> Maybe (Int, Int)   -- ^ Optional document size
-                     -> Dpi                -- ^ Current resolution for text and elements
-                     -> Document           -- ^ Svg document
-                     -> IO (DrawResult, LoadedElements)
-drawingOfSvgDocument cache size dpi =
-    RR.drawingOfSvgDocument cache size dpi . applyCSSRules . resolveUses
-
--- | Rendering status.
-data Result
-  = ResultSuccess       -- ^ No problem found
-  | ResultError String  -- ^ Error with message
-  deriving (Eq, Show)
-
--- | Convert an SVG file to a PNG file, return True
--- if the operation went without problems.
--- 
--- This function will call loadCreateFontCache with
--- the filename "fonty-texture-cache"
-renderSvgFile :: FilePath -> FilePath -> IO Result
-renderSvgFile svgfilename pngfilename = do
-  f <- loadSvgFile svgfilename
-  case f of
-     Nothing -> return $ ResultError "Error while loading SVG"
-     Just doc -> do
-        cache <- loadCreateFontCache "fonty-texture-cache"
-        (finalImage, _) <- renderSvgDocument cache Nothing 96 doc
-        writePng pngfilename finalImage
-        return ResultSuccess
-
--- | This function will create a font cache,
--- a structure allowing to quickly match a font
--- family name and style to a specific true type font
--- on disk.
---
--- The cache is saved on disk at the filepath given
--- as parameter. If a cache is found it is automatically
--- loaded from the file.
---
--- Creating the cache is a rather long operation (especially
--- on Windows), that's why you may want to keep the cache
--- around.
-loadCreateFontCache :: FilePath -> IO FontCache
-loadCreateFontCache filename = do
-  exist <- doesFileExist filename
-  if exist then loadCache else createWrite
-  where
-    loadCache = do
-      bstr <- B.readFile filename
-      case decodeOrFail bstr of
-        Left _ -> createWrite
-        Right (_, _, v) -> return v
-      
-    createWrite = do
-      cache <- buildCache
-      encodeFile filename cache
-      return cache
-
+-- | Svg renderer based on Rasterific.
+--
+-- Here is a simple example of loading a SVG file (using svg-tree)
+-- rendering it to a picture, and saving it to a PNG (using Juicy.Pixels)
+--
+-- @
+-- import Codec.Picture( writePng )
+-- import Graphics.Svg( loadSvgFile )
+-- import Graphics.Rasterific.Svg( loadCreateFontCache
+--                               , renderSvgDocument
+--                               )
+-- loadRender :: FilePath -> FilePath -> IO ()
+-- loadRender svgfilename pngfilename = do
+--   f <- loadSvgFile svgfilename
+--   case f of
+--     Nothing -> putStrLn "Error while loading SVG"
+--     Just doc -> do
+--       cache <- loadCreateFontCache "fonty-texture-cache"
+--       (finalImage, _) <- renderSvgDocument cache Nothing 96 doc
+--       writePng pngfilename finalImage
+-- @
+--
+module Graphics.Rasterific.Svg
+                    ( -- * Main functions
+                      drawingOfSvgDocument
+                    , renderSvgDocument
+                    , pdfOfSvgDocument
+                    , loadCreateFontCache
+                      -- * Types
+                    , LoadedElements( .. )
+                    , Result( .. )
+                    , DrawResult( .. )
+                    , Dpi
+                      -- * Other helper functions
+                    , renderSvgFile
+                    ) where
+
+import qualified Data.ByteString.Lazy as B
+import Graphics.Rasterific.Svg.RasterificRender( DrawResult( .. ) )
+import qualified Graphics.Rasterific.Svg.RasterificRender as RR
+import Data.Binary( encodeFile, decodeOrFail )
+import Graphics.Svg.Types hiding ( Dpi )
+import Graphics.Svg hiding ( Dpi )
+import Graphics.Rasterific.Svg.RenderContext
+
+import System.Directory( doesFileExist )
+import Graphics.Text.TrueType
+
+
+import qualified Codec.Picture as CP
+import Codec.Picture( PixelRGBA8( .. )
+                    , writePng )
+
+{-import Graphics.Svg.CssParser-}
+
+-- | Render an svg document to an image.
+-- If you provide a size, the document will be stretched to
+-- match the provided size.
+--
+-- The DPI parameter really should depend of your screen, but
+-- a good default value is 96
+--
+-- The use of the IO Monad is there to allow loading of fonts
+-- and referenced images.
+renderSvgDocument :: FontCache          -- ^ Structure used to access fonts
+                  -> Maybe (Int, Int)   -- ^ Optional document size
+                  -> Dpi                -- ^ Current resolution for text and elements
+                  -> Document           -- ^ Svg document
+                  -> IO (CP.Image PixelRGBA8, LoadedElements)
+renderSvgDocument cache size dpi =
+    RR.renderSvgDocument cache size dpi . applyCSSRules . resolveUses
+
+pdfOfSvgDocument :: FontCache -> Maybe (Int, Int) -> Dpi -> Document
+                 -> IO (B.ByteString, LoadedElements)
+pdfOfSvgDocument cache sizes dpi =
+    RR.pdfOfSvgDocument cache sizes dpi . applyCSSRules . resolveUses
+
+-- | Render an svg document to a Rasterific Drawing.
+-- If you provide a size, the document will be stretched to
+-- match the provided size.
+--
+-- The DPI parameter really should depend of your screen, but
+-- a good default value is 96
+--
+-- The use of the IO Monad is there to allow loading of fonts
+-- and referenced images.
+drawingOfSvgDocument :: FontCache          -- ^ Structure used to access fonts
+                     -> Maybe (Int, Int)   -- ^ Optional document size
+                     -> Dpi                -- ^ Current resolution for text and elements
+                     -> Document           -- ^ Svg document
+                     -> IO (DrawResult, LoadedElements)
+drawingOfSvgDocument cache size dpi =
+    RR.drawingOfSvgDocument cache size dpi . applyCSSRules . resolveUses
+
+-- | Rendering status.
+data Result
+  = ResultSuccess       -- ^ No problem found
+  | ResultError String  -- ^ Error with message
+  deriving (Eq, Show)
+
+-- | Convert an SVG file to a PNG file, return True
+-- if the operation went without problems.
+-- 
+-- This function will call loadCreateFontCache with
+-- the filename "fonty-texture-cache"
+renderSvgFile :: FilePath -> FilePath -> IO Result
+renderSvgFile svgfilename pngfilename = do
+  f <- loadSvgFile svgfilename
+  case f of
+     Nothing -> return $ ResultError "Error while loading SVG"
+     Just doc -> do
+        cache <- loadCreateFontCache "fonty-texture-cache"
+        (finalImage, _) <- renderSvgDocument cache Nothing 96 doc
+        writePng pngfilename finalImage
+        return ResultSuccess
+
+-- | This function will create a font cache,
+-- a structure allowing to quickly match a font
+-- family name and style to a specific true type font
+-- on disk.
+--
+-- The cache is saved on disk at the filepath given
+-- as parameter. If a cache is found it is automatically
+-- loaded from the file.
+--
+-- Creating the cache is a rather long operation (especially
+-- on Windows), that's why you may want to keep the cache
+-- around.
+loadCreateFontCache :: FilePath -> IO FontCache
+loadCreateFontCache filename = do
+  exist <- doesFileExist filename
+  if exist then loadCache else createWrite
+  where
+    loadCache = do
+      bstr <- B.readFile filename
+      case decodeOrFail bstr of
+        Left _ -> createWrite
+        Right (_, _, v) -> return v
+      
+    createWrite = do
+      cache <- buildCache
+      encodeFile filename cache
+      return cache
+
diff --git a/src/Graphics/Rasterific/Svg/RasterificRender.hs b/src/Graphics/Rasterific/Svg/RasterificRender.hs
--- a/src/Graphics/Rasterific/Svg/RasterificRender.hs
+++ b/src/Graphics/Rasterific/Svg/RasterificRender.hs
@@ -5,6 +5,7 @@
     ( DrawResult( .. )
     , renderSvgDocument
     , drawingOfSvgDocument
+    , pdfOfSvgDocument
     ) where
 
 #if !MIN_VERSION_base(4,8,0)
@@ -37,6 +38,7 @@
                           , convertPixel
                           )
 
+import qualified Data.ByteString.Lazy as LB
 import qualified Data.Foldable as F
 import qualified Data.Map as M
 import qualified Graphics.Rasterific as R
@@ -77,6 +79,14 @@
           $ _drawAction drawing
   return (img, loaded)
 
+pdfOfSvgDocument :: FontCache -> Maybe (Int, Int) -> Dpi -> Document
+                 -> IO (LB.ByteString, LoadedElements)
+pdfOfSvgDocument cache sizes dpi doc = do
+  (drawing, loaded) <- drawingOfSvgDocument cache sizes dpi doc
+  let img = R.renderDrawingAtDpiToPDF (_drawWidth drawing) (_drawHeight drawing) dpi $ _drawAction drawing
+  return (img, loaded)
+
+
 drawingOfSvgDocument :: FontCache -> Maybe (Int, Int) -> Dpi -> Document
                      -> IO (DrawResult, LoadedElements)
 drawingOfSvgDocument cache sizes dpi doc = case sizes of
@@ -104,9 +114,9 @@
 
     subRenderer subDoc = do
        (drawing, loaded) <-
-           liftIO $ renderSvgDocument cache Nothing dpi subDoc
+           liftIO $ drawingOfSvgDocument cache Nothing dpi subDoc
        modify (<> loaded)
-       return drawing
+       return $ _drawAction drawing
 
     sizeFitter (V2 0 0, V2 vw vh) (actualWidth, actualHeight)
       | aw /= vw || vh /= ah =
diff --git a/src/Graphics/Rasterific/Svg/RenderContext.hs b/src/Graphics/Rasterific/Svg/RenderContext.hs
--- a/src/Graphics/Rasterific/Svg/RenderContext.hs
+++ b/src/Graphics/Rasterific/Svg/RenderContext.hs
@@ -51,7 +51,7 @@
     , _renderDpi          :: Int
     , _contextDefinitions :: M.Map String Element
     , _fontCache          :: FontCache
-    , _subRender          :: Document -> IODraw (CP.Image PixelRGBA8)
+    , _subRender          :: Document -> IODraw (R.Drawing PixelRGBA8 ())
     , _basePath           :: FilePath
     }
 
@@ -273,7 +273,10 @@
       return . Just $ prepareRadialGradientTexture ctxt
                         attr grad opacity prims
     prepare (ElementPattern pat) = do
-      patternPicture <- _subRender ctxt $ documentOfPattern pat (_basePath ctxt)
-      return . Just . RT.withSampler R.SamplerRepeat
-                    $ RT.sampledImageTexture patternPicture
+      let doc = documentOfPattern pat (_basePath ctxt)
+          dpi = _renderDpi ctxt
+          w = floor . lineariseXLength ctxt attr $ _patternWidth pat
+          h = floor . lineariseYLength ctxt attr $ _patternHeight pat
+      patDrawing <- _subRender ctxt doc
+      return . Just $ RT.patternTexture w h dpi (PixelRGBA8 0 0 0 0) patDrawing
 
