diff --git a/CHANGES b/CHANGES index c975a596..ce69f2a2 100644 --- a/CHANGES +++ b/CHANGES @@ -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" @@ -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 diff --git a/src/Diagrams/TwoD.hs b/src/Diagrams/TwoD.hs index fed216d3..e040a856 100644 --- a/src/Diagrams/TwoD.hs +++ b/src/Diagrams/TwoD.hs @@ -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' diff --git a/src/Diagrams/TwoD/Adjust.hs b/src/Diagrams/TwoD/Adjust.hs index 478c5bcd..1c367252 100644 --- a/src/Diagrams/TwoD/Adjust.hs +++ b/src/Diagrams/TwoD/Adjust.hs @@ -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 @@ -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 ((.-.)) @@ -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 \ No newline at end of file diff --git a/src/Diagrams/TwoD/Size.hs b/src/Diagrams/TwoD/Size.hs index 16569703..1315ec49 100644 --- a/src/Diagrams/TwoD/Size.hs +++ b/src/Diagrams/TwoD/Size.hs @@ -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 @@ -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. @@ -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 \ No newline at end of file +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) \ No newline at end of file