-- | Sizes a block element & positions their children.
-- Taking into account size bounds.
module Graphics.Layout.Flow(flowMinWidth, flowNatWidth, flowMaxWidth, flowWidth,
        flowNatHeight, flowMinHeight, flowMaxHeight, flowHeight,
        positionFlow, layoutFlow) where

import Graphics.Layout.Box as B

-- | Compute the minimum width of a block element with children of the given sizes.
flowMinWidth :: Double -> PaddedBox a Length -> [PaddedBox b Double] -> Double
flowMinWidth :: forall a b.
Double -> PaddedBox a Length -> [PaddedBox b Double] -> Double
flowMinWidth Double
_ PaddedBox {min :: forall m n. PaddedBox m n -> Size m n
B.min = Size (Pixels Double
x) a
_} [PaddedBox b Double]
_ = Double
x
flowMinWidth Double
parent PaddedBox {min :: forall m n. PaddedBox m n -> Size m n
B.min = Size (Percent Double
x) a
_} [PaddedBox b Double]
_ = Double
x forall a. Num a => a -> a -> a
* Double
parent
flowMinWidth Double
parent self :: PaddedBox a Length
self@PaddedBox {min :: forall m n. PaddedBox m n -> Size m n
B.min = Size Length
Preferred a
_} [PaddedBox b Double]
childs =
    forall a b.
Double -> PaddedBox a Length -> [PaddedBox b Double] -> Double
flowNatWidth Double
parent PaddedBox a Length
self [PaddedBox b Double]
childs
flowMinWidth Double
_ PaddedBox a Length
_ [PaddedBox b Double]
childs = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum forall a b. (a -> b) -> a -> b
$ (Double
0forall a. a -> [a] -> [a]
:) forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall {a} {m}. Num a => PaddedBox m a -> a
minWidth [PaddedBox b Double]
childs
-- | Compute the natural width of a block element with children of the given sizes.
flowNatWidth :: Double -> PaddedBox a Length -> [PaddedBox b Double] -> Double
flowNatWidth :: forall a b.
Double -> PaddedBox a Length -> [PaddedBox b Double] -> Double
flowNatWidth Double
_ PaddedBox {size :: forall m n. PaddedBox m n -> Size m n
size = Size (Pixels Double
x) a
_} [PaddedBox b Double]
_ = Double
x
flowNatWidth Double
parent PaddedBox {size :: forall m n. PaddedBox m n -> Size m n
size = Size (Percent Double
x) a
_} [PaddedBox b Double]
_ = Double
x forall a. Num a => a -> a -> a
* Double
parent
flowNatWidth Double
parent self :: PaddedBox a Length
self@PaddedBox {size :: forall m n. PaddedBox m n -> Size m n
size = Size Length
Min a
_, min :: forall m n. PaddedBox m n -> Size m n
B.min = Size Length
x a
_} [PaddedBox b Double]
childs
    -- Avoid infinite loops!
    | Length
x forall a. Eq a => a -> a -> Bool
/= Length
Preferred = forall a b.
Double -> PaddedBox a Length -> [PaddedBox b Double] -> Double
flowMinWidth Double
parent PaddedBox a Length
self [PaddedBox b Double]
childs
flowNatWidth Double
parent PaddedBox a Length
_ [PaddedBox b Double]
childs = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum forall a b. (a -> b) -> a -> b
$ (Double
0forall a. a -> [a] -> [a]
:) forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall {a} {m}. Num a => PaddedBox m a -> a
maxWidth [PaddedBox b Double]
childs
-- | Compute the maximum width of a block element inside the given parent size.
flowMaxWidth :: PaddedBox a Double -> PaddedBox b Length -> Double
flowMaxWidth :: forall a b. PaddedBox a Double -> PaddedBox b Length -> Double
flowMaxWidth PaddedBox a Double
_ PaddedBox {max :: forall m n. PaddedBox m n -> Size m n
B.max = Size (Pixels Double
x) b
_} = Double
x
flowMaxWidth PaddedBox a Double
parent PaddedBox {max :: forall m n. PaddedBox m n -> Size m n
B.max = Size (Percent Double
x) b
_} = Double
x forall a. Num a => a -> a -> a
* (forall m n. Size m n -> n
inline forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
size PaddedBox a Double
parent)
flowMaxWidth PaddedBox a Double
parent self :: PaddedBox b Length
self@PaddedBox {max :: forall m n. PaddedBox m n -> Size m n
B.max = Size Length
Auto b
_} = forall m n. Size m n -> n
inline (forall m n. PaddedBox m n -> Size m n
size PaddedBox a Double
parent) forall a. Num a => a -> a -> a
- Double
ws
    where
        ws :: Double
