Skip to content

Commit

Permalink
Merge pull request #52 from diagrams/sized
Browse files Browse the repository at this point in the history
new sized, sizedAs, and sizeSpec2D functions
  • Loading branch information
fryguybob committed Oct 22, 2012
2 parents 876aa19 + e2edf15 commit 3a55b89
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 32 deletions.
22 changes: 22 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@

- New 'withTrace' function for setting the Trace of a diagram

- Three new size-related functions:

- New 'sized' function for scaling an object to a particular size.
One particularly nice use of this is to obviate the need to keep
fiddling with the line width to get diagrams to "look right";
just set the line width relative to some arbitrary scale
(e.g. assuming the final diagram will fit into a 1x1 box) and
then apply 'sized' to the final diagram to make it that given
arbitrary size. It can also be used for easily making something
(a diagram, path, trail, ...) the same size as something else,
with the help of the new 'sizeSpec2D' function.

- New 'sizedAs' function, for setting the size of some object to
be "the same as" some other object.

- New 'sizeSpec2D' function for conveniently calculating the size
of an object as a SizeSpec2D value (for use with the new 'sized'
funtion).

* New instances

- The Show instance for R2 now produces something like "2 & 6"
Expand All @@ -49,6 +68,9 @@
- Data.Colour is now re-exported from Diagrams.Prelude for
convenience.

- Diagrams.TwoD.Adjust.adjustSize is now deprecated; it has been
renamed and moved to Diagrams.TwoD.Size.requiredScaleT.

* Dependency/version changes

- Allow data-default 0.4 and 0.5
Expand Down
5 changes: 4 additions & 1 deletion src/Diagrams/TwoD.hs
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,16 @@ module Diagrams.TwoD

-- * Size
-- ** Computing size
, width, height, size2D
, width, height, size2D, sizeSpec2D
, extentX, extentY, center2D

-- ** Specifying size
, SizeSpec2D(..)
, mkSizeSpec

-- ** Adjusting size
, sized, sizedAs

-- * Visual aids for understanding the internal model
, showOrigin
, showOrigin'
Expand Down
38 changes: 9 additions & 29 deletions src/Diagrams/TwoD/Adjust.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ module Diagrams.TwoD.Adjust
setDefault2DAttributes
, adjustDiaSize2D
, adjustDia2D
, adjustSize
, requiredScale

, adjustSize -- for backwards compatibility
, requiredScale -- re-exported for backwards compatibility
) where

