diagrams-lib-0.4: src/Diagrams/TwoD/Adjust.hs
-----------------------------------------------------------------------------
-- |
-- Module : Diagrams.TwoD.Adjust
-- Copyright : (c) 2011 diagrams-lib team (see LICENSE)
-- License : BSD-style (see LICENSE)
-- Maintainer : diagrams-discuss@googlegroups.com
--
-- A default diagram-adjustment implementation for two-dimensional
-- diagrams, useful for backend implementors.
--
-----------------------------------------------------------------------------
module Diagrams.TwoD.Adjust (
adjustDia2D
, adjustSize
) where
import Graphics.Rendering.Diagrams
import Diagrams.Attributes (lw, lc)
import Diagrams.Util ((#))
import Diagrams.TwoD.Types (R2)
import Diagrams.TwoD.Size (size2D, center2D, SizeSpec2D(..))
import Diagrams.TwoD.Text (fontSize)
import Data.AffineSpace ((.-.))
import Data.Colour.Names (black)
import Data.Monoid (Monoid, mempty)
-- | @adjustDia2D@ provides a useful default implementation of
-- the 'adjustDia' method from the 'Backend' type class.
--
-- As its first argument it requires a method for extracting the
-- requested output size from the rendering options.
--
-- It then performs the following adjustments:
--
-- * Set some default attributes (in case they have not been set):
--
-- * Line width 0.01
--
-- * Line color black
--
-- * Font size 1
--
-- * Freeze the diagram in its final form
--
-- * Scale and translate the diagram to fit within the requested size
adjustDia2D :: Monoid m => (Options b R2 -> R2) -> b -> Options b R2 -> AnnDiagram b R2 m -> AnnDiagram b R2 m
adjustDia2D getSize _ opts d = d # lw 0.01 # lc black # fontSize 1 # freeze
# scale s
# translate tr
where (w,h) = getSize opts
(wd,hd) = size2D d
xscale = w / wd
yscale = h / hd
s' = min xscale yscale
s | isInfinite s' = 1
| otherwise = s'
tr = (0.5 *. P (w,h)) .-. (s *. center2D d)
-- | @adjustSize spec sz@ returns a transformation which can be
-- applied to something of size @sz@ to make it the requested size
-- @spec@.
adjustSize :: SizeSpec2D -> R2 -> Transformation R2
adjustSize Absolute _ = mempty
adjustSize (Width wSpec) (w,_)
| wSpec == 0 || w == 0 = mempty
| otherwise = scaling (wSpec / w)
adjustSize (Height hSpec) (_,h)
| hSpec == 0 || h == 0 = mempty
| otherwise = scaling (hSpec / h)
adjustSize (Dims wSpec hSpec) (w,h) = scaling s
where xscale = wSpec / w
yscale = hSpec / h
s' = min xscale yscale
s | isInfinite s' = 1
| otherwise = s'