ws = Length -> Double
l2d (forall m n. Border m n -> n
left forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
margin PaddedBox b Length
self) forall a. Num a => a -> a -> a
+ Length -> Double
l2d (forall m n. Border m n -> n
left forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
border PaddedBox b Length
self) forall a. Num a => a -> a -> a
+ Length -> Double
l2d (forall m n. Border m n -> n
left forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
padding PaddedBox b Length
self) forall a. Num a => a -> a -> a
+
            Length -> Double
l2d (forall m n. Border m n -> n
right forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
padding PaddedBox b Length
self) forall a. Num a => a -> a -> a
+ Length -> Double
l2d (forall m n. Border m n -> n
right forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
border PaddedBox b Length
self) forall a. Num a => a -> a -> a
+ Length -> Double
l2d (forall m n. Border m n -> n
right forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
margin PaddedBox b Length
self)
        l2d :: Length -> Double
l2d = Double -> Length -> Double
lowerLength forall a b. (a -> b) -> a -> b
$ forall m n. Size m n -> n
inline forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
size PaddedBox a Double
parent
flowMaxWidth PaddedBox a Double
parent self :: PaddedBox b Length
self@PaddedBox {max :: forall m n. PaddedBox m n -> Size m n
B.max = Size Length
Preferred b
_} =
    forall a b.
Double -> PaddedBox a Length -> [PaddedBox b Double] -> Double
flowNatWidth (forall m n. Size m n -> n
inline forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
size PaddedBox a Double
parent) PaddedBox b Length
self []
flowMaxWidth PaddedBox a Double
parent self :: PaddedBox b Length
self@PaddedBox {max :: forall m n. PaddedBox m n -> Size m n
B.max = Size Length
Min b
_} =
    forall a b.
Double -> PaddedBox a Length -> [PaddedBox b Double] -> Double
flowMinWidth (forall m n. Size m n -> n
inline forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
B.min PaddedBox a Double
parent) PaddedBox b Length
self []
-- | Compute final block element width based on cached width computations &
-- parent size.
flowWidth :: PaddedBox a Double -> PaddedBox b Length -> Double
flowWidth :: forall a b. PaddedBox a Double -> PaddedBox b Length -> Double
flowWidth PaddedBox a Double
parent PaddedBox b Length
self
    | Double
small forall a. Ord a => a -> a -> Bool
> Double
large = Double
small
    | Double
natural forall a. Ord a => a -> a -> Bool
> Double
large = Double
large
    | forall m n. Size m n -> n
inline (forall m n. PaddedBox m n -> Size m n
size PaddedBox b Length
self) forall a. Eq a => a -> a -> Bool
== Length
Auto = Double
large -- specialcase
    | Double
natural forall a. Ord a => a -> a -> Bool
>= Double
small = Double
natural
    | Bool
otherwise = Double
small
  where
    small :: Double
small = forall a b.
Double -> PaddedBox a Length -> [PaddedBox b Double] -> Double
flowMinWidth (forall m n. Size m n -> n
inline forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
B.min PaddedBox a Double
parent) PaddedBox b Length
self []
    natural :: Double
natural = forall a b.
Double -> PaddedBox a Length -> [PaddedBox b Double] -> Double
flowNatWidth (forall m n. Size m n -> n
inline forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
size PaddedBox a Double
parent) PaddedBox b Length
self []
    large :: Double
large = forall a b. PaddedBox a Double -> PaddedBox b Length -> Double
flowMaxWidth PaddedBox a Double
parent PaddedBox b Length
self

