{-# LANGUAGE TupleSections #-}
-- | Sizes inline text & extracts positioned children,
-- wraps Balkón for the actual logic.
module Graphics.Layout.Inline(paragraphMap, layoutMap, treeMap,
    inlineMin, inlineSize, inlineChildren, layoutSize, layoutChildren,
    treeBox, positionTree, treeInner, FragmentTree(..)) where

import Data.Text.ParagraphLayout.Rich (Paragraph(..), ParagraphOptions(..),
                                Fragment(..), ParagraphLayout(..), AncestorBox(..),
                                InnerNode(..), Box(..), RootNode(..),
                                layoutRich, boxSpacing, BoxSpacing(..))
import Data.Text.ParagraphLayout.Rect (Rect(..),
                                width, height, x_max, x_min, y_min, y_max)
import Data.Int (Int32)
import Debug.Trace (trace) -- To warn about unexpected branches!

import Graphics.Layout.Box hiding (min, max, width, height)
import qualified Graphics.Layout.Box as Box
import Graphics.Layout.CSS.Font (hbUnit)

-- | Convert from Harfbuzz units to device pixels as a Double
hbScale :: Int32 -> Double
hbScale :: Int32 -> Double
hbScale = (Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
hbUnit) (Double -> Double) -> (Int32 -> Double) -> Int32 -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral
-- | Convert from Harfbuzz units to device pixels as a Double or Length.
c :: CastDouble a => Int32 -> a
c :: Int32 -> a
c = Double -> a
forall a. CastDouble a => Double -> a
fromDouble (Double -> a) -> (Int32 -> Double) -> Int32 -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> Double
hbScale
-- | Convert from a CastDouble in device pixels to Harfbuzz units.
unscale :: CastDouble x => x -> Int32
unscale :: x -> Int32
unscale = Double -> Int32
forall a b. (RealFrac a, Integral b) => a -> b
floor (Double -> Int32) -> (x -> Double) -> x -> Int32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
hbUnit) (Double -> Double) -> (x -> Double) -> x -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Double
forall a. CastDouble a => a -> Double
toDouble

-- | Compute minimum width & height for some richtext.
inlineMin :: (CastDouble x, CastDouble y) =>
        Paragraph (a, PaddedBox x y, c) -> Size x y
inlineMin :: Paragraph (a, PaddedBox x y, c) -> Size x y
inlineMin self :: Paragraph (a, PaddedBox x y, c)
self = y -> x -> Size x y
forall m n. n -> m -> Size m n
Size (Int32 -> y
forall a. CastDouble a => Int32 -> a
c (Int32 -> y) -> Int32 -> y
forall a b. (a -> b) -> a -> b
$ Rect Int32 -> Int32
forall a. Num a => Rect a -> a
width Rect Int32
rect) (Int32 -> x
forall a. CastDouble a => Int32 -> a
c (Int32 -> x) -> Int32 -> x
forall a b. (a -> b) -> a -> b
$ Rect Int32 -> Int32
forall a. Num a => Rect a -> a
height Rect Int32
rect)
    where rect :: Rect Int32
rect = Paragraph (a, PaddedBox x y, c) -> Int32 -> Rect Int32
forall m n a c.
(CastDouble m, CastDouble n) =>
Paragraph (a, PaddedBox m n, c) -> Int32 -> Rect Int32
layoutRich' Paragraph (a, PaddedBox x y, c)
self 0
-- | Compute width & height of some richtext at configured width.
inlineSize :: (CastDouble x, CastDouble y) =>
        Paragraph (a, PaddedBox x y, c) -> Size x y
inlineSize :: Paragraph (a, PaddedBox x y, c) -> Size x y
inlineSize self :: Paragraph (a, PaddedBox x y, c)
self = ParagraphLayout (a, PaddedBox x y, c) -> Size x y
forall x y a.
(CastDouble x, CastDouble y) =>
ParagraphLayout a -> Size x y
layoutSize (ParagraphLayout (a, PaddedBox x y, c) -> Size x y)
-> ParagraphLayout (a, PaddedBox x y, c) -> Size x y
forall a b. (a -> b) -> a -> b
$ Paragraph (a, PaddedBox x y, c)
-> ParagraphLayout (a, PaddedBox x y, c)
forall d. Paragraph d -> ParagraphLayout d
layoutRich (Paragraph (a, PaddedBox x y, c)
 -> ParagraphLayout (a, PaddedBox x y, c))
-> Paragraph (a, PaddedBox x y, c)
-> ParagraphLayout (a, PaddedBox x y, c)
forall a b. (a -> b) -> a -> b
$ Paragraph (a, PaddedBox x y, c) -> Paragraph (a, PaddedBox x y, c)
forall m n a c.
(CastDouble m, CastDouble n) =>
Paragraph (a, PaddedBox m n, c) -> Paragraph (a, PaddedBox m n, c)
lowerSpacing Paragraph (a, PaddedBox x y, c)
self
-- | Retrieve children out of some richtext,
-- associating given userdata with them.
inlineChildren :: (CastDouble x, CastDouble y, Eq x, Eq y, Eq a, Eq c) =>
        Paragraph (a, PaddedBox x y, c) -> [FragmentTree (a, PaddedBox x y, c)]
inlineChildren :: Paragraph (a, PaddedBox x y, c)
-> [FragmentTree (a, PaddedBox x y, c)]
inlineChildren self :: Paragraph (a, PaddedBox x y, c)
self = ParagraphLayout (a, PaddedBox x y, c)
-> [FragmentTree (a, PaddedBox x y, c)]
forall a. Eq a => ParagraphLayout a -> [FragmentTree a]
layoutChildren (ParagraphLayout (a, PaddedBox x y, c)
 -> [FragmentTree (a, PaddedBox x y, c)])
-> ParagraphLayout (a, PaddedBox x y, c)
-> [FragmentTree (a, PaddedBox x y, c)]
forall a b. (a -> b) -> a -> b
$ Paragraph (a, PaddedBox x y, c)
-> ParagraphLayout (a, PaddedBox x y, c)
forall d. Paragraph d -> ParagraphLayout d
layoutRich (Paragraph (a, PaddedBox x y, c)
 -> ParagraphLayout (a, PaddedBox x y, c))
