@@ -5,7 +5,17 @@
55{-# LANGUAGE NamedFieldPuns #-}
66{-# LANGUAGE GADTs #-}
77{-# LANGUAGE ScopedTypeVariables #-}
8−-- The ops to define the content for an output region.
8+{- | A picture is translated into a sequences of state changes and character spans.
9+ - State changes are currently limited to new attribute values. The attribute is applied to all
10+ - following spans. Including spans of the next row. The nth element of the sequence represents the
11+ - nth row (from top to bottom) of the picture to render.
12+ -
13+ - A span op sequence will be defined for all rows and columns (and no more) of the region provided
14+ - with the picture to spans_for_pic.
15+ -
16+ - todo: Partition attribute changes into multiple categories according to the serialized
17+ - representation of the various attributes.
18+ -}
919module Graphics.Vty.Span
1020 where
1121
@@ -32,26 +42,31 @@ import qualified Data.ByteString.Lazy as BL
3242import qualified Data.ByteString.Lazy.Internal as BLInt
3343import qualified Data.Foldable as Foldable
3444import qualified Data.Text.Lazy as TL
45+import qualified Data.Text.Lazy.Encoding as TL
3546import Data.Word
3647
3748import Foreign.Storable ( pokeByteOff )
3849
39−-- | Currently append in the Monoid instance is equivalent to <->.
40−instance Monoid Image where
41− mempty = EmptyImage
42− mappend = (<->)
50+-- | This represents an operation on the terminal. Either an attribute change or the output of a
51+-- text string.
52+--
53+-- todo: This type may need to be restructured to increase sharing in the bytestring
54+--
55+-- todo: Make foldable
56+data SpanOp =
57+ AttributeChange !Attr
58+ -- | a span of UTF-8 text occupies a specific number of screen space columns. A single UTF
59+ -- character does not necessarially represent 1 colunm. See Codec.Binary.UTF8.Width
60+ -- TextSpan [output width in columns] [number of characters] [data]
61+ | TextSpan !Int !Int BL.ByteString
62+ deriving Eq
63+
64+-- | vector of span operations. executed in succession. This represents the operations required to
65+-- render a row of the terminal. The operations in one row may effect subsequent rows.
66+-- EG: Setting the foreground color in one row will effect all subsequent rows until the foreground
67+-- color is changed.
68+type SpanOps = Vector SpanOp
4369
44−{- | A picture is translated into a sequences of state changes and character spans.
45− - State changes are currently limited to new attribute values. The attribute is applied to all
46− - following spans. Including spans of the next row. The nth element of the sequence represents the
47− - nth row (from top to bottom) of the picture to render.
48− -
49− - A span op sequence will be defined for all rows and columns (and no more) of the region provided
50− - with the picture to spans_for_pic.
51− -
52− - todo: Partition attribute changes into multiple categories according to the serialized
53− - representation of the various attributes.
54− -}
5570
5671data DisplayOps = DisplayOps
5772 { effected_region :: DisplayRegion
@@ -63,12 +78,6 @@ type RowOps = Vector SpanOps
6378
6479type MRowOps s = MVector s SpanOps
6580
66−-- | vector of span operations. executed in succession. This represents the operations required to
67−-- render a row of the terminal. The operations in one row may effect subsequent rows.
68−-- EG: Setting the foreground color in one row will effect all subsequent rows until the foreground
69−-- color is changed.
70−type SpanOps = Vector SpanOp
71−
7281type MSpanOps s = MVector s SpanOp
7382
7483instance Show DisplayOps where
@@ -79,6 +88,34 @@ instance Show SpanOp where
7988 show (AttributeChange attr) = show attr
8089 show (TextSpan ow cw _) = "TextSpan " ++ show ow ++ " " ++ show cw
8190
91+-- transform plus clip. More or less.
92+data BlitState = BlitState
93+ -- we always snoc to the operation vectors. Thus the column_offset = length of row at row_offset
94+ { _row_offset :: Int
95+ -- clip coordinate space is in image space. Which means it's >= 0 and < image_width.
96+ , _skip_columns :: Int
97+ -- >= 0 and < image_height
98+ , _skip_rows :: Int
99+ -- includes consideration of skip_columns. In display space.
100+ -- The number of columns from the next column to be defined to the end of the display for the
101+ -- row.
102+ , _remaining_columns :: Int
103+ -- includes consideration of skip_rows. In display space.
104+ , _remaining_rows :: Int
105+ }
106+
107+makeLenses ''BlitState
108+
109+data BlitEnv s = BlitEnv
110+ { _bg :: Background
111+ , _region :: DisplayRegion
112+ , _mrow_ops :: MRowOps s
113+ }
114+
115+makeLenses ''BlitEnv
116+
117+type BlitM s a = ReaderT (BlitEnv s) (StateT BlitState (ST s)) a
118+
82119-- | Number of columns the DisplayOps are defined for
83120span_ops_columns :: DisplayOps -> Word
84121span_ops_columns ops = region_width $ effected_region ops
@@ -94,20 +131,6 @@ span_ops_effected_columns in_ops = Vector.foldl' span_ops_effected_columns' 0 in
94131 span_ops_effected_columns' t (TextSpan w _ _ ) = t + w
95132 span_ops_effected_columns' t _ = t
96133
97−-- | This represents an operation on the terminal. Either an attribute change or the output of a
98−-- text string.
99−--
100−-- todo: This type may need to be restructured to increase sharing in the bytestring
101−--
102−-- todo: Make foldable
103−data SpanOp =
104− AttributeChange !Attr
105− -- | a span of UTF-8 text occupies a specific number of screen space columns. A single UTF
106− -- character does not necessarially represent 1 colunm. See Codec.Binary.UTF8.Width
107− -- TextSpan [output width in columns] [number of characters] [data]
108− | TextSpan !Int !Int BL.ByteString
109− deriving Eq
110−
111134-- | The width of a single SpanOp in columns
112135span_op_has_width :: SpanOp -> Maybe (Int, Int)
113136span_op_has_width (TextSpan ow cw _) = Just (cw, ow)
@@ -125,34 +148,6 @@ columns_to_char_offset _cx _ = error "columns_to_char_offset applied to span op
125148spans_for_pic :: Picture -> DisplayRegion -> DisplayOps
126149spans_for_pic pic r = DisplayOps r $ Vector.create (build_spans pic r)
127150
128−-- transform plus clip. More or less.
129−newtype BlitState = BlitState
130− -- we always snoc to the operation vectors. Thus the column_offset = length of row at row_offset
131− { _row_offset :: Int
132− -- clip coordinate space is in image space. Which means it's >= 0 and < image_width.
133− , _skip_columns :: Int
134− -- >= 0 and < image_height
135− , _skip_rows :: Int
136− -- includes consideration of skip_columns. In display space.
137− -- The number of columns from the next column to be defined to the end of the display for the
138− -- row.
139− , _remaining_columns :: Int
140− -- includes consideration of skip_rows. In display space.
141− , _remaining_rows :: Int
142− }
143−
144−makeLenses ''BlitState
145−
146−newtype BlitEnv s = BlitEnv
147− { _bg :: Background
148− , _region :: DisplayRegion
149− , _mrow_ops :: MRowOps s
150− }
151−
152−makeLenses ''BlitEnv
153−
154−type BlitM s a = ReaderT (BlitEnv s) (StateT BlitState (ST s)) a
155−
156151-- | Builds a vector of row operations that will output the given picture to the terminal.
157152--
158153-- Crops to the given display region.