@@ -34,6 +34,8 @@ module Graphics.Vty.Image ( DisplayText
34 , crop_top
34 , crop_top
37 , translate
39 , translate
38 -- | The possible display attributes used in constructing an `Image`.
40 -- | The possible display attributes used in constructing an `Image`.
39 , module Graphics.Vty.Attributes
41 , module Graphics.Vty.Attributes
@@ -56,7 +58,7 @@ import Data.Word
56infixr 5 <|>
58infixr 5 <|>
57infixr 4 <->
59infixr 4 <->
59−-- | Currently append in the Monoid instance is equivalent to <->.
61+-- | Append in the Monoid instance is equivalent to <->.
60instance Monoid Image where
62instance Monoid Image where
61 mempty = EmptyImage
63 mempty = EmptyImage
62 mappend = (<->)
64 mappend = (<->)
@@ -229,6 +231,7 @@ empty_image :: Image
229empty_image = EmptyImage
231empty_image = EmptyImage
231-- | pad the given image. This adds background character fills to the left, top, right, bottom.
233-- | pad the given image. This adds background character fills to the left, top, right, bottom.
234+-- The pad values are how many display columns or rows to add.
232pad :: Int -> Int -> Int -> Int -> Image -> Image
235pad :: Int -> Int -> Int -> Int -> Image -> Image
233pad 0 0 0 0 i = i
236pad 0 0 0 0 i = i
234pad in_l in_t in_r in_b in_image
237pad in_l in_t in_r in_b in_image
@@ -273,12 +276,15 @@ crop_bottom h in_i
273 | otherwise = go in_i
276 | otherwise = go in_i
275 go EmptyImage = EmptyImage
278 go EmptyImage = EmptyImage
276− go (CropBottom {cropped_image, output_width, output_height}) =
279+ go i@(CropBottom {cropped_image, output_width, output_height})
280+ | output_height <= h = i
277− CropBottom cropped_image output_width (min h output_height)
281+ | otherwise = CropBottom cropped_image output_width (min h output_height)
279 | h >= image_height i = i
283 | h >= image_height i = i
280 | otherwise = CropBottom i (image_width i) h
284 | otherwise = CropBottom i (image_width i) h
286+-- | ensure the image is no wider than the given width. If the image is wider then crop the right
282crop_right :: Int -> Image -> Image
288crop_right :: Int -> Image -> Image
283crop_right 0 _ = EmptyImage
289crop_right 0 _ = EmptyImage
284crop_right w in_i
290crop_right w in_i
@@ -286,20 +292,67 @@ crop_right w in_i
286 | otherwise = go in_i
292 | otherwise = go in_i
288 go EmptyImage = EmptyImage
294 go EmptyImage = EmptyImage
289− go (CropRight {cropped_image, output_width, output_height}) =
295+ go i@(CropRight {cropped_image, output_width, output_height})
296+ | output_width <= w = i
290− CropRight cropped_image (min w output_width) output_height
297+ | otherwise = CropRight cropped_image (min w output_width) output_height
292 | w >= image_width i = i
299 | w >= image_width i = i
293 | otherwise = CropRight i w (image_height i)
300 | otherwise = CropRight i w (image_height i)
302+-- | ensure the image is no wider than the given width. If the image is wider then crop the left
295crop_left :: Int -> Image -> Image
304crop_left :: Int -> Image -> Image
296−crop_left _ _ = error "not implemented"
305+crop_left 0 _ = EmptyImage
307+ | w < 0 = error "cannot crop the width to less than zero"
308+ | otherwise = go in_i
310+ go EmptyImage = EmptyImage
311+ go i@(CropLeft {cropped_image, left_skip, output_width, output_height})
312+ | output_width <= w = i
314+ let left_skip' = left_skip + w - output_width
315+ in CropLeft cropped_image left_skip' w output_height
317+ | image_width i <= w = i
318+ | otherwise = CropLeft i (image_width i - w) w (image_height i)
320+-- | crop the display height. If the image is less than or equal in height then this operation has
321+-- no effect. Otherwise the image is cropped from the top.
298crop_top :: Int -> Image -> Image
322crop_top :: Int -> Image -> Image
299−crop_top _ _ = error "not implemented"
323+crop_top 0 _ = EmptyImage
325+ | h < 0 = error "cannot crop the height to less than zero"
326+ | otherwise = go in_i
328+ go EmptyImage = EmptyImage
329+ go i@(CropTop {cropped_image, top_skip, output_width, output_height})
330+ | output_height <= h = i
332+ let top_skip' = top_skip + h - output_height
333+ in CropTop cropped_image top_skip' output_width h
335+ | image_height i <= h = i
336+ | otherwise = CropTop i (image_height i - h) (image_width i) h
301-- | Generic resize. Pads and crops as required to assure the given display width and height.
338-- | Generic resize. Pads and crops as required to assure the given display width and height.
302−-- This is biased to pad the right and bottom.
339+-- This is biased to pad/crop the right and bottom.
303resize :: Int -> Int -> Image -> Image
340resize :: Int -> Int -> Image -> Image
304−resize _w _h _i = error "not implemented yet"
341+resize w h i = resize_height h (resize_width w i)
343+-- | Resize the width. Pads and crops as required to assure the given display width.
344+-- This is biased to pad/crop the right.
345+resize_width :: Int -> Image -> Image
346+resize_width w i = case w `compare` image_width i of
347+ LT -> crop_right w i
349+ GT -> i <|> BGFill (w - image_width i) (image_height i)
351+-- | Resize the height. Pads and crops as required to assure the given display height.
352+-- This is biased to pad/crop the bottom.
353+resize_height :: Int -> Image -> Image
354+resize_height h i = case h `compare` image_height i of
355+ LT -> crop_bottom h i
357+ GT -> i <-> BGFill (image_width i) (h - image_height i)