-- | Compute natural block element height at cached width.
flowNatHeight :: Double -> PaddedBox Length Double -> [PaddedBox Double Double] -> Double
flowNatHeight :: Double
-> PaddedBox Length Double -> [PaddedBox Double Double] -> Double
flowNatHeight Double
_ PaddedBox {size :: forall m n. PaddedBox m n -> Size m n
size = Size Double
_ (Pixels Double
y)} [PaddedBox Double Double]
_ = Double
y
flowNatHeight Double
parent PaddedBox {size :: forall m n. PaddedBox m n -> Size m n
size = Size Double
_ (Percent Double
y)} [PaddedBox Double Double]
_ = Double
y forall a. Num a => a -> a -> a
* Double
parent
flowNatHeight Double
_ PaddedBox {size :: forall m n. PaddedBox m n -> Size m n
size = Size Double
_ Length
Min} [PaddedBox Double Double]
childs =
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall {a} {n}. Num a => PaddedBox a n -> a
minHeight forall a b. (a -> b) -> a -> b
$ forall n. [PaddedBox Double n] -> [PaddedBox Double n]
marginCollapse [PaddedBox Double Double]
childs
flowNatHeight Double
_ PaddedBox {size :: forall m n. PaddedBox m n -> Size m n
size = Size Double
owidth Length
_} [PaddedBox Double Double]
childs =
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall {a} {n}. Num a => PaddedBox a n -> a
height forall a b. (a -> b) -> a -> b
$ forall n. [PaddedBox Double n] -> [PaddedBox Double n]
marginCollapse [PaddedBox Double Double]
childs
-- | Compute minimum block height at cached width.
flowMinHeight :: Double -> PaddedBox Length Double -> Double
flowMinHeight :: Double -> PaddedBox Length Double -> Double
flowMinHeight Double
_ PaddedBox {min :: forall m n. PaddedBox m n -> Size m n
B.min = Size Double
_ (Pixels Double
y)} = Double
y
flowMinHeight Double
parent PaddedBox {min :: forall m n. PaddedBox m n -> Size m n
B.min = Size Double
_ (Percent Double
y)} = Double
y forall a. Num a => a -> a -> a
* Double
parent
flowMinHeight Double
parent PaddedBox Length Double
self = Double
-> PaddedBox Length Double -> [PaddedBox Double Double] -> Double
flowNatHeight Double
parent PaddedBox Length Double
self []
-- | Compute maximum block height at cached width.
flowMaxHeight :: Double -> PaddedBox Length Double -> Double
flowMaxHeight :: Double -> PaddedBox Length Double -> Double
flowMaxHeight Double
_ PaddedBox {max :: forall m n. PaddedBox m n -> Size m n
B.max = Size Double
_ (Pixels Double
y)} = Double
y
flowMaxHeight Double
parent PaddedBox {max :: forall m n. PaddedBox m n -> Size m n
B.max = Size Double
_ (Percent Double
y)} = Double
y forall a. Num a => a -> a -> a
* Double
parent
flowMaxHeight Double
parent PaddedBox {max :: forall m n. PaddedBox m n -> Size m n
B.max = Size Double
_ Length
Auto} = Double
parent
flowMaxHeight Double
parent self :: PaddedBox Length Double
self@PaddedBox {max :: forall m n. PaddedBox m n -> Size m n
B.max = Size Double
_ Length
Preferred} = Double
-> PaddedBox Length Double -> [PaddedBox Double Double] -> Double
flowNatHeight Double
parent PaddedBox Length Double
self []
flowMaxHeight Double
parent self :: PaddedBox Length Double
self@PaddedBox {max :: forall m n. PaddedBox m n -> Size m n
B.max = Size Double
_ Length
Min} = Double -> PaddedBox Length Double -> Double
flowMinHeight Double
parent PaddedBox Length Double
self
-- | Compute final block height at cached width.
flowHeight :: PaddedBox Double Double -> PaddedBox Length Double -> Double
flowHeight :: PaddedBox Double Double -> PaddedBox Length Double -> Double
flowHeight PaddedBox Double Double
parent PaddedBox Length Double
self
    | Double
small forall a. Ord a => a -> a -> Bool
> Double
large = Double
small
    | Double
natural forall a. Ord a => a -> a -> Bool
> Double
large = Double
large
    | Double
natural forall a. Ord a => a -> a -> Bool
>= Double
small = Double
natural
    | Bool
otherwise = Double
small
  where
    small :: Double
small = Double -> PaddedBox Length Double -> Double
flowMinHeight (forall m n. Size m n -> m
block forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
B.min PaddedBox Double Double
parent) PaddedBox Length Double
self
    natural :: Double