-> Paragraph (a, PaddedBox x y, c)
-> ParagraphLayout (a, PaddedBox x y, c)
forall a b. (a -> b) -> a -> b
$ Paragraph (a, PaddedBox x y, c) -> Paragraph (a, PaddedBox x y, c)
forall m n a c.
(CastDouble m, CastDouble n) =>
Paragraph (a, PaddedBox m n, c) -> Paragraph (a, PaddedBox m n, c)
lowerSpacing Paragraph (a, PaddedBox x y, c)
self

-- | Retrieve a laid-out paragraph's rect & convert to CatTrap types.
layoutSize :: (CastDouble x, CastDouble y) => ParagraphLayout a -> Size x y
layoutSize :: ParagraphLayout a -> Size x y
layoutSize self :: ParagraphLayout a
self = y -> x -> Size x y
forall m n. n -> m -> Size m n
Size (Int32 -> y
forall a. CastDouble a => Int32 -> a
c (Int32 -> y) -> Int32 -> y
forall a b. (a -> b) -> a -> b
$ Rect Int32 -> Int32
forall a. Num a => Rect a -> a
width Rect Int32
r) (Int32 -> x
forall a. CastDouble a => Int32 -> a
c (Int32 -> x) -> Int32 -> x
forall a b. (a -> b) -> a -> b
$ Rect Int32 -> Int32
forall a. Num a => Rect a -> a
height Rect Int32
r)
  where r :: Rect Int32
r = ParagraphLayout a -> Rect Int32
forall d. ParagraphLayout d -> Rect Int32
paragraphRect ParagraphLayout a
self
-- | Retrieve a laid-out paragraph's children & associate with given userdata.
layoutChildren :: Eq a => ParagraphLayout a -> [FragmentTree a]
layoutChildren :: ParagraphLayout a -> [FragmentTree a]
layoutChildren self :: ParagraphLayout a
self = ParagraphLayout a -> [FragmentTree a]
forall a. Eq a => ParagraphLayout a -> [FragmentTree a]
reconstructTree ParagraphLayout a
self

-- | Layout a paragraph at given width & retrieve resulting rect.
layoutRich' :: (CastDouble m, CastDouble n) =>
        Paragraph (a, PaddedBox m n, c) -> Int32 -> Rect Int32
layoutRich' :: Paragraph (a, PaddedBox m n, c) -> Int32 -> Rect Int32
layoutRich' (Paragraph a :: Array
a b :: Int
b c :: RootNode Int (a, PaddedBox m n, c)
c d :: ParagraphOptions
d) width :: Int32
width = ParagraphLayout (a, PaddedBox m n, c) -> Rect Int32
forall d. ParagraphLayout d -> Rect Int32
paragraphRect (ParagraphLayout (a, PaddedBox m n, c) -> Rect Int32)
-> ParagraphLayout (a, PaddedBox m n, c) -> Rect Int32
forall a b. (a -> b) -> a -> b
$ Paragraph (a, PaddedBox m n, c)
-> ParagraphLayout (a, PaddedBox m n, c)
forall d. Paragraph d -> ParagraphLayout d
layoutRich (Paragraph (a, PaddedBox m n, c)
 -> ParagraphLayout (a, PaddedBox m n, c))
-> Paragraph (a, PaddedBox m n, c)
-> ParagraphLayout (a, PaddedBox m n, c)
forall a b. (a -> b) -> a -> b
$
    Paragraph (a, PaddedBox m n, c) -> Paragraph (a, PaddedBox m n, c)
forall m n a c.
(CastDouble m, CastDouble n) =>
Paragraph (a, PaddedBox m n, c) -> Paragraph (a, PaddedBox m n, c)
lowerSpacing (Paragraph (a, PaddedBox m n, c)
 -> Paragraph (a, PaddedBox m n, c))
-> Paragraph (a, PaddedBox m n, c)
-> Paragraph (a, PaddedBox m n, c)
forall a b. (a -> b) -> a -> b
$ Array
-> Int
-> RootNode Int (a, PaddedBox m n, c)
-> ParagraphOptions
-> Paragraph (a, PaddedBox m n, c)
forall d.
Array -> Int -> RootNode Int d -> ParagraphOptions -> Paragraph d
Paragraph Array
a Int
b RootNode Int (a, PaddedBox m n, c)
c ParagraphOptions
d { paragraphMaxWidth :: Int32
paragraphMaxWidth = Int32
width }

-- | Copy surrounding whitespace into Balkon properties.
lowerSpacing :: (CastDouble m, CastDouble n) =>
    Paragraph (a, PaddedBox m n, c) -> Paragraph (a, PaddedBox m n, c)
lowerSpacing :: Paragraph (a, PaddedBox m n, c) -> Paragraph (a, PaddedBox m n, c)
lowerSpacing (Paragraph a :: Array
a b :: Int
b (RootBox c :: Box Int (a, PaddedBox m n, c)
c) d :: ParagraphOptions
d) = Array
-> Int
-> RootNode Int (a, PaddedBox m n, c)
-> ParagraphOptions
-> Paragraph (a, PaddedBox m n, c)
forall d.
Array -> Int -> RootNode Int d -> ParagraphOptions -> Paragraph d
Paragraph Array
a Int
b (Box Int (a, PaddedBox m n, c) -> RootNode Int (a, PaddedBox m n, c)
forall t d. Box t d -> RootNode t d
RootBox (Box Int (a, PaddedBox m n, c)
 -> RootNode Int (a, PaddedBox m n, c))
-> Box Int (a, PaddedBox m n, c)
-> RootNode Int (a, PaddedBox m n, c)
forall a b. (a -> b) -> a -> b
$ Box Int (a, PaddedBox m n, c) -> Box Int (a, PaddedBox m n, c)
forall x x t a c.
(CastDouble x, CastDouble x) =>
Box t (a, PaddedBox x x, c) -> Box t (a, PaddedBox x x, c)
inner Box Int (a, PaddedBox m n, c)
c) ParagraphOptions
d
  where
    inner :: Box t (a, PaddedBox x x, c) -> Box t (a, PaddedBox x x, c)
inner (Box childs :: [InnerNode t (a, PaddedBox x x, c)]
childs opts :: TextOptions
opts) = ([InnerNode t (a, PaddedBox x x, c)]
 -> TextOptions -> Box t (a, PaddedBox x x, c))
