1 /*
2  * Copyright 2011 Ole Loots <ole@monochrom.net>
3  *
4  * This file is part of NetSurf, http://www.netsurf-browser.org/
5  *
6  * NetSurf is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * NetSurf is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include <stdbool.h>
20 
21 #include "utils/utils.h"
22 
23 #include "atari/redrawslots.h"
24 #include "atari/gemtk/gemtk.h"
25 
redraw_slots_init(struct s_redrw_slots * slots,short size)26 void redraw_slots_init(struct s_redrw_slots * slots, short size)
27 {
28 	// TODO: allocate slots dynamically!
29 	slots->size = MIN( MAX_REDRW_SLOTS , size);
30 	slots->areas_used = 0;
31 }
32 
redraw_slots_free(struct s_redrw_slots * slots)33 void redraw_slots_free(struct s_redrw_slots * slots)
34 {
35 	// TOOD: free areas...
36 }
37 
38 
rect_intersect(struct rect * box1,struct rect * box2)39 static inline bool rect_intersect( struct rect * box1, struct rect * box2 )
40 {
41 	if (box2->x1 < box1->x0)
42 		return false;
43 
44 	if (box2->y1 < box1->y0)
45 		return false;
46 
47 	if (box2->x0 > box1->x1)
48 		return false;
49 
50 	if (box2->y0 > box1->y1)
51 		return false;
52 
53 	return true;
54 }
55 
56 
redraw_slot_schedule_grect(struct s_redrw_slots * slots,GRECT * area,bool force)57 void redraw_slot_schedule_grect(struct s_redrw_slots * slots, GRECT *area,
58 				bool force)
59 {
60 	redraw_slot_schedule(slots, area->g_x, area->g_y,
61 			     area->g_x + area->g_w, area->g_y + area->g_h, force);
62 }
63 
64 /*
65   schedule redraw coords.
66 */
redraw_slot_schedule(struct s_redrw_slots * slots,short x0,short y0,short x1,short y1,bool force)67 void redraw_slot_schedule(struct s_redrw_slots * slots, short x0, short y0,
68 			  short x1, short y1, bool force)
69 {
70 	int i = 0;
71 	struct rect area;
72 
73 	area.x0 = x0;
74 	area.y0 = y0;
75 	area.x1 = x1;
76 	area.y1 = y1;
77 
78 	if (force == false) {
79 		for (i=0; i<slots->areas_used; i++) {
80 			if (slots->areas[i].x0 <= x0
81 			    && slots->areas[i].x1 >= x1
82 			    && slots->areas[i].y0 <= y0
83 			    && slots->areas[i].y1 >= y1) {
84 				/* the area is already queued for redraw */
85 				return;
86 			} else {
87 				if (rect_intersect(&slots->areas[i], &area )) {
88 					slots->areas[i].x0 = MIN(slots->areas[i].x0, x0);
89 					slots->areas[i].y0 = MIN(slots->areas[i].y0, y0);
90 					slots->areas[i].x1 = MAX(slots->areas[i].x1, x1);
91 					slots->areas[i].y1 = MAX(slots->areas[i].y1, y1);
92 					return;
93 				}
94 			}
95 		}
96 	}
97 
98 	if (slots->areas_used < slots->size) {
99 		slots->areas[slots->areas_used].x0 = x0;
100 		slots->areas[slots->areas_used].x1 = x1;
101 		slots->areas[slots->areas_used].y0 = y0;
102 		slots->areas[slots->areas_used].y1 = y1;
103 		slots->areas_used++;
104 	} else {
105 		/*
106 		  we are out of available slots, merge box with last slot
107 		  this is dumb... but also a very rare case.
108 		*/
109 		slots->areas[slots->size-1].x0 = MIN(slots->areas[i].x0, x0);
110 		slots->areas[slots->size-1].y0 = MIN(slots->areas[i].y0, y0);
111 		slots->areas[slots->size-1].x1 = MAX(slots->areas[i].x1, x1);
112 		slots->areas[slots->size-1].y1 = MAX(slots->areas[i].y1, y1);
113 	}
114 
115 	return;
116 }
117 
redraw_slots_remove_area(struct s_redrw_slots * slots,int i)118 void redraw_slots_remove_area(struct s_redrw_slots * slots, int i)
119 {
120 	int x;
121 	for (x = i+1; i<slots->areas_used; x++) {
122 		slots->areas[x-1] = slots->areas[x];
123 	}
124 	slots->areas_used--;
125 }
126