diagrams-lib-1.2: src/Diagrams/TwoD/Adjust.hs
{-# LANGUAGE Rank2Types #-}
-----------------------------------------------------------------------------
-- |
-- 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
(
setDefault2DAttributes
, adjustDiaSize2D
, adjustDia2D
) where
import Diagrams.Attributes (lineCap, lineJoin,
lineMiterLimitA)
import Diagrams.Core
import Diagrams.TwoD.Attributes (lineWidthA, lineTextureA)
import Diagrams.TwoD.Size (SizeSpec2D (..), center2D,
requiredScale, size2D)
import Diagrams.TwoD.Text (fontSizeA)
import Diagrams.TwoD.Types (R2, T2, p2)
import Diagrams.Util (( # ))
import Control.Lens (Lens', (&), (.~), (^.))
import Data.AffineSpace ((.-.))
import Data.Default.Class
import Data.Semigroup
-- | Set default attributes of a 2D diagram (in case they have not
-- been set):
--
-- * Line width 0.01
--
-- * Line color black
--
-- * Font size 1
--
-- * Line cap LineCapButt
--
-- * line join miter
--
-- * Miter limit 10
setDefault2DAttributes :: Semigroup m => QDiagram b R2 m -> QDiagram b R2 m
setDefault2DAttributes d = d # lineWidthA def # lineTextureA def # fontSizeA def
# lineCap def # lineJoin def # lineMiterLimitA def
-- | Adjust the size and position of a 2D diagram to fit within the
-- requested size. The first argument is a lens into the output
-- size contained in the rendering options. Returns an updated
-- options record, any transformation applied to the diagram (the
-- inverse of which can be used, say, to translate output/device
-- coordinates back into local diagram coordinates), and the
-- modified diagram itself.
adjustDiaSize2D :: Monoid' m
=> Lens' (Options b R2) SizeSpec2D
-> b -> Options b R2 -> QDiagram b R2 m
-> (Options b R2, T2, QDiagram b R2 m)
adjustDiaSize2D szL _ opts d =
( case spec of
Dims _ _ -> opts
_ -> opts & szL .~ (uncurry Dims . scale s $ size)
, adjustT
, d # transform adjustT
)
where spec = opts ^. szL
size = size2D d
s = requiredScale spec size
finalSz = case spec of
Dims w h -> (w,h)
_ -> scale s size
tr = (0.5 *. p2 finalSz) .-. (s *. center2D d)
adjustT = translation tr <> scaling s
-- | @adjustDia2D@ provides a useful default implementation of
-- the 'adjustDia' method from the 'Backend' type class.
--
-- As its first argument it requires a lens into the output size
-- contained in the rendering options.
--
-- It then performs the following adjustments:
--
-- * Set default attributes (see 'setDefault2DAttributes')
--
-- * Scale and translate the diagram to fit within the requested
-- size (see 'adjustDiaSize2D')
--
-- It returns an updated options record, any transformation applied
-- to the diagram (the inverse of which can be used, say, to
-- translate output/device coordinates back into local diagram
-- coordinates), and the modified diagram itself.
adjustDia2D :: Monoid' m
=> Lens' (Options b R2) SizeSpec2D
-> b -> Options b R2 -> QDiagram b R2 m
-> (Options b R2, T2, QDiagram b R2 m)
adjustDia2D szL b opts d
= adjustDiaSize2D szL b opts (d # setDefault2DAttributes)