natural = Double
-> PaddedBox Length Double -> [PaddedBox Double Double] -> Double
flowNatHeight (forall m n. Size m n -> m
block forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size Double Double
B.nat PaddedBox Double Double
parent) PaddedBox Length Double
self []
    large :: Double
large = Double -> PaddedBox Length Double -> Double
flowMaxHeight (forall m n. Size m n -> m
block forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
B.max PaddedBox Double Double
parent) PaddedBox Length Double
self

-- | Compute position of all children relative to this block element.
positionFlow :: [PaddedBox Double Double] -> [Size Double Double]
positionFlow :: [PaddedBox Double Double] -> [Size Double Double]
positionFlow [PaddedBox Double Double]
childs = forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl forall {m} {m} {n} {n}.
Num m =>
Size m n -> PaddedBox m n -> Size m n
inner (forall m n. n -> m -> Size m n
Size Double
0 Double
0) forall a b. (a -> b) -> a -> b
$ forall n. [PaddedBox Double n] -> [PaddedBox Double n]
marginCollapse [PaddedBox Double Double]
childs
  where inner :: Size m n -> PaddedBox m n -> Size m n
inner (Size n
x m
y) PaddedBox m n
self = forall m n. n -> m -> Size m n
Size n
x forall a b. (a -> b) -> a -> b
$ forall {a} {n}. Num a => PaddedBox a n -> a
height PaddedBox m n
self
-- | Compute size given block element in given parent,
-- & position of given children.
layoutFlow :: PaddedBox Double Double -> PaddedBox Length Length ->
        [PaddedBox Length Double] ->
        (PaddedBox Double Double, [(Size Double Double, PaddedBox Double Double)])
layoutFlow :: PaddedBox Double Double
-> PaddedBox Length Length
-> [PaddedBox Length Double]
-> (PaddedBox Double Double,
    [(Size Double Double, PaddedBox Double Double)])