-> TextOptions
-> [InnerNode t (a, PaddedBox x x, c)]
-> Box t (a, PaddedBox x x, c)
forall a b c. (a -> b -> c) -> b -> a -> c
flip [InnerNode t (a, PaddedBox x x, c)]
-> TextOptions -> Box t (a, PaddedBox x x, c)
forall t d. [InnerNode t d] -> TextOptions -> Box t d
Box TextOptions
opts ([InnerNode t (a, PaddedBox x x, c)]
 -> Box t (a, PaddedBox x x, c))
-> [InnerNode t (a, PaddedBox x x, c)]
-> Box t (a, PaddedBox x x, c)
forall a b. (a -> b) -> a -> b
$ (InnerNode t (a, PaddedBox x x, c)
 -> InnerNode t (a, PaddedBox x x, c))
-> [InnerNode t (a, PaddedBox x x, c)]
-> [InnerNode t (a, PaddedBox x x, c)]
forall a b. (a -> b) -> [a] -> [b]
map InnerNode t (a, PaddedBox x x, c)
-> InnerNode t (a, PaddedBox x x, c)
inner' [InnerNode t (a, PaddedBox x x, c)]
childs
    inner' :: InnerNode t (a, PaddedBox x x, c)
-> InnerNode t (a, PaddedBox x x, c)
inner' (InlineBox e :: (a, PaddedBox x x, c)
e@(_, f :: PaddedBox x x
f, _) child :: Box t (a, PaddedBox x x, c)
child opts :: BoxOptions
opts) = (a, PaddedBox x x, c)
-> Box t (a, PaddedBox x x, c)
-> BoxOptions
-> InnerNode t (a, PaddedBox x x, c)
forall t d. d -> Box t d -> BoxOptions -> InnerNode t d
InlineBox (a, PaddedBox x x, c)
e (Box t (a, PaddedBox x x, c) -> Box t (a, PaddedBox x x, c)
inner Box t (a, PaddedBox x x, c)
child) BoxOptions
opts {
            boxSpacing :: BoxSpacing
boxSpacing = Int32 -> Int32 -> BoxSpacing
BoxSpacingLeftRight (PaddedBox Int32 Int32 -> Int32
forall n m. Num n => PaddedBox m n -> n
leftSpace PaddedBox Int32 Int32
box) (PaddedBox Int32 Int32 -> Int32
forall n m. Num n => PaddedBox m n -> n
rightSpace PaddedBox Int32 Int32
box)
        }
      where box :: PaddedBox Int32 Int32
box = (x -> Int32) -> PaddedBox Int32 x -> PaddedBox Int32 Int32
forall n nn m. (n -> nn) -> PaddedBox m n -> PaddedBox m nn
mapX' x -> Int32
forall x. CastDouble x => x -> Int32
unscale (PaddedBox Int32 x -> PaddedBox Int32 Int32)
-> PaddedBox Int32 x -> PaddedBox Int32 Int32
forall a b. (a -> b) -> a -> b
$ (x -> Int32) -> PaddedBox x x -> PaddedBox Int32 x
forall m mm n. (m -> mm) -> PaddedBox m n -> PaddedBox mm n
mapY' x -> Int32
forall x. CastDouble x => x -> Int32
unscale PaddedBox x x
f
    inner' self :: InnerNode t (a, PaddedBox x x, c)
self@(TextSequence _ _) = InnerNode t (a, PaddedBox x x, c)
self


data FragmentTree x = Branch (AncestorBox x) [FragmentTree x]
    | Leaf (Fragment x)

-- | Apply an operation to the 2nd field of the paragraph's userdata,
-- for it's entire subtree.
paragraphMap :: (b -> b') -> Paragraph (a, b, c) -> Paragraph (a, b', c)
paragraphMap :: (b -> b') -> Paragraph (a, b, c) -> Paragraph (a, b', c)
paragraphMap cb :: b -> b'
cb (Paragraph a :: Array
a b :: Int
b (RootBox c :: Box Int (a, b, c)
c) d :: ParagraphOptions
d) =
    Array
