@@ -17,96 +17,96 @@ import qualified Data.Vector as Vector
1717unit_image_and_zero_window_0 :: UnitImage -> EmptyWindow -> Bool
1818unit_image_and_zero_window_0 (UnitImage _ i) (EmptyWindow w) =
1919 let p = pic_for_image i
20− spans = spans_for_pic p (region_for_window w)
21− in span_ops_columns spans == 0 && span_ops_rows spans == 0
20+ ops = display_ops_for_pic p (region_for_window w)
21+ in display_ops_columns ops == 0 && display_ops_rows ops == 0
2222
2323unit_image_and_zero_window_1 :: UnitImage -> EmptyWindow -> Bool
2424unit_image_and_zero_window_1 (UnitImage _ i) (EmptyWindow w) =
2525 let p = pic_for_image i
26− spans = spans_for_pic p (region_for_window w)
27− in ( span_ops_effected_rows spans == 0 ) && ( all_spans_have_width spans 0 )
26+ ops = display_ops_for_pic p (region_for_window w)
27+ in ( span_ops_effected_rows ops == 0 ) && ( all_spans_have_width ops 0 )
2828
2929horiz_span_image_and_zero_window_0 :: SingleRowSingleAttrImage -> EmptyWindow -> Bool
3030horiz_span_image_and_zero_window_0 (SingleRowSingleAttrImage { row_image = i }) (EmptyWindow w) =
3131 let p = pic_for_image i
32− spans = spans_for_pic p (region_for_window w)
33− in span_ops_columns spans == 0 && span_ops_rows spans == 0
32+ ops = display_ops_for_pic p (region_for_window w)
33+ in display_ops_columns ops == 0 && display_ops_rows ops == 0
3434
3535horiz_span_image_and_zero_window_1 :: SingleRowSingleAttrImage -> EmptyWindow -> Bool
3636horiz_span_image_and_zero_window_1 (SingleRowSingleAttrImage { row_image = i }) (EmptyWindow w) =
3737 let p = pic_for_image i
38− spans = spans_for_pic p (region_for_window w)
39− in ( span_ops_effected_rows spans == 0 ) && ( all_spans_have_width spans 0 )
38+ ops = display_ops_for_pic p (region_for_window w)
39+ in ( span_ops_effected_rows ops == 0 ) && ( all_spans_have_width ops 0 )
4040
4141horiz_span_image_and_equal_window_0 :: SingleRowSingleAttrImage -> Result
4242horiz_span_image_and_equal_window_0 (SingleRowSingleAttrImage { row_image = i, expected_columns = c }) =
4343 let p = pic_for_image i
4444 w = MockWindow c 1
45− spans = spans_for_pic p (region_for_window w)
46− in verify_all_spans_have_width i spans c
45+ ops = display_ops_for_pic p (region_for_window w)
46+ in verify_all_spans_have_width i ops c
4747
4848horiz_span_image_and_equal_window_1 :: SingleRowSingleAttrImage -> Bool
4949horiz_span_image_and_equal_window_1 (SingleRowSingleAttrImage { row_image = i, expected_columns = c }) =
5050 let p = pic_for_image i
5151 w = MockWindow c 1
52− spans = spans_for_pic p (region_for_window w)
53− in span_ops_effected_rows spans == 1
52+ ops = display_ops_for_pic p (region_for_window w)
53+ in span_ops_effected_rows ops == 1
5454
5555horiz_span_image_and_lesser_window_0 :: SingleRowSingleAttrImage -> Result
5656horiz_span_image_and_lesser_window_0 (SingleRowSingleAttrImage { row_image = i, expected_columns = c }) =
5757 let p = pic_for_image i
5858 lesser_width = c `div` 2
5959 w = MockWindow lesser_width 1
60− spans = spans_for_pic p (region_for_window w)
61− in verify_all_spans_have_width i spans lesser_width
60+ ops = display_ops_for_pic p (region_for_window w)
61+ in verify_all_spans_have_width i ops lesser_width
6262
6363single_attr_single_span_stack_cropped_0 :: SingleAttrSingleSpanStack -> Result
6464single_attr_single_span_stack_cropped_0 stack =
6565 let p = pic_for_image (stack_image stack)
6666 w = MockWindow (stack_width stack `div` 2) (stack_height stack)
67− spans = spans_for_pic p (region_for_window w)
68− in verify_all_spans_have_width (stack_image stack) spans (stack_width stack `div` 2)
67+ ops = display_ops_for_pic p (region_for_window w)
68+ in verify_all_spans_have_width (stack_image stack) ops (stack_width stack `div` 2)
6969
7070single_attr_single_span_stack_cropped_1 :: SingleAttrSingleSpanStack -> Bool
7171single_attr_single_span_stack_cropped_1 stack =
7272 let p = pic_for_image (stack_image stack)
7373 expected_row_count = stack_height stack `div` 2
7474 w = MockWindow (stack_width stack) expected_row_count
75− spans = spans_for_pic p (region_for_window w)
76− actual_row_count = span_ops_effected_rows spans
75+ ops = display_ops_for_pic p (region_for_window w)
76+ actual_row_count = span_ops_effected_rows ops
7777 in expected_row_count == actual_row_count
7878
7979single_attr_single_span_stack_cropped_2 :: SingleAttrSingleSpanStack -> SingleAttrSingleSpanStack -> Result
8080single_attr_single_span_stack_cropped_2 stack_0 stack_1 =
8181 let p = pic_for_image (stack_image stack_0 <|> stack_image stack_1)
8282 w = MockWindow (stack_width stack_0) (image_height (pic_image p))
83− spans = spans_for_pic p (region_for_window w)
84− in verify_all_spans_have_width (pic_image p) spans (stack_width stack_0)
83+ ops = display_ops_for_pic p (region_for_window w)
84+ in verify_all_spans_have_width (pic_image p) ops (stack_width stack_0)
8585
8686single_attr_single_span_stack_cropped_3 :: SingleAttrSingleSpanStack -> SingleAttrSingleSpanStack -> Bool
8787single_attr_single_span_stack_cropped_3 stack_0 stack_1 =
8888 let p = pic_for_image (stack_image stack_0 <|> stack_image stack_1)
8989 w = MockWindow (image_width (pic_image p)) expected_row_count
90− spans = spans_for_pic p (region_for_window w)
90+ ops = display_ops_for_pic p (region_for_window w)
9191 expected_row_count = image_height (pic_image p) `div` 2
92− actual_row_count = span_ops_effected_rows spans
92+ actual_row_count = span_ops_effected_rows ops
9393 in expected_row_count == actual_row_count
9494
9595single_attr_single_span_stack_cropped_4 :: SingleAttrSingleSpanStack -> SingleAttrSingleSpanStack -> Result
9696single_attr_single_span_stack_cropped_4 stack_0 stack_1 =
9797 let p = pic_for_image (stack_image stack_0 <-> stack_image stack_1)
9898 w = MockWindow expected_width (image_height (pic_image p))
99− spans = spans_for_pic p (region_for_window w)
99+ ops = display_ops_for_pic p (region_for_window w)
100100 expected_width = image_width (pic_image p) `div` 2
101− in verify_all_spans_have_width (pic_image p) spans expected_width
101+ in verify_all_spans_have_width (pic_image p) ops expected_width
102102
103103single_attr_single_span_stack_cropped_5 :: SingleAttrSingleSpanStack -> SingleAttrSingleSpanStack -> Bool
104104single_attr_single_span_stack_cropped_5 stack_0 stack_1 =
105105 let p = pic_for_image (stack_image stack_0 <-> stack_image stack_1)
106106 w = MockWindow (image_width (pic_image p)) (stack_height stack_0)
107− spans = spans_for_pic p (region_for_window w)
107+ ops = display_ops_for_pic p (region_for_window w)
108108 expected_row_count = stack_height stack_0
109− actual_row_count = span_ops_effected_rows spans
109+ actual_row_count = span_ops_effected_rows ops
110110 in expected_row_count == actual_row_count
111111
112112horiz_span_image_and_greater_window_0 :: SingleRowSingleAttrImage -> Result
@@ -115,46 +115,82 @@ horiz_span_image_and_greater_window_0 (SingleRowSingleAttrImage { row_image = i,
115115 -- SingleRowSingleAttrImage always has width >= 1
116116 greater_width = c * 2
117117 w = MockWindow greater_width 1
118− spans = spans_for_pic p (region_for_window w)
119− in verify_all_spans_have_width i spans greater_width
118+ ops = display_ops_for_pic p (region_for_window w)
119+ in verify_all_spans_have_width i ops greater_width
120120
121121arb_image_is_cropped :: DefaultImage -> MockWindow -> Bool
122122arb_image_is_cropped (DefaultImage image) win@(MockWindow w h) =
123123 let pic = pic_for_image image
124− spans = spans_for_pic pic (region_for_window win)
125− in ( span_ops_effected_rows spans == h ) && ( all_spans_have_width spans w )
124+ ops = display_ops_for_pic pic (region_for_window win)
125+ in ( span_ops_effected_rows ops == h ) && ( all_spans_have_width ops w )
126126
127127span_ops_actually_fill_rows :: DefaultPic -> Bool
128128span_ops_actually_fill_rows (DefaultPic pic win) =
129− let spans = spans_for_pic pic (region_for_window win)
129+ let ops = display_ops_for_pic pic (region_for_window win)
130130 expected_row_count = region_height (region_for_window win)
131− actual_row_count = span_ops_effected_rows spans
131+ actual_row_count = span_ops_effected_rows ops
132132 in expected_row_count == actual_row_count
133133
134134span_ops_actually_fill_columns :: DefaultPic -> Bool
135135span_ops_actually_fill_columns (DefaultPic pic win) =
136− let spans = spans_for_pic pic (region_for_window win)
136+ let ops = display_ops_for_pic pic (region_for_window win)
137137 expected_column_count = region_width (region_for_window win)
138− in all_spans_have_width spans expected_column_count
138+ in all_spans_have_width ops expected_column_count
139139
140140first_span_op_sets_attr :: DefaultPic -> Bool
141141first_span_op_sets_attr DefaultPic { default_pic = pic, default_win = win } =
142− let spans = spans_for_pic pic (region_for_window win)
143− in all ( is_attr_span_op . Vector.head ) ( Vector.toList $ display_ops spans )
142+ let ops = display_ops_for_pic pic (region_for_window win)
143+ in all ( is_attr_span_op . Vector.head ) ( Vector.toList ops )
144144
145145single_attr_single_span_stack_op_coverage :: SingleAttrSingleSpanStack -> Result
146146single_attr_single_span_stack_op_coverage stack =
147147 let p = pic_for_image (stack_image stack)
148148 w = MockWindow (stack_width stack) (stack_height stack)
149− spans = spans_for_pic p (region_for_window w)
150− in verify_all_spans_have_width (stack_image stack) spans (stack_width stack)
149+ ops = display_ops_for_pic p (region_for_window w)
150+ in verify_all_spans_have_width (stack_image stack) ops (stack_width stack)
151+
152+crop_op_display_ops :: (Int -> Image -> Image) ->
153+ Int -> Image -> (DisplayOps, Image)
154+crop_op_display_ops crop_op v i =
155+ let i_out = crop_op v i
156+ p = pic_for_image i_out
157+ w = MockWindow (image_width i_out) (image_height i_out)
158+ in (display_ops_for_pic p (region_for_window w), i_out)
159+
160+width_crop_output_columns :: (Int -> Image -> Image) ->
161+ SingleAttrSingleSpanStack ->
162+ NonNegative Int ->
163+ Property
164+width_crop_output_columns crop_op s (NonNegative w) = stack_width s > w ==>
165+ let (ops, i_out) = crop_op_display_ops crop_op w (stack_image s)
166+ in verify_all_spans_have_width i_out ops w
167+
168+height_crop_output_columns :: (Int -> Image -> Image) ->
169+ SingleAttrSingleSpanStack ->
170+ NonNegative Int ->
171+ Property
172+height_crop_output_columns crop_op s (NonNegative h) = stack_height s > h ==>
173+ let (ops, _) = crop_op_display_ops crop_op h (stack_image s)
174+ in display_ops_rows ops == h
175+
176+crop_right_output_columns :: SingleAttrSingleSpanStack -> NonNegative Int -> Property
177+crop_right_output_columns = width_crop_output_columns crop_right
178+
179+crop_left_output_columns :: SingleAttrSingleSpanStack -> NonNegative Int -> Property
180+crop_left_output_columns = width_crop_output_columns crop_left
181+
182+crop_top_output_rows :: SingleAttrSingleSpanStack -> NonNegative Int -> Property
183+crop_top_output_rows = height_crop_output_columns crop_top
184+
185+crop_bottom_output_rows :: SingleAttrSingleSpanStack -> NonNegative Int -> Property
186+crop_bottom_output_rows = height_crop_output_columns crop_bottom
151187
152188image_coverage_matches_bounds :: Image -> Result
153189image_coverage_matches_bounds i =
154190 let p = pic_for_image i
155191 r = DisplayRegion (image_width i) (image_height i)
156− spans = spans_for_pic p r
157− in verify_all_spans_have_width i spans (image_width i)
192+ ops = display_ops_for_pic p r
193+ in verify_all_spans_have_width i ops (image_width i)
158194
159195tests :: IO [Test]
160196tests = return
@@ -176,14 +212,22 @@ tests = return
176212 single_attr_single_span_stack_cropped_0
177213 , verify "a single attr text span is cropped when window size < size of stack image [height]"
178214 single_attr_single_span_stack_cropped_1
179− , verify "single attr text span <|> single attr text span cropped. [width]"
215+ , verify "single attr text span <|> single attr text span display cropped. [width]"
180216 single_attr_single_span_stack_cropped_2
181− , verify "single attr text span <|> single attr text span cropped. [height]"
217+ , verify "single attr text span <|> single attr text span display cropped. [height]"
182218 single_attr_single_span_stack_cropped_3
183− , verify "single attr text span <-> single attr text span cropped. [width]"
219+ , verify "single attr text span <-> single attr text span display cropped. [width]"
184220 single_attr_single_span_stack_cropped_4
185− , verify "single attr text span <-> single attr text span cropped. [height]"
221+ , verify "single attr text span <-> single attr text span display cropped. [height]"
186222 single_attr_single_span_stack_cropped_5
223+ , verify "cropping from the bottom produces display operations covering the expected rows"
224+ crop_bottom_output_rows
225+ , verify "cropping from the top produces display operations covering the expected rows"
226+ crop_top_output_rows
227+ , verify "cropping from the left produces display operations covering the expected columns"
228+ crop_left_output_columns
229+ , verify "cropping from the right produces display operations covering the expected columns"
230+ crop_right_output_columns
187231 , verify "an arbitrary image when rendered to a window of the same size will cover the entire window"
188232 image_coverage_matches_bounds
189233 ]