import Diagrams.Core
Expand All @@ -29,7 +28,9 @@ import Diagrams.Attributes (lw, lc)
import Diagrams.Util ((#))

import Diagrams.TwoD.Types (R2, p2)
import Diagrams.TwoD.Size (size2D, center2D, SizeSpec2D(..))
import Diagrams.TwoD.Size ( size2D, center2D, SizeSpec2D(..)
, requiredScaleT, requiredScale
)
import Diagrams.TwoD.Text (fontSize)

import Data.AffineSpace ((.-.))
Expand Down Expand Up @@ -99,29 +100,8 @@ adjustDia2D :: Monoid' m
adjustDia2D getSize setSize b opts d
= adjustDiaSize2D getSize setSize b opts (d # setDefault2DAttributes # freeze)

-- | @adjustSize spec sz@ returns a transformation (a uniform scale)
-- which can be applied to something of size @sz@ to make it the
-- requested size @spec@.
{-# DEPRECATED adjustSize "Use Diagrams.TwoD.Size.requiredScaleT instead." #-}
-- | Re-export 'requiredScaleT' with the name 'adjustSize' for
-- backwards compatibility.
adjustSize :: SizeSpec2D -> (Double, Double) -> Transformation R2
adjustSize spec size = scaling (requiredScale spec size)

-- | @requiredScale spec sz@ returns a scaling factor necessary to
-- make something of size @sz@ fit the requested size @spec@,
-- without changing the aspect ratio. Hence an explicit
-- specification of both dimensions may not be honored if the aspect
-- ratios do not match; in that case the scaling will be as large as
-- possible so that the object still fits within the requested size.
requiredScale :: SizeSpec2D -> (Double, Double) -> Double
requiredScale Absolute _ = 1
requiredScale (Width wSpec) (w,_)
| wSpec == 0 || w == 0 = 1
| otherwise = wSpec / w
requiredScale (Height hSpec) (_,h)
| hSpec == 0 || h == 0 = 1
| otherwise = hSpec / h
requiredScale (Dims wSpec hSpec) (w,h) = s
where xscale = wSpec / w
yscale = hSpec / h
s' = min xscale yscale
s | isInfinite s' = 1
| otherwise = s'
adjustSize = requiredScaleT
54 changes: 52 additions & 2 deletions src/Diagrams/TwoD/Size.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@ module Diagrams.TwoD.Size
(
-- * Size and extent of diagrams in R2
-- ** Computing sizes
width, height, size2D
width, height, size2D, sizeSpec2D
, extentX, extentY, center2D

-- ** Specifying sizes
, SizeSpec2D(..)
, mkSizeSpec

, requiredScaleT, requiredScale

-- ** Changing the size of things
, sized, sizedAs
) where

import Diagrams.Core
Expand All @@ -46,6 +51,10 @@ height = maybe 0 (negate . uncurry (-)) . extentY
size2D :: (Enveloped a, V a ~ R2) => a -> (Double, Double)
size2D = width &&& height

-- | Compute the size of an enveloped object as a 'SizeSpec2D' value.
sizeSpec2D :: (Enveloped a, V a ~ R2) => a -> SizeSpec2D
sizeSpec2D = uncurry Dims . size2D

-- | Compute the absolute x-coordinate range of an enveloped object in
-- R2, in the form (lo,hi). Return @Nothing@ for objects with an
-- empty envelope.
Expand Down Expand Up @@ -90,4 +99,45 @@ mkSizeSpec :: Maybe Double -> Maybe Double -> SizeSpec2D
mkSizeSpec Nothing Nothing = Absolute
mkSizeSpec (Just w) Nothing = Width w
mkSizeSpec Nothing (Just h) = Height h
mkSizeSpec (Just w) (Just h) = Dims w h
mkSizeSpec (Just w) (Just h) = Dims w h

-- | @requiredScaleT spec sz@ returns a transformation (a uniform scale)
-- which can be applied to something of size @sz@ to make it fit the
-- requested size @spec@, without changing the aspect ratio.
requiredScaleT :: SizeSpec2D -> (Double, Double) -> Transformation R2
requiredScaleT spec size = scaling (requiredScale spec size)

-- | @requiredScale spec sz@ returns a scaling factor necessary to
-- make something of size @sz@ fit the requested size @spec@,
-- without changing the aspect ratio. Hence an explicit
-- specification of both dimensions may not be honored if the aspect
-- ratios do not match; in that case the scaling will be as large as
-- possible so that the object still fits within the requested size.
requiredScale :: SizeSpec2D -> (Double, Double) -> Double
requiredScale Absolute _ = 1
requiredScale (Width wSpec) (w,_)
| wSpec == 0 || w == 0 = 1
| otherwise = wSpec / w
requiredScale (Height hSpec) (_,h)
| hSpec == 0 || h == 0 = 1
| otherwise = hSpec / h
requiredScale (Dims wSpec hSpec) (w,h) = s
where xscale = wSpec / w
yscale = hSpec / h
s' = min xscale yscale
s | isInfinite s' = 1
| otherwise = s'

-- | Uniformly scale any enveloped object so that it fits within the
-- given size.
sized :: (Transformable a, Enveloped a, V a ~ R2)
=> SizeSpec2D -> a -> a
sized spec a = transform (requiredScaleT spec (size2D a)) a

-- | Uniformly scale an enveloped object so that it \"has the same
-- size as\" (fits within the width and height of) some other
-- object.
sizedAs :: ( Transformable a, Enveloped a, V a ~ R2
, Enveloped b, V b ~ R2)
=> b -> a -> a
sizedAs other = sized (sizeSpec2D other)

0 comments on commit 3a55b89

Please sign in to comment.