    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Util.Rectangle
    -- Copyright   :  (c) 2018 Yclept Nemo
    -- License     :  BSD-style (see LICENSE)
    --
    -- Maintainer  :
    -- Stability   :  unstable
    -- Portability :  unportable
    --
    -- A module for handling pixel rectangles: 'Rectangle'.
    --
    -----------------------------------------------------------------------------

    module XMonad.Util.Rectangle
        ( -- * Usage
          -- $usage
          PointRectangle (..)
        , pixelsToIndices, pixelsToCoordinates
        , indicesToRectangle, coordinatesToRectangle
        , empty
        , intersects
        , supersetOf
        , difference
        , withBorder
        , center
        , toRatio
        ) where

    import           XMonad
    import qualified XMonad.StackSet as W

    import           Data.Ratio

    -- $usage
    -- > import XMonad.Util.Rectangle as R
    -- > R.empty (Rectangle 0 0 1024 768)

    -- | Rectangle as two points. What those points mean depends on the conversion
    -- function.
    data PointRectangle a = PointRectangle
        { PointRectangle a -> a
    point_x1::a   -- ^ Point nearest to the origin.
        , PointRectangle a -> a
    point_y1::a
        , PointRectangle a -> a
    point_x2::a   -- ^ Point furthest from the origin.
        , PointRectangle a -> a
    point_y2::a
        } deriving (PointRectangle a -> PointRectangle a -> Bool
    (PointRectangle a -> PointRectangle a -> Bool)
    -> (PointRectangle a -> PointRectangle a -> Bool)
    -> Eq (PointRectangle a)
    forall a. Eq a => PointRectangle a -> PointRectangle a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: PointRectangle a -> PointRectangle a -> Bool
    $c/= :: forall a. Eq a => PointRectangle a -> PointRectangle a -> Bool
    == :: PointRectangle a -> PointRectangle a -> Bool
    $c== :: forall a. Eq a => PointRectangle a -> PointRectangle a -> Bool
    Eq,ReadPrec [PointRectangle a]
    ReadPrec (PointRectangle a)
    Int -> ReadS (PointRectangle a)
    ReadS [PointRectangle a]
    (Int -> ReadS (PointRectangle a))
    -> ReadS [PointRectangle a]
    -> ReadPrec (PointRectangle a)
    -> ReadPrec [PointRectangle a]
    -> Read (PointRectangle a)
    forall a. Read a => ReadPrec [PointRectangle a]
    forall a. Read a => ReadPrec (PointRectangle a)
    forall a. Read a => Int -> ReadS (PointRectangle a)
    forall a. Read a => ReadS [PointRectangle a]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [PointRectangle a]
    $creadListPrec :: forall a. Read a => ReadPrec [PointRectangle a]
    readPrec :: ReadPrec (PointRectangle a)
    $creadPrec :: forall a. Read a => ReadPrec (PointRectangle a)
    readList :: ReadS [PointRectangle a]
    $creadList :: forall a. Read a => ReadS [PointRectangle a]
    readsPrec :: Int -> ReadS (PointRectangle a)
    $creadsPrec :: forall a. Read a => Int -> ReadS (PointRectangle a)
    Read,Int -> PointRectangle a -> ShowS
    [PointRectangle a] -> ShowS
    PointRectangle a -> String
    (Int -> PointRectangle a -> ShowS)
    -> (PointRectangle a -> String)
    -> ([PointRectangle a] -> ShowS)
    -> Show (PointRectangle a)
    forall a. Show a => Int -> PointRectangle a -> ShowS
    forall a. Show a => [PointRectangle a] -> ShowS
    forall a. Show a => PointRectangle a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [PointRectangle a] -> ShowS
    $cshowList :: forall a. Show a => [PointRectangle a] -> ShowS
    show :: PointRectangle a -> String
    $cshow :: forall a. Show a => PointRectangle a -> String
    showsPrec :: Int -> PointRectangle a -> ShowS
    $cshowsPrec :: forall a. Show a => Int -> PointRectangle a -> ShowS
    Show)

    -- | There are three possible ways to convert rectangles to pixels:
    --
    -- * Consider integers as "gaps" between pixels; pixels range from @(N,N+1)@,
    -- exclusively: @(0,1)@, @(1,2)@, and so on. This leads to interval ambiguity:
    -- whether an integer endpoint contains a pixel depends on which direction the
    -- interval approaches the pixel. Consider the adjacent pixels @(0,1)@ and
    -- @(1,2)@ where @1@ can refer to either pixel @(0,1)@ or pixel @(1,2)@.
    --
    -- * Consider integers to demarcate the start of each pixel; pixels range from
    -- @[N,N+1)@: @[0,1)@, @[1,2)@, and so on - or equivalently: @(N,N+1]@. This is
    -- the most flexible coordinate system, and the convention used by the
    -- 'Rectangle' type.
    --
    -- * Consider integers to demarcate the center of each pixel; pixels range from
    -- @[N,N+1]@, as though each real-valued coordinate had been rounded (either
    -- down or up) to the nearest integers. So each pixel, from zero, is listed as:
    -- @[0,0]@, @[1,1]@, @[2,2]@, and so on. Rather than a coordinate system, this
    -- considers pixels as row/colum indices.  While easiest to reason with,
    -- indices are unable to represent zero-dimension rectangles.
    --
    -- Consider pixels as indices. Do not use this on empty rectangles.
    pixelsToIndices :: Rectangle -> (PointRectangle Integer)
    pixelsToIndices :: Rectangle -> PointRectangle Integer
    pixelsToIndices (Rectangle px :: Position
    px py :: Position
    py dx :: Dimension
    dx dy :: Dimension
    dy) =
        Integer -> Integer -> Integer -> Integer -> PointRectangle Integer
    forall a. a -> a -> a -> a -> PointRectangle a
    PointRectangle (Position -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    px)
                       (Position -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    py)
                       (Position -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    px Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + Dimension -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    dx Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    - 1)
                       (Position -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    py Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + Dimension -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    dy Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    - 1)

    -- | Consider pixels as @[N,N+1)@ coordinates. Available for empty rectangles.
    pixelsToCoordinates :: Rectangle -> (PointRectangle Integer)
    pixelsToCoordinates :: Rectangle -> PointRectangle Integer
    pixelsToCoordinates (Rectangle px :: Position
    px py :: Position
    py dx :: Dimension
    dx dy :: Dimension
    dy) =
        Integer -> Integer -> Integer -> Integer -> PointRectangle Integer
    forall a. a -> a -> a -> a -> PointRectangle a
    PointRectangle (Position -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    px)
                       (Position -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    py)
                       (Position -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    px Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + Dimension -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    dx)
                       (Position -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    py Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + Dimension -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    dy)

    -- | Invert 'pixelsToIndices'.
    indicesToRectangle :: (PointRectangle Integer) -> Rectangle
    indicesToRectangle :: PointRectangle Integer -> Rectangle
    indicesToRectangle (PointRectangle x1 :: Integer
    x1 y1 :: Integer
    y1 x2 :: Integer
    x2 y2 :: Integer
    y2) =
        Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle (Integer -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    x1)
                  (Integer -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    y1)
                  (Integer -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Integer -> Dimension) -> Integer -> Dimension
    forall a b. (a -> b) -> a -> b
    $ Integer
    x2 Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    - Integer
    x1 Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + 1)
                  (Integer -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Integer -> Dimension) -> Integer -> Dimension
    forall a b. (a -> b) -> a -> b
    $ Integer
    y2 Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    - Integer
    y1 Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + 1)

    -- | Invert 'pixelsToCoordinates'.
    coordinatesToRectangle :: (PointRectangle Integer) -> Rectangle
    coordinatesToRectangle :: PointRectangle Integer -> Rectangle
    coordinatesToRectangle (PointRectangle x1 :: Integer
    x1 y1 :: Integer
    y1 x2 :: Integer
    x2 y2 :: Integer
    y2) =
        Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle (Integer -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    x1)
                  (Integer -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    y1)
                  (Integer -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Integer -> Dimension) -> Integer -> Dimension
    forall a b. (a -> b) -> a -> b
    $ Integer
    x2 Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    - Integer
    x1)
                  (Integer -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Integer -> Dimension) -> Integer -> Dimension
    forall a b. (a -> b) -> a -> b
    $ Integer
    y2 Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    - Integer
    y1)

    -- | True if either the 'rect_width' or 'rect_height' fields are zero, i.e. the
    -- rectangle has no area.
    empty :: Rectangle -> Bool
    empty :: Rectangle -> Bool
    empty (Rectangle _ _ _ 0) = Bool
    True
    empty (Rectangle _ _ 0 _) = Bool
    True
    empty (Rectangle _ _ _ _) = Bool
    False

    -- | True if the intersection of the set of points comprising each rectangle is
    -- not the empty set. Therefore any rectangle containing the initial points of
    -- an empty rectangle will never intersect that rectangle - including the same
    -- empty rectangle.
    intersects :: Rectangle -> Rectangle -> Bool
    intersects :: Rectangle -> Rectangle -> Bool
    intersects r1 :: Rectangle
    r1 r2 :: Rectangle
    r2 | Rectangle -> Bool
    empty Rectangle
    r1 Bool -> Bool -> Bool
    || Rectangle -> Bool
    empty Rectangle
    r2 = Bool
    False
                     | Bool
    otherwise            =    Integer
    r1_x1 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < Integer
    r2_x2
                                              Bool -> Bool -> Bool
    && Integer
    r1_x2 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > Integer
    r2_x1
                                              Bool -> Bool -> Bool
    && Integer
    r1_y1 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < Integer
    r2_y2
                                              Bool -> Bool -> Bool
    && Integer
    r1_y2 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > Integer
    r2_y1
        where PointRectangle r1_x1 :: Integer
    r1_x1 r1_y1 :: Integer
    r1_y1 r1_x2 :: Integer
    r1_x2 r1_y2 :: Integer
    r1_y2 = Rectangle -> PointRectangle Integer
    pixelsToCoordinates Rectangle
    r1
              PointRectangle r2_x1 :: Integer
    r2_x1 r2_y1 :: Integer
    r2_y1 r2_x2 :: Integer
    r2_x2 r2_y2 :: Integer
    r2_y2 = Rectangle -> PointRectangle Integer
    pixelsToCoordinates Rectangle
    r2

    -- | True if the first rectangle contains at least all the points of the second
    -- rectangle. Any rectangle containing the initial points of an empty rectangle
    -- will be a superset of that rectangle - including the same empty rectangle.
    supersetOf :: Rectangle -> Rectangle -> Bool
    supersetOf :: Rectangle -> Rectangle -> Bool
    supersetOf r1 :: Rectangle
    r1 r2 :: Rectangle
    r2 =    Integer
    r1_x1 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Integer
    r2_x1
                       Bool -> Bool -> Bool
    && Integer
    r1_y1 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Integer
    r2_y1
                       Bool -> Bool -> Bool
    && Integer
    r1_x2 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Integer
    r2_x2
                       Bool -> Bool -> Bool
    && Integer
    r1_y2 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Integer
    r2_y2
        where PointRectangle r1_x1 :: Integer
    r1_x1 r1_y1 :: Integer
    r1_y1 r1_x2 :: Integer
    r1_x2 r1_y2 :: Integer
    r1_y2 = Rectangle -> PointRectangle Integer
    pixelsToCoordinates Rectangle
    r1
              PointRectangle r2_x1 :: Integer
    r2_x1 r2_y1 :: Integer
    r2_y1 r2_x2 :: Integer
    r2_x2 r2_y2 :: Integer
    r2_y2 = Rectangle -> PointRectangle Integer
    pixelsToCoordinates Rectangle
    r2

    -- | Return the smallest set of rectangles resulting from removing all the
    -- points of the second rectangle from those of the first, i.e. @r1 - r2@, such
    -- that @0 <= l <= 4@ where @l@ is the length of the resulting list.
    difference :: Rectangle -> Rectangle -> [Rectangle]
    difference :: Rectangle -> Rectangle -> [Rectangle]
    difference r1 :: Rectangle
    r1 r2 :: Rectangle
    r2 | Rectangle
    r1 Rectangle -> Rectangle -> Bool
    `intersects` Rectangle
    r2 = (PointRectangle Integer -> Rectangle)
    -> [PointRectangle Integer] -> [Rectangle]
    forall a b. (a -> b) -> [a] -> [b]
    map PointRectangle Integer -> Rectangle
    coordinatesToRectangle ([PointRectangle Integer] -> [Rectangle])
    -> [PointRectangle Integer] -> [Rectangle]
    forall a b. (a -> b) -> a -> b
    $
                                            [[PointRectangle Integer]] -> [PointRectangle Integer]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat [[PointRectangle Integer]
    rt,[PointRectangle Integer]
    rr,[PointRectangle Integer]
    rb,[PointRectangle Integer]
    rl]
                     | Bool
    otherwise          = [Rectangle
    r1]
        where PointRectangle r1_x1 :: Integer
    r1_x1 r1_y1 :: Integer
    r1_y1 r1_x2 :: Integer
    r1_x2 r1_y2 :: Integer
    r1_y2 = Rectangle -> PointRectangle Integer
    pixelsToCoordinates Rectangle
    r1
              PointRectangle r2_x1 :: Integer
    r2_x1 r2_y1 :: Integer
    r2_y1 r2_x2 :: Integer
    r2_x2 r2_y2 :: Integer
    r2_y2 = Rectangle -> PointRectangle Integer
    pixelsToCoordinates Rectangle
    r2
              -- top - assuming (0,0) is top-left
              rt :: [PointRectangle Integer]
    rt = if Integer
    r2_y1 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > Integer
    r1_y1 Bool -> Bool -> Bool
    && Integer
    r2_y1 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < Integer
    r1_y2
                   then [Integer -> Integer -> Integer -> Integer -> PointRectangle Integer
    forall a. a -> a -> a -> a -> PointRectangle a
    PointRectangle (Integer -> Integer -> Integer
    forall a. Ord a => a -> a -> a
    max Integer
    r2_x1 Integer
    r1_x1) Integer
    r1_y1 Integer
    r1_x2 Integer
    r2_y1]
                   else []
              -- right
              rr :: [PointRectangle Integer]
    rr = if Integer
    r2_x2 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > Integer
    r1_x1 Bool -> Bool -> Bool
    && Integer
    r2_x2 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < Integer
    r1_x2
                   then [Integer -> Integer -> Integer -> Integer -> PointRectangle Integer
    forall a. a -> a -> a -> a -> PointRectangle a
    PointRectangle Integer
    r2_x2 (Integer -> Integer -> Integer
    forall a. Ord a => a -> a -> a
    max Integer
    r2_y1 Integer
    r1_y1) Integer
    r1_x2 Integer
    r1_y2]
                   else []
              -- bottom
              rb :: [PointRectangle Integer]
    rb = if Integer
    r2_y2 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > Integer
    r1_y1 Bool -> Bool -> Bool
    && Integer
    r2_y2 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < Integer
    r1_y2
                   then [Integer -> Integer -> Integer -> Integer -> PointRectangle Integer
    forall a. a -> a -> a -> a -> PointRectangle a
    PointRectangle Integer
    r1_x1 Integer
    r2_y2 (Integer -> Integer -> Integer
    forall a. Ord a => a -> a -> a
    min Integer
    r2_x2 Integer
    r1_x2) Integer
    r1_y2]
                   else []
              -- left
              rl :: [PointRectangle Integer]
    rl = if Integer
    r2_x1 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > Integer
    r1_x1 Bool -> Bool -> Bool
    && Integer
    r2_x1 Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < Integer
    r1_x2
                   then [Integer -> Integer -> Integer -> Integer -> PointRectangle Integer
    forall a. a -> a -> a -> a -> PointRectangle a
    PointRectangle Integer
    r1_x1 Integer
    r1_y1 Integer
    r2_x1 (Integer -> Integer -> Integer
    forall a. Ord a => a -> a -> a
    min Integer
    r2_y2 Integer
    r1_y2)]
                   else []

    -- | Fit a 'Rectangle' within the given borders of itself. Given insufficient
    -- space, borders are minimized while preserving the ratio of opposite borders.
    -- Origin is top-left, and yes, negative borders are allowed.
    withBorder :: Integer -- ^ Top border.
               -> Integer -- ^ Bottom border.
               -> Integer -- ^ Right border.
               -> Integer -- ^ Left border.
               -> Integer -- ^ Smallest allowable rectangle dimensions, i.e.
                          --   width/height, with values @<0@ defaulting to @0@.
               -> Rectangle -> Rectangle
    withBorder :: Integer
    -> Integer
    -> Integer
    -> Integer
    -> Integer
    -> Rectangle
    -> Rectangle
    withBorder t :: Integer
    t b :: Integer
    b r :: Integer
    r l :: Integer
    l i :: Integer
    i (Rectangle x :: Position
    x y :: Position
    y w :: Dimension
    w h :: Dimension
    h) =
        let -- conversions
            w' :: Integer
    w' = Dimension -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    w
            h' :: Integer
    h' = Dimension -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    h
            -- minimum window dimensions
            i' :: Integer
    i' = Integer -> Integer -> Integer
    forall a. Ord a => a -> a -> a
    max Integer
    i 0
            iw :: Integer
    iw = Integer -> Integer -> Integer
    forall a. Ord a => a -> a -> a
    min Integer
    i' Integer
    w'
            ih :: Integer
    ih = Integer -> Integer -> Integer
    forall a. Ord a => a -> a -> a
    min Integer
    i' Integer
    h'
            -- maximum border dimensions
            bh :: Integer
    bh = Integer
    w' Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    - Integer
    iw
            bv :: Integer
    bv = Integer
    h' Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    - Integer
    ih
            -- scaled border ratios
            rh :: Ratio Integer
    rh = if Integer
    l Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + Integer
    r Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    <= 0
                 then 1
                 else Ratio Integer -> Ratio Integer -> Ratio Integer
    forall a. Ord a => a -> a -> a
    min 1 (Ratio Integer -> Ratio Integer) -> Ratio Integer -> Ratio Integer
    forall a b. (a -> b) -> a -> b
    $ Integer
    bh Integer -> Integer -> Ratio Integer
    forall a. Integral a => a -> a -> Ratio a
    % (Integer
    l Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + Integer
    r)
            rv :: Ratio Integer
    rv = if Integer
    t Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + Integer
    b Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    <= 0
                 then 1
                 else Ratio Integer -> Ratio Integer -> Ratio Integer
    forall a. Ord a => a -> a -> a
    min 1 (Ratio Integer -> Ratio Integer) -> Ratio Integer -> Ratio Integer
    forall a b. (a -> b) -> a -> b
    $ Integer
    bv Integer -> Integer -> Ratio Integer
    forall a. Integral a => a -> a -> Ratio a
    % (Integer
    t Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + Integer
    b)
            -- scaled border pixels
            t' :: Position
    t' = Ratio Integer -> Position
    forall a b. (RealFrac a, Integral b) => a -> b
    truncate (Ratio Integer -> Position) -> Ratio Integer -> Position
    forall a b. (a -> b) -> a -> b
    $ Ratio Integer
    rv Ratio Integer -> Ratio Integer -> Ratio Integer
    forall a. Num a => a -> a -> a
    * Integer -> Ratio Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    t
            b' :: Dimension
    b' = Ratio Integer -> Dimension
    forall a b. (RealFrac a, Integral b) => a -> b
    truncate (Ratio Integer -> Dimension) -> Ratio Integer -> Dimension
    forall a b. (a -> b) -> a -> b
    $ Ratio Integer
    rv Ratio Integer -> Ratio Integer -> Ratio Integer
    forall a. Num a => a -> a -> a
    * Integer -> Ratio Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    b
            r' :: Dimension
    r' = Ratio Integer -> Dimension
    forall a b. (RealFrac a, Integral b) => a -> b
    truncate (Ratio Integer -> Dimension) -> Ratio Integer -> Dimension
    forall a b. (a -> b) -> a -> b
    $ Ratio Integer
    rh Ratio Integer -> Ratio Integer -> Ratio Integer
    forall a. Num a => a -> a -> a
    * Integer -> Ratio Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    r
            l' :: Position
    l' = Ratio Integer -> Position
    forall a b. (RealFrac a, Integral b) => a -> b
    truncate (Ratio Integer -> Position) -> Ratio Integer -> Position
    forall a b. (a -> b) -> a -> b
    $ Ratio Integer
    rh Ratio Integer -> Ratio Integer -> Ratio Integer
    forall a. Num a => a -> a -> a
    * Integer -> Ratio Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    l
        in  Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle (Position
    x Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + Position
    l')
                      (Position
    y Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + Position
    t')
                      (Dimension
    w Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    r' Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Position -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    l')
                      (Dimension
    h Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    b' Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Position -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    t')

    -- | Calculate the center - @(x,y)@ - as if the 'Rectangle' were bounded.
    center :: Rectangle -> (Ratio Integer,Ratio Integer)
    center :: Rectangle -> (Ratio Integer, Ratio Integer)
    center (Rectangle x :: Position
    x y :: Position
    y w :: Dimension
    w h :: Dimension
    h) = (Ratio Integer
    cx,Ratio Integer
    cy)
        where cx :: Ratio Integer
    cx = Position -> Ratio Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    x Ratio Integer -> Ratio Integer -> Ratio Integer
    forall a. Num a => a -> a -> a
    + (Dimension -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    w) Integer -> Integer -> Ratio Integer
    forall a. Integral a => a -> a -> Ratio a
    % 2
              cy :: Ratio Integer
    cy = Position -> Ratio Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    y Ratio Integer -> Ratio Integer -> Ratio Integer
    forall a. Num a => a -> a -> a
    + (Dimension -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    h) Integer -> Integer -> Ratio Integer
    forall a. Integral a => a -> a -> Ratio a
    % 2

    -- | Invert 'scaleRationalRect'. Since that operation is lossy a roundtrip
    -- conversion may not result in the original value. The first 'Rectangle' is
    -- scaled to the second:
    --
    -- >>> (Rectangle 2 2 6 6) `toRatio` (Rectangle 0 0 10 10)
    -- RationalRect (1 % 5) (1 % 5) (3 % 5) (3 % 5)
    toRatio :: Rectangle -> Rectangle -> W.RationalRect
    toRatio :: Rectangle -> Rectangle -> RationalRect
    toRatio (Rectangle x1 :: Position
    x1 y1 :: Position
    y1 w1 :: Dimension
    w1 h1 :: Dimension
    h1) (Rectangle x2 :: Position
    x2 y2 :: Position
    y2 w2 :: Dimension
    w2 h2 :: Dimension
    h2) =
        let [x1n :: Ratio Integer
    x1n,y1n :: Ratio Integer
    y1n,x2n :: Ratio Integer
    x2n,y2n :: Ratio Integer
    y2n] = (Position -> Ratio Integer) -> [Position] -> [Ratio Integer]
    forall a b. (a -> b) -> [a] -> [b]
    map Position -> Ratio Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral [Position
    x1,Position
    y1,Position
    x2,Position
    y2]
            [w1n :: Ratio Integer
    w1n,h1n :: Ratio Integer
    h1n,w2n :: Ratio Integer
    w2n,h2n :: Ratio Integer
    h2n] = (Dimension -> Ratio Integer) -> [Dimension] -> [Ratio Integer]
    forall a b. (a -> b) -> [a] -> [b]
    map Dimension -> Ratio Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral [Dimension
    w1,Dimension
    h1,Dimension
    w2,Dimension
    h2]
        in  Ratio Integer
    -> Ratio Integer -> Ratio Integer -> Ratio Integer -> RationalRect
    W.RationalRect ((Ratio Integer
    x1nRatio Integer -> Ratio Integer -> Ratio Integer
    forall a. Num a => a -> a -> a
    -Ratio Integer
    x2n)Ratio Integer -> Ratio Integer -> Ratio Integer
    forall a. Fractional a => a -> a -> a
    /Ratio Integer
    w2n) ((Ratio Integer
    y1nRatio Integer -> Ratio Integer -> Ratio Integer
    forall a. Num a => a -> a -> a
    -Ratio Integer
    y2n)Ratio Integer -> Ratio Integer -> Ratio Integer
    forall a. Fractional a => a -> a -> a
    /Ratio Integer
    h2n) (Ratio Integer
    w1nRatio Integer -> Ratio Integer -> Ratio Integer
    forall a. Fractional a => a -> a -> a
    /Ratio Integer
    w2n) (Ratio Integer
    h1nRatio Integer -> Ratio Integer -> Ratio Integer
    forall a. Fractional a => a -> a -> a
    /Ratio Integer
    h2n)