layoutFlow PaddedBox Double Double
parent PaddedBox Length Length
self [PaddedBox Length Double]
childs = (PaddedBox Double Double
self', forall a b. [a] -> [b] -> [(a, b)]
zip [Size Double Double]
positions' [PaddedBox Double Double]
childs')
  where
    positions' :: [Size Double Double]
positions' = [PaddedBox Double Double] -> [Size Double Double]
positionFlow [PaddedBox Double Double]
childs'
    childs' :: [PaddedBox Double Double]
childs' = forall a b. (a -> b) -> [a] -> [b]
map PaddedBox Length Double -> PaddedBox Double Double
layoutZooko [PaddedBox Length Double]
childs
    self' :: PaddedBox Double Double
self' = PaddedBox Length Double
self0 {
        min :: Size Double Double
B.min = (forall m n. PaddedBox m n -> Size m n
B.min PaddedBox Length Double
self0) { block :: Double
block = Double -> PaddedBox Length Double -> Double
flowMinHeight (forall m n. Size m n -> m
block forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
B.min PaddedBox Double Double
parent) PaddedBox Length Double
self0 },
        size :: Size Double Double
size = (forall m n. PaddedBox m n -> Size m n
size PaddedBox Length Double
self0) { block :: Double
block = PaddedBox Double Double -> PaddedBox Length Double -> Double
flowHeight PaddedBox Double Double
parent PaddedBox Length Double
self0 },
        max :: Size Double Double
B.max = (forall m n. PaddedBox m n -> Size m n
B.max PaddedBox Length Double
self0) { block :: Double
block = Double -> PaddedBox Length Double -> Double
flowMaxHeight (forall m n. Size m n -> m
block forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
B.max PaddedBox Double Double
parent) PaddedBox Length Double
self0 },
        padding :: Border Double Double
padding = forall m mm n. (m -> mm) -> Border m n -> Border mm n
mapY (Double -> Length -> Double
lowerLength Double
owidth) forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
padding PaddedBox Length Double
self0,
        border :: Border Double Double
border = forall m mm n. (m -> mm) -> Border m n -> Border mm n
mapY (Double -> Length -> Double
lowerLength Double
owidth) forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
border PaddedBox Length Double
self0,
        margin :: Border Double Double
margin = forall m mm n. (m -> mm) -> Border m n -> Border mm n
mapY (Double -> Length -> Double
lowerLength Double
owidth) forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
margin PaddedBox Length Double
self0
      }
    self0 :: PaddedBox Length Double
self0 = PaddedBox Length Double
self1 {
        size :: Size Length Double
size = (forall m n. PaddedBox m n -> Size m n
size PaddedBox Length Double
self1) { block :: Length
block = Double -> Length
Pixels forall a b. (a -> b) -> a -> b
$ Double
-> PaddedBox Length Double -> [PaddedBox Double Double] -> Double
flowNatHeight Double
oheight PaddedBox Length Double
self1 [PaddedBox Double Double]
childs'}
      }
    self1 :: PaddedBox Length Double
self1 = PaddedBox Length Length
self2 {
        size :: Size Length Double
size = (forall m n. PaddedBox m n -> Size m n
size PaddedBox Length Length
self2) { inline :: Double
inline = Double
width' },
        max :: Size Length Double
B.max = (forall m n. PaddedBox m n -> Size m n
B.max PaddedBox Length Length
self2) { inline :: Double
inline = forall a b. PaddedBox a Double -> PaddedBox b Length -> Double
flowMaxWidth PaddedBox Double Double
parent PaddedBox Length Length
self2 },
        min :: Size Length Double
B.min = (forall m n. PaddedBox m n -> Size m n
B.min PaddedBox Length Length
self2) { inline :: Double
inline = forall a b.
Double -> PaddedBox a Length -> [PaddedBox b Double] -> Double
flowMinWidth Double
owidth PaddedBox Length Length
self2 [] },
        padding :: Border Length Double
padding = forall n nn m. (n -> nn) -> Border m n -> Border m nn
mapX (Double -> Length -> Double
lowerLength Double
owidth) forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
padding PaddedBox Length Length
self2,
        border :: Border Length Double
border = forall n nn m. (n -> nn) -> Border m n -> Border m nn
mapX (Double -> Length -> Double
lowerLength Double
owidth) forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
border PaddedBox Length Length
self2,
        margin :: Border Length Double
margin = forall m. Double -> Double -> Border m Length -> Border m Double
lowerMargin Double
owidth (Double
owidth forall a. Num a => a -> a -> a
- Double
width') forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
margin PaddedBox Length Length
self2
      }
    width' :: Double
width' = forall a b. PaddedBox a Double -> PaddedBox b Length -> Double
flowWidth PaddedBox Double Double
parent PaddedBox Length Length
self
    self2 :: PaddedBox Length Length
self2 = PaddedBox Length Length
self {
        size :: Size Length Length
size = (forall m n. PaddedBox m n -> Size m n
size PaddedBox Length Length
self) { inline :: Length
inline = Double -> Length
Pixels forall a b. (a -> b) -> a -> b
$ forall a b.
Double -> PaddedBox a Length -> [PaddedBox b Double] -> Double
flowNatWidth Double
owidth PaddedBox Length Length
self [PaddedBox Length Double]
childs },
        min :: Size Length Length
B.min = (forall m n. PaddedBox m n -> Size m n
B.min PaddedBox Length Length
self) { inline :: Length
inline = Double -> Length
Pixels forall a b. (a -> b) -> a -> b
$ forall a b.
Double -> PaddedBox a Length -> [PaddedBox b Double] -> Double
flowMinWidth Double
owidth PaddedBox Length Length
self [PaddedBox Length Double]
childs }
      }
    owidth :: Double
owidth = forall m n. Size m n -> n
inline forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
size PaddedBox Double Double
parent
    oheight :: Double
oheight = forall m n. Size m n -> m
block forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
size PaddedBox Double Double
parent
    layoutZooko :: PaddedBox Length Double -> PaddedBox Double Double
layoutZooko PaddedBox Length Double
child = PaddedBox Length Double
child {
        min :: Size Double Double
B.min = forall m n. n -> m -> Size m n
Size (forall m n. Size m n -> n
inline forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
B.min PaddedBox Length Double
child) (Double -> PaddedBox Length Double -> Double
flowMinHeight (forall m n. Size m n -> m
block forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
B.min PaddedBox Double Double
self') PaddedBox Length Double
child),
        size :: Size Double Double
size = forall m n. n -> m -> Size m n
Size (forall m n. Size m n -> n
inline forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
size PaddedBox Length Double
child) (PaddedBox Double Double -> PaddedBox Length Double -> Double
flowHeight PaddedBox Double Double
self' PaddedBox Length Double
child),
        max :: Size Double Double
B.max = forall m n. n -> m -> Size m n
Size (forall m n. Size m n -> n
inline forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
B.max PaddedBox Length Double
child) (Double -> PaddedBox Length Double -> Double
flowMaxHeight (forall m n. Size m n -> m
block forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Size m n
size PaddedBox Double Double
self') PaddedBox Length Double
child),
        padding :: Border Double Double
padding = forall m mm n. (m -> mm) -> Border m n -> Border mm n
mapY (Double -> Length -> Double
lowerLength Double
owidth) forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
padding PaddedBox Length Double
child,
        border :: Border Double Double
border = forall m mm n. (m -> mm) -> Border m n -> Border mm n
mapY (Double -> Length -> Double
lowerLength Double
owidth) forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
border PaddedBox Length Double
child,
        margin :: Border Double Double
margin = forall m mm n. (m -> mm) -> Border m n -> Border mm n
mapY (Double -> Length -> Double
lowerLength Double
owidth) forall a b. (a -> b) -> a -> b
$ forall m n. PaddedBox m n -> Border m n
margin PaddedBox Length Double
child
      }

-- | Removes overlapping margins.
marginCollapse :: [PaddedBox Double n] -> [PaddedBox Double n]
marginCollapse :: forall n. [PaddedBox Double n] -> [PaddedBox Double n]
marginCollapse (x' :: PaddedBox Double n
x'@PaddedBox {margin :: forall m n. PaddedBox m n -> Border m n
margin = xm :: Border Double n
xm@Border { bottom :: forall m n. Border m n -> m
bottom = Double
x }}:
        y' :: PaddedBox Double n
y'@PaddedBox {margin :: forall m n. PaddedBox m n -> Border m n
margin = ym :: Border Double n
ym@Border { top :: forall m n. Border m n -> m
top = Double
y}}:[PaddedBox Double n]
rest)
    | Double
x forall a. Ord a => a -> a -> Bool
> Double
y = PaddedBox Double n
x'forall a. a -> [a] -> [a]
:forall n. [PaddedBox Double n] -> [PaddedBox Double n]
marginCollapse (PaddedBox Double n
y' {margin :: Border Double n
margin = Border Double n
ym { top :: Double
top = Double
0 }}forall a. a -> [a] -> [a]
:[PaddedBox Double n]
rest)
    | Bool
otherwise = PaddedBox Double n
x' { margin :: Border Double n
margin = Border Double n
xm { bottom :: Double
bottom = Double
0 }}forall a. a -> [a] -> [a]
:forall n. [PaddedBox Double n] -> [PaddedBox Double n]
marginCollapse (PaddedBox Double n
y'forall a. a -> [a] -> [a]
:[PaddedBox Double n]
rest)
marginCollapse [PaddedBox Double n]
rest = [PaddedBox Double n]
rest

-- | Resolves auto paddings or margins to fill given width.
lowerMargin :: Double -> Double -> Border m Length -> Border m Double
lowerMargin :: forall m. Double -> Double -> Border m Length -> Border m Double
lowerMargin Double
_ Double
available (Border m
top' m
bottom' Length
Auto Length
Auto) =
    forall m n. m -> m -> n -> n -> Border m n
Border m
top' m
bottom' (Double
availableforall a. Fractional a => a -> a -> a
/Double
2) (Double
availableforall a. Fractional a => a -> a -> a
/Double
2)
lowerMargin Double
outerwidth Double
available (Border m
top' m
bottom' Length
Auto Length
right') =
    forall m n. m -> m -> n -> n -> Border m n
Border m
top' m
bottom' Double
available forall a b. (a -> b) -> a -> b
$ Double -> Length -> Double
lowerLength Double
outerwidth Length
right'
lowerMargin Double
outerwidth Double
available (Border m
top' m
bottom' Length
left' Length
Auto) =
    forall m n. m -> m -> n -> n -> Border m n
Border m
top' m
bottom' (Double -> Length -> Double
lowerLength Double
outerwidth Length
left') Double
available
lowerMargin Double
outerwidth Double
_ (Border m
top' m
bottom' Length
left' Length
right') =
    forall m n. m -> m -> n -> n -> Border m n
Border m
top' m
bottom' (Double -> Length -> Double
lowerLength Double
outerwidth Length
left') (Double -> Length -> Double
lowerLength Double
outerwidth Length
right')