-> Int
-> RootNode Int (a, b', c)
-> ParagraphOptions
-> Paragraph (a, b', c)
forall d.
Array -> Int -> RootNode Int d -> ParagraphOptions -> Paragraph d
Paragraph Array
a Int
b (Box Int (a, b', c) -> RootNode Int (a, b', c)
forall t d. Box t d -> RootNode t d
RootBox (Box Int (a, b', c) -> RootNode Int (a, b', c))
-> Box Int (a, b', c) -> RootNode Int (a, b', c)
forall a b. (a -> b) -> a -> b
$ Box Int (a, b, c) -> Box Int (a, b', c)
forall t a c. Box t (a, b, c) -> Box t (a, b', c)
inner Box Int (a, b, c)
c) ParagraphOptions
d
  where
    inner :: Box t (a, b, c) -> Box t (a, b', c)
inner (Box childs :: [InnerNode t (a, b, c)]
childs opts :: TextOptions
opts) = ([InnerNode t (a, b', c)] -> TextOptions -> Box t (a, b', c))
-> TextOptions -> [InnerNode t (a, b', c)] -> Box t (a, b', c)
forall a b c. (a -> b -> c) -> b -> a -> c
flip [InnerNode t (a, b', c)] -> TextOptions -> Box t (a, b', c)
forall t d. [InnerNode t d] -> TextOptions -> Box t d
Box TextOptions
opts ([InnerNode t (a, b', c)] -> Box t (a, b', c))
-> [InnerNode t (a, b', c)] -> Box t (a, b', c)
forall a b. (a -> b) -> a -> b
$ (InnerNode t (a, b, c) -> InnerNode t (a, b', c))
-> [InnerNode t (a, b, c)] -> [InnerNode t (a, b', c)]
forall a b. (a -> b) -> [a] -> [b]
map InnerNode t (a, b, c) -> InnerNode t (a, b', c)
inner' [InnerNode t (a, b, c)]
childs
    inner' :: InnerNode t (a, b, c) -> InnerNode t (a, b', c)
inner' (InlineBox (e :: a
e, f :: b
f, g :: c
g) child :: Box t (a, b, c)
child opts :: BoxOptions
opts) =
        (a, b', c)
-> Box t (a, b', c) -> BoxOptions -> InnerNode t (a, b', c)
forall t d. d -> Box t d -> BoxOptions -> InnerNode t d
InlineBox (a
e, b -> b'
cb b
f, c
g) (Box t (a, b, c) -> Box t (a, b', c)
inner Box t (a, b, c)
child) BoxOptions
opts
    inner' (TextSequence (e :: a
e, f :: b
f, g :: c
g) leaf :: t
leaf) = (a, b', c) -> t -> InnerNode t (a, b', c)
forall t d. d -> t -> InnerNode t d
TextSequence (a
e, b -> b'
cb b
f, c
g) t
leaf

-- | Apply an operation to the 2nd field of a laid-out paragraph's userdata,
-- for it's entire subtree.
layoutMap :: (b -> b') -> ParagraphLayout (a, b, c) -> ParagraphLayout (a, b', c)
layoutMap :: (b -> b')
-> ParagraphLayout (a, b, c) -> ParagraphLayout (a, b', c)
layoutMap cb :: b -> b'
cb (ParagraphLayout a :: Rect Int32
a b :: [Fragment (a, b, c)]
b) = Rect Int32 -> [Fragment (a, b', c)] -> ParagraphLayout (a, b', c)
forall d. Rect Int32 -> [Fragment d] -> ParagraphLayout d
ParagraphLayout Rect Int32
a ([Fragment (a, b', c)] -> ParagraphLayout (a, b', c))
-> [Fragment (a, b', c)] -> ParagraphLayout (a, b', c)
forall a b. (a -> b) -> a -> b
$ (Fragment (a, b, c) -> Fragment (a, b', c))
-> [Fragment (a, b, c)] -> [Fragment (a, b', c)]
forall a b. (a -> b) -> [a] -> [b]
map Fragment (a, b, c) -> Fragment (a, b', c)
forall a c. Fragment (a, b, c) -> Fragment (a, b', c)
inner [Fragment (a, b, c)]
b
  where
    inner :: Fragment (a, b, c) -> Fragment (a, b', c)
inner self :: Fragment (a, b, c)
self@Fragment { fragmentUserData :: forall d. Fragment d -> d
fragmentUserData = (a :: a
a, b :: b
b, c :: c
c) } = Fragment (a, b, c)
self {
        fragmentUserData :: (a, b', c)
fragmentUserData = (a
a, b -> b'
cb b
b, c
c),
        fragmentAncestorBoxes :: [AncestorBox (a, b', c)]
fragmentAncestorBoxes = (AncestorBox (a, b, c) -> AncestorBox (a, b', c))
-> [AncestorBox (a, b, c)] -> [AncestorBox (a, b', c)]
forall a b. (a -> b) -> [a] -> [b]
map AncestorBox (a, b, c) -> AncestorBox (a, b', c)
forall a c. AncestorBox (a, b, c) -> AncestorBox (a, b', c)
inner' ([AncestorBox (a, b, c)] -> [AncestorBox (a, b', c)])
-> [AncestorBox (a, b, c)] -> [AncestorBox (a, b', c)]
forall a b. (a -> b) -> a -> b
$ Fragment (a, b, c) -> [AncestorBox (a, b, c)]
forall d. Fragment d -> [AncestorBox d]
fragmentAncestorBoxes Fragment (a, b, c)
self
      }
    inner' :: AncestorBox (a, b, c) -> AncestorBox (a, b', c)
inner' self :: AncestorBox (a, b, c)
self@AncestorBox { boxUserData :: forall d. AncestorBox d -> d
boxUserData = (a :: a
a, b :: b
b, c :: c
c) } = AncestorBox (a, b, c)
self {
        boxUserData :: (a, b', c)
boxUserData = (a
a, b -> b'
cb b
b, c
c)
      }

-- | Apply an operation to the 2nd field of the tree extracted from a laid-out
-- paragraph, for all nodes.
treeMap :: (b -> b') -> FragmentTree (a, b, c) -> FragmentTree (a, b', c)
treeMap :: (b -> b') -> FragmentTree (a, b, c) -> FragmentTree (a, b', c)
treeMap cb :: b -> b'
cb (Branch self :: AncestorBox (a, b, c)
self@AncestorBox { boxUserData :: forall d. AncestorBox d -> d
boxUserData = (a :: a
a, b :: b
b, c :: c
c) } childs :: [FragmentTree (a, b, c)]
childs) =
    AncestorBox (a, b', c)
-> [FragmentTree (a, b', c)] -> FragmentTree (a, b', c)
forall x. AncestorBox x -> [FragmentTree x] -> FragmentTree x
Branch AncestorBox (a, b, c)
self { boxUserData :: (a, b', c)
boxUserData = (a
a, b -> b'
cb b
b, c
c) } ([FragmentTree (a, b', c)] -> FragmentTree (a, b', c))
-> [FragmentTree (a, b', c)] -> FragmentTree (a, b', c)
forall a b. (a -> b) -> a -> b
$ (FragmentTree (a, b, c) -> FragmentTree (a, b', c))
-> [FragmentTree (a, b, c)] -> [FragmentTree (a, b', c)]
forall a b. (a -> b) -> [a] -> [b]
map ((b -> b') -> FragmentTree (a, b, c) -> FragmentTree (a, b', c)
forall b b' a c.
(b -> b') -> FragmentTree (a, b, c) -> FragmentTree (a, b', c)
treeMap b -> b'
cb) [FragmentTree (a, b, c)]
childs
treeMap cb :: b -> b'
cb (Leaf self :: Fragment (a, b, c)
self@Fragment { fragmentUserData :: forall d. Fragment d -> d
fragmentUserData = (a :: a
a, b :: b
b, c :: c
c) }) =
    Fragment (a, b', c) -> FragmentTree (a, b', c)
forall x. Fragment x -> FragmentTree x
Leaf Fragment (a, b, c)
self { fragmentUserData :: (a, b', c)
fragmentUserData = (a
a, b -> b'
cb b
b, c
c), fragmentAncestorBoxes :: [AncestorBox (a, b', c)]
fragmentAncestorBoxes = [] }

-- | Retrieve the rect for a fragment & convert to CatTrap types.
fragmentSize :: (CastDouble x, CastDouble y) =>
        FragmentTree (a, PaddedBox x y, c) -> Size x y
fragmentSize :: FragmentTree (a, PaddedBox x y, c) -> Size x y
fragmentSize self :: FragmentTree (a, PaddedBox x y, c)
self = y -> x -> Size x y
forall m n. n -> m -> Size m n
Size (Int32 -> y
forall a. CastDouble a => Int32 -> a
c (Int32 -> y) -> Int32 -> y
forall a b. (a -> b) -> a -> b
$ Rect Int32 -> Int32
forall a. Num a => Rect a -> a
width Rect Int32
r) (Int32 -> x
forall a. CastDouble a => Int32 -> a
c (Int32 -> x) -> Int32 -> x
forall a b. (a -> b) -> a -> b
$ Rect Int32 -> Int32
forall a. Num a => Rect a -> a
height Rect Int32
r)
    where r :: Rect Int32
r = FragmentTree (a, PaddedBox x y, c) -> Rect Int32
forall m n a c.
(CastDouble m, CastDouble n) =>
FragmentTree (a, PaddedBox m n, c) -> Rect Int32
treeRect FragmentTree (a, PaddedBox x y, c)
self
-- | Compute the unioned rect for a subtree.
treeRect :: (CastDouble m, CastDouble n) =>
        FragmentTree (a, PaddedBox m n, c) -> Rect Int32
treeRect :: FragmentTree (a, PaddedBox m n, c) -> Rect Int32
treeRect (Branch AncestorBox { boxUserData :: forall d. AncestorBox d -> d
boxUserData = (_, box' :: PaddedBox m n
box', _)} childs :: [FragmentTree (a, PaddedBox m n, c)]
childs) =
        [Rect Int32] -> Rect Int32
forall a. (Num a, Ord a) => [Rect a] -> Rect a
unions ([Rect Int32] -> Rect Int32) -> [Rect Int32] -> Rect Int32
forall a b. (a -> b) -> a -> b
$ (FragmentTree (a, PaddedBox m n, c) -> Rect Int32)
-> [FragmentTree (a, PaddedBox m n, c)] -> [Rect Int32]
forall a b. (a -> b) -> [a] -> [b]
map FragmentTree (a, PaddedBox m n, c) -> Rect Int32
forall m n a c.
(CastDouble m, CastDouble n) =>
FragmentTree (a, PaddedBox m n, c) -> Rect Int32
treeRect [FragmentTree (a, PaddedBox m n, c)]
childs
    where
        box :: PaddedBox Int32 Int32
        box :: PaddedBox Int32 Int32
box = (n -> Int32) -> PaddedBox Int32 n -> PaddedBox Int32 Int32
forall n nn m. (n -> nn) -> PaddedBox m n -> PaddedBox m nn
mapX' n -> Int32
forall x. CastDouble x => x -> Int32
unscale (PaddedBox Int32 n -> PaddedBox Int32 Int32)
-> PaddedBox Int32 n -> PaddedBox Int32 Int32
forall a b. (a -> b) -> a -> b
$ (m -> Int32) -> PaddedBox m n -> PaddedBox Int32 n
forall m mm n. (m -> mm) -> PaddedBox m n -> PaddedBox mm n
mapY' m -> Int32
forall x. CastDouble x => x -> Int32
unscale PaddedBox m n
box'
treeRect (Leaf self :: Fragment (a, PaddedBox m n, c)
self) = Fragment (a, PaddedBox m n, c) -> Rect Int32
forall d. Fragment d -> Rect Int32
fragmentRect Fragment (a, PaddedBox m n, c)
self

-- | Compute the paddedbox for a subtree.
treeBox :: (CastDouble m, CastDouble n) =>
    FragmentTree (a, PaddedBox m n, c) -> PaddedBox m n
treeBox :: FragmentTree (a, PaddedBox m n, c) -> PaddedBox m n
treeBox self :: FragmentTree (a, PaddedBox m n, c)
self@(Branch AncestorBox { boxUserData :: forall d. AncestorBox d -> d
boxUserData = (_, box' :: PaddedBox m n
box', _)} _) = PaddedBox m n
box' {
    min :: Size m n
Box.min = Size m n
size', max :: Size m n
Box.max = Size m n
size', size :: Size m n
Box.size = Size m n
size', nat :: Size Double Double
Box.nat = Size Double Double
size
  } where
    size' :: Size m n
size' = (Double -> n) -> Size m Double -> Size m n
forall n nn m. (n -> nn) -> Size m n -> Size m nn
mapSizeX Double -> n
forall a. CastDouble a => Double -> a
fromDouble (Size m Double -> Size m n) -> Size m Double -> Size m n
forall a b. (a -> b) -> a -> b
$ (Double -> m) -> Size Double Double -> Size m Double
forall m mm n. (m -> mm) -> Size m n -> Size mm n
mapSizeY Double -> m
forall a. CastDouble a => Double -> a
fromDouble Size Double Double
size
    size :: Size Double Double
size = (Double -> Double) -> Size Double Double -> Size Double Double
forall n nn m. (n -> nn) -> Size m n -> Size m nn
mapSizeX (Double -> Double -> Double
forall a. Num a => a -> a -> a
subtract (Double -> Double -> Double) -> Double -> Double -> Double
forall a b. (a -> b) -> a -> b
$ PaddedBox Double Double -> Double
forall n m. Num n => PaddedBox m n -> n
hSpace PaddedBox Double Double
box) (Size Double Double -> Size Double Double)
-> Size Double Double -> Size Double Double
forall a b. (a -> b) -> a -> b
$ (Double -> Double) -> Size Double Double -> Size Double Double
forall m mm n. (m -> mm) -> Size m n -> Size mm n
mapSizeY (Double -> Double -> Double
forall a. Num a => a -> a -> a
subtract (Double -> Double -> Double) -> Double -> Double -> Double
forall a b. (a -> b) -> a -> b
$ PaddedBox Double Double -> Double
forall m n. Num m => PaddedBox m n -> m
vSpace PaddedBox Double Double
box)(Size Double Double -> Size Double Double)
-> Size Double Double -> Size Double Double
forall a b. (a -> b) -> a -> b
$
         (n -> Double) -> Size Double n -> Size Double Double
forall n nn m. (n -> nn) -> Size m n -> Size m nn
mapSizeX n -> Double
forall a. CastDouble a => a -> Double
toDouble (Size Double n -> Size Double Double)
-> Size Double n -> Size Double Double
forall a b. (a -> b) -> a -> b
$ (m -> Double) -> Size m n -> Size Double n
forall m mm n. (m -> mm) -> Size m n -> Size mm n
mapSizeY m -> Double
forall a. CastDouble a => a -> Double
toDouble (Size m n -> Size Double n) -> Size m n -> Size Double n
forall a b. (a -> b) -> a -> b
$ FragmentTree (a, PaddedBox m n, c) -> Size m n
forall x y a c.
(CastDouble x, CastDouble y) =>
FragmentTree (a, PaddedBox x y, c) -> Size x y
fragmentSize FragmentTree (a, PaddedBox m n, c)
self
    box :: PaddedBox Double Double
box = (n -> Double) -> PaddedBox Double n -> PaddedBox Double Double
forall n nn m. (n -> nn) -> PaddedBox m n -> PaddedBox m nn
mapX' n -> Double
forall a. CastDouble a => a -> Double
toDouble (PaddedBox Double n -> PaddedBox Double Double)
-> PaddedBox Double n -> PaddedBox Double Double
forall a b. (a -> b) -> a -> b
$ (m -> Double) -> PaddedBox m n -> PaddedBox Double n
forall m mm n. (m -> mm) -> PaddedBox m n -> PaddedBox mm n
mapY' m -> Double
forall a. CastDouble a => a -> Double
toDouble PaddedBox m n
box'
treeBox self :: FragmentTree (a, PaddedBox m n, c)
self@(Leaf Fragment { fragmentUserData :: forall d. Fragment d -> d
fragmentUserData = (_, box' :: PaddedBox m n
box', _)}) = PaddedBox m n
box' {
    min :: Size m n
Box.min = Size m n
size', max :: Size m n
Box.max = Size m n
size', size :: Size m n
Box.size = Size m n
size', nat :: Size Double Double
Box.nat = Size Double Double
size
  } where
    size' :: Size m n
size' = (Double -> n) -> Size m Double -> Size m n
forall n nn m. (n -> nn) -> Size m n -> Size m nn
mapSizeX Double -> n
forall a. CastDouble a => Double -> a
fromDouble (Size m Double -> Size m n) -> Size m Double -> Size m n
forall a b. (a -> b) -> a -> b
$ (Double -> m) -> Size Double Double -> Size m Double
forall m mm n. (m -> mm) -> Size m n -> Size mm n
mapSizeY Double -> m
forall a. CastDouble a => Double -> a
fromDouble Size Double Double
size
    size :: Size Double Double
size = (Double -> Double) -> Size Double Double -> Size Double Double
forall n nn m. (n -> nn) -> Size m n -> Size m nn
mapSizeX (Double -> Double -> Double
forall a. Num a => a -> a -> a
subtract (Double -> Double -> Double) -> Double -> Double -> Double
forall a b. (a -> b) -> a -> b
$ PaddedBox Double Double -> Double
forall n m. Num n => PaddedBox m n -> n
hSpace PaddedBox Double Double
box) (Size Double Double -> Size Double Double)
-> Size Double Double -> Size Double Double
forall a b. (a -> b) -> a -> b
$ (Double -> Double) -> Size Double Double -> Size Double Double
forall m mm n. (m -> mm) -> Size m n -> Size mm n
mapSizeY (Double -> Double -> Double
forall a. Num a => a -> a -> a
subtract (Double -> Double -> Double) -> Double -> Double -> Double
forall a b. (a -> b) -> a -> b
$ PaddedBox Double Double -> Double
forall m n. Num m => PaddedBox m n -> m
vSpace PaddedBox Double Double
box) (Size Double Double -> Size Double Double)
-> Size Double Double -> Size Double Double
forall a b. (a -> b) -> a -> b
$
        (n -> Double) -> Size Double n -> Size Double Double
forall n nn m. (n -> nn) -> Size m n -> Size m nn
mapSizeX n -> Double
forall a. CastDouble a => a -> Double
toDouble (Size Double n -> Size Double Double)
-> Size Double n -> Size Double Double
forall a b. (a -> b) -> a -> b
$ (m -> Double) -> Size m n -> Size Double n
forall m mm n. (m -> mm) -> Size m n -> Size mm n
mapSizeY m -> Double
forall a. CastDouble a => a -> Double
toDouble (Size m n -> Size Double n) -> Size m n -> Size Double n
forall a b. (a -> b) -> a -> b
$ FragmentTree (a, PaddedBox m n, c) -> Size m n
forall x y a c.
(CastDouble x, CastDouble y) =>
FragmentTree (a, PaddedBox x y, c) -> Size x y
fragmentSize FragmentTree (a, PaddedBox m n, c)
self
    box :: PaddedBox Double Double
box = (n -> Double) -> PaddedBox Double n -> PaddedBox Double Double
forall n nn m. (n -> nn) -> PaddedBox m n -> PaddedBox m nn
mapX' n -> Double
forall a. CastDouble a => a -> Double
toDouble (PaddedBox Double n -> PaddedBox Double Double)
-> PaddedBox Double n -> PaddedBox Double Double
forall a b. (a -> b) -> a -> b
$ (m -> Double) -> PaddedBox m n -> PaddedBox Double n
forall m mm n. (m -> mm) -> PaddedBox m n -> PaddedBox mm n
mapY' m -> Double
forall a. CastDouble a => a -> Double
toDouble PaddedBox m n
box'

-- | Variant of `fragmentSize` asserting to the typesystem that both fields
-- of the resulting `Size` are of the same type.
fragmentSize' :: CastDouble x => FragmentTree (a, PaddedBox x x, c) -> Size x x
fragmentSize' :: FragmentTree (a, PaddedBox x x, c) -> Size x x
fragmentSize' = FragmentTree (a, PaddedBox x x, c) -> Size x x
forall x y a c.
(CastDouble x, CastDouble y) =>
FragmentTree (a, PaddedBox x y, c) -> Size x y
fragmentSize -- Work around for typesystem.
-- | Retrieve the position of a fragment.
fragmentPos :: (Double, Double) -> Fragment a -> (Double, Double)
fragmentPos :: (Double, Double) -> Fragment a -> (Double, Double)
fragmentPos (x :: Double
x, y :: Double
y) self :: Fragment a
self = (Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Int32 -> Double
hbScale (Rect Int32 -> Int32
forall a. (Num a, Ord a) => Rect a -> a
x_min Rect Int32
r), Double
y Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Int32 -> Double
hbScale (Rect Int32 -> Int32
forall a. (Num a, Ord a) => Rect a -> a
y_min Rect Int32
r))
    where r :: Rect Int32
r = Fragment a -> Rect Int32
forall d. Fragment d -> Rect Int32
fragmentRect Fragment a
self

reconstructTree :: Eq x => ParagraphLayout x -> [FragmentTree x]
reconstructTree :: ParagraphLayout x -> [FragmentTree x]
reconstructTree ParagraphLayout { paragraphFragments :: forall d. ParagraphLayout d -> [Fragment d]
paragraphFragments = [Fragment x]
frags } =
    [Fragment x] -> [FragmentTree x]
forall x. Eq x => [Fragment x] -> [FragmentTree x]
reconstructTree' [Fragment x
frag {
            fragmentAncestorBoxes :: [AncestorBox x]
fragmentAncestorBoxes = [AncestorBox x] -> [AncestorBox x]
forall a. [a] -> [a]
reverse ([AncestorBox x] -> [AncestorBox x])
-> [AncestorBox x] -> [AncestorBox x]
forall a b. (a -> b) -> a -> b
$ Fragment x -> [AncestorBox x]
forall d. Fragment d -> [AncestorBox d]
fragmentAncestorBoxes Fragment x
frag
        } | Fragment x
frag <- [Fragment x]
frags]
reconstructTree' :: Eq x => [Fragment x] -> [FragmentTree x]
reconstructTree' :: [Fragment x] -> [FragmentTree x]
reconstructTree' (self :: Fragment x
self@Fragment { fragmentAncestorBoxes :: forall d. Fragment d -> [AncestorBox d]
fragmentAncestorBoxes = [] }:frags :: [Fragment x]
frags) =
    Fragment x -> FragmentTree x
forall x. Fragment x -> FragmentTree x
Leaf Fragment x
selfFragmentTree x -> [FragmentTree x] -> [FragmentTree x]
forall a. a -> [a] -> [a]
:[Fragment x] -> [FragmentTree x]
forall x. Eq x => [Fragment x] -> [FragmentTree x]
reconstructTree' [Fragment x]
frags
reconstructTree' frags :: [Fragment x]
frags@(Fragment {
        fragmentAncestorBoxes :: forall d. Fragment d -> [AncestorBox d]
fragmentAncestorBoxes = branch :: AncestorBox x
branch:_, fragmentLine :: forall d. Fragment d -> Int
fragmentLine = Int
line
  }:_) =
    AncestorBox x -> [FragmentTree x] -> FragmentTree x
forall x. AncestorBox x -> [FragmentTree x] -> FragmentTree x
Branch AncestorBox x
branch ([Fragment x] -> [FragmentTree x]
forall x. Eq x => [Fragment x] -> [FragmentTree x]
reconstructTree' [ Fragment x
child { fragmentAncestorBoxes :: [AncestorBox x]
fragmentAncestorBoxes = [AncestorBox x]
ancestors }
            | child :: Fragment x
child@Fragment { fragmentAncestorBoxes :: forall d. Fragment d -> [AncestorBox d]
fragmentAncestorBoxes = _:ancestors :: [AncestorBox x]
ancestors } <- [Fragment x]
childs])
        FragmentTree x -> [FragmentTree x] -> [FragmentTree x]
forall a. a -> [a] -> [a]
:[Fragment x] -> [FragmentTree x]
forall x. Eq x => [Fragment x] -> [FragmentTree x]
reconstructTree' [Fragment x]
sibs
  where
    (childs :: [Fragment x]
childs, sibs :: [Fragment x]
sibs) = (Fragment x -> Bool)
-> [Fragment x] -> ([Fragment x], [Fragment x])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span Fragment x -> Bool
sameBranch [Fragment x]
frags
    -- Cluster ancestor branches, breaking them per-line.
    sameBranch :: Fragment x -> Bool
sameBranch Fragment {fragmentAncestorBoxes :: forall d. Fragment d -> [AncestorBox d]
fragmentAncestorBoxes=branch' :: AncestorBox x
branch':_, fragmentLine :: forall d. Fragment d -> Int
fragmentLine=Int
line'} =
        AncestorBox x
branch AncestorBox x -> AncestorBox x -> Bool
forall a. Eq a => a -> a -> Bool
== AncestorBox x
branch' Bool -> Bool -> Bool
&& Int
line Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
line'
    -- Leaves are always in their own branch.
    sameBranch Fragment { fragmentAncestorBoxes :: forall d. Fragment d -> [AncestorBox d]
fragmentAncestorBoxes = [] } = Bool
False
reconstructTree' [] = []

positionTree :: (CastDouble m, CastDouble n) => (Double, Double) ->
        FragmentTree (a, PaddedBox m n, c) ->
        FragmentTree (a, PaddedBox m n, ((Double, Double), c))
positionTree :: (Double, Double)
-> FragmentTree (a, PaddedBox m n, c)
-> FragmentTree (a, PaddedBox m n, ((Double, Double), c))
positionTree (x :: Double
x, y :: Double
y) self :: FragmentTree (a, PaddedBox m n, c)
self@(Branch (AncestorBox (a :: a
a, b :: PaddedBox m n
b, c :: c
c) d :: BoxEdge
d e :: BoxEdge
e f :: BoxEdge
f g :: BoxEdge
g) childs :: [FragmentTree (a, PaddedBox m n, c)]
childs) =
    AncestorBox (a, PaddedBox m n, ((Double, Double), c))
-> [FragmentTree (a, PaddedBox m n, ((Double, Double), c))]
-> FragmentTree (a, PaddedBox m n, ((Double, Double), c))
forall x. AncestorBox x -> [FragmentTree x] -> FragmentTree x
Branch ((a, PaddedBox m n, ((Double, Double), c))
-> BoxEdge
-> BoxEdge
-> BoxEdge
-> BoxEdge
-> AncestorBox (a, PaddedBox m n, ((Double, Double), c))
forall d.
d -> BoxEdge -> BoxEdge -> BoxEdge -> BoxEdge -> AncestorBox d
AncestorBox (a
a, PaddedBox m n
b, ((Double, Double)
pos, c
c)) BoxEdge
d BoxEdge
e BoxEdge
f BoxEdge
g) ([FragmentTree (a, PaddedBox m n, ((Double, Double), c))]
 -> FragmentTree (a, PaddedBox m n, ((Double, Double), c)))
-> [FragmentTree (a, PaddedBox m n, ((Double, Double), c))]
-> FragmentTree (a, PaddedBox m n, ((Double, Double), c))
forall a b. (a -> b) -> a -> b
$
        (FragmentTree (a, PaddedBox m n, c)
 -> FragmentTree (a, PaddedBox m n, ((Double, Double), c)))
-> [FragmentTree (a, PaddedBox m n, c)]
-> [FragmentTree (a, PaddedBox m n, ((Double, Double), c))]
forall a b. (a -> b) -> [a] -> [b]
map ((Double, Double)
-> FragmentTree (a, PaddedBox m n, c)
-> FragmentTree (a, PaddedBox m n, ((Double, Double), c))
forall m n a c.
(CastDouble m, CastDouble n) =>
(Double, Double)
-> FragmentTree (a, PaddedBox m n, c)
-> FragmentTree (a, PaddedBox m n, ((Double, Double), c))
positionTree (Double, Double)
pos) [FragmentTree (a, PaddedBox m n, c)]
childs
  where
    pos :: (Double, Double)
pos = (Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Int32 -> Double
hbScale (Rect Int32 -> Int32
forall a. (Num a, Ord a) => Rect a -> a
x_min Rect Int32
rect), Double
y Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Int32 -> Double
hbScale (Rect Int32 -> Int32
forall a. (Num a, Ord a) => Rect a -> a
y_min Rect Int32
rect))
    rect :: Rect Int32
rect = FragmentTree (a, PaddedBox m n, c) -> Rect Int32
forall m n a c.
(CastDouble m, CastDouble n) =>
FragmentTree (a, PaddedBox m n, c) -> Rect Int32
treeRect FragmentTree (a, PaddedBox m n, c)
self
positionTree (x :: Double
x, y :: Double
y) self :: FragmentTree (a, PaddedBox m n, c)
self@(Leaf (Fragment (a :: a
a, b :: PaddedBox m n
b, c :: c
c) d :: Int
d _ f :: Rect Int32
f g :: (Int32, Int32)
g h :: [(GlyphInfo, GlyphPos)]
h)) =
    Fragment (a, PaddedBox m n, ((Double, Double), c))
-> FragmentTree (a, PaddedBox m n, ((Double, Double), c))
forall x. Fragment x -> FragmentTree x
Leaf ((a, PaddedBox m n, ((Double, Double), c))
-> Int
-> [AncestorBox (a, PaddedBox m n, ((Double, Double), c))]
-> Rect Int32
-> (Int32, Int32)
-> [(GlyphInfo, GlyphPos)]
-> Fragment (a, PaddedBox m n, ((Double, Double), c))
forall d.
d
-> Int
-> [AncestorBox d]
-> Rect Int32
-> (Int32, Int32)
-> [(GlyphInfo, GlyphPos)]
-> Fragment d
Fragment (a
a, PaddedBox m n
b, ((Double, Double)
pos, c
c)) Int
d [] Rect Int32
f (Int32, Int32)
g [(GlyphInfo, GlyphPos)]
h)
  where
    pos :: (Double, Double)
pos = (Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Int32 -> Double
hbScale (Rect Int32 -> Int32
forall a. (Num a, Ord a) => Rect a -> a
x_min Rect Int32
rect), Double
y Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Int32 -> Double
hbScale (Rect Int32 -> Int32
forall a. (Num a, Ord a) => Rect a -> a
y_min Rect Int32
rect))
    rect :: Rect Int32
rect = FragmentTree (a, PaddedBox m n, c) -> Rect Int32
forall m n a c.
(CastDouble m, CastDouble n) =>
FragmentTree (a, PaddedBox m n, c) -> Rect Int32
treeRect FragmentTree (a, PaddedBox m n, c)
self
treeInner :: FragmentTree (a, b, c) -> c
treeInner :: FragmentTree (a, b, c) -> c
treeInner (Branch AncestorBox { boxUserData :: forall d. AncestorBox d -> d
boxUserData = (_, _, ret :: c
ret) } _) = c
ret
treeInner (Leaf Fragment { fragmentUserData :: forall d. Fragment d -> d
fragmentUserData = (_, _, ret :: c
ret) }) = c
ret

------
--- Taken from Balkón
------
-- | Calculate the smallest rectangle that completely contains all the given
-- rectangles.
unions :: [Rect a] -> Rect a
unions [] = String -> Rect a -> Rect a
forall a. String -> a -> a
trace "No rects to union!" (Rect a -> Rect a) -> Rect a -> Rect a
forall a b. (a -> b) -> a -> b
$ a -> a -> a -> a -> Rect a
forall a. a -> a -> a -> a -> Rect a
Rect 0 0 0 0
unions rects :: [Rect a]
rects = (Rect a -> Rect a -> Rect a) -> [Rect a] -> Rect a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 Rect a -> Rect a -> Rect a
forall a. (Num a, Ord a) => Rect a -> Rect a -> Rect a
union [Rect a]
rects

-- | Calculate the smallest rectangle that completely contains the given two
-- rectangles.
--
-- The origin of the resulting rectangle will be the corner with the lowest
-- X coordinate and the highest Y coordinate, regardless of the origin of the
-- input rectangles.
union :: (Num a, Ord a) => Rect a -> Rect a -> Rect a
union :: Rect a -> Rect a -> Rect a
union a :: Rect a
a b :: Rect a
b = a -> a -> a -> a -> Rect a
forall a. a -> a -> a -> a -> Rect a
Rect a
x_low a
y_high a
dx (-a
dy) where
    x_low :: a
x_low = Rect a -> a
forall a. (Num a, Ord a) => Rect a -> a
x_min Rect a
a a -> a -> a
forall a. Ord a => a -> a -> a
`min` Rect a -> a
forall a. (Num a, Ord a) => Rect a -> a
x_min Rect a
b
    y_low :: a
y_low = Rect a -> a
forall a. (Num a, Ord a) => Rect a -> a
y_min Rect a
a a -> a -> a
forall a. Ord a => a -> a -> a
`min` Rect a -> a
forall a. (Num a, Ord a) => Rect a -> a
y_min Rect a
b
    x_high :: a
x_high = Rect a -> a
forall a. (Num a, Ord a) => Rect a -> a
x_max Rect a
a a -> a -> a
forall a. Ord a => a -> a -> a
`max` Rect a -> a
forall a. (Num a, Ord a) => Rect a -> a
x_max Rect a
b
    y_high :: a
y_high = Rect a -> a
forall a. (Num a, Ord a) => Rect a -> a
y_max Rect a
a a -> a -> a
forall a. Ord a => a -> a -> a
`max` Rect a -> a
forall a. (Num a, Ord a) => Rect a -> a
y_max Rect a
b
    dx :: a
dx = a
x_high a -> a -> a
forall a. Num a => a -> a -> a
- a
x_low
    dy :: a
dy = a
y_high a -> a -> a
forall a. Num a => a -> a -> a
- a
y_low