1 #include "evas_common.h"
5 static const list_node_t list_node_zeroed = { NULL };
6 static const list_t list_zeroed = { NULL, NULL };
9 typedef struct list_node_pool
16 static list_node_pool_t list_node_pool = { NULL, 0, 1024 };
19 rect_list_node_pool_set_max(int max)
23 diff = list_node_pool.len - max;
24 for (; diff > 0 && list_node_pool.node != NULL; diff--)
28 node = list_node_pool.node;
29 list_node_pool.node = node->next;
35 list_node_pool.max = max;
39 rect_list_node_pool_flush(void)
41 while (list_node_pool.node)
45 node = list_node_pool.node;
46 list_node_pool.node = node->next;
54 rect_list_node_pool_get(void)
56 if (list_node_pool.node)
60 node = list_node_pool.node;
61 list_node_pool.node = node->next;
66 else return malloc(sizeof(rect_node_t));
70 rect_list_node_pool_put(list_node_t *node)
72 if (list_node_pool.len < list_node_pool.max)
74 node->next = list_node_pool.node;
75 list_node_pool.node = node;
82 rect_init(rect_t *r, int x, int y, int w, int h)
97 rect_print(const rect_t r)
99 printf("<rect(%d, %d, %d, %d)>", r.left, r.top, r.width, r.height);
103 rect_list_print(const list_t rects)
109 for (node = rects.head; node != NULL; node = node->next) len++;
112 for (node = rects.head; node != NULL; node = node->next)
114 rect_print(((rect_node_t *)node)->rect);
118 if (len < 4) putchar(' ');
130 rect_list_append_node(list_t *rects, list_node_t *node)
134 rects->tail->next = node;
145 rect_list_append(list_t *rects, const rect_t r)
147 rect_node_t *rect_node;
149 rect_node = (rect_node_t *)rect_list_node_pool_get();
151 rect_node->_lst = list_node_zeroed;
153 rect_list_append_node(rects, (list_node_t *)rect_node);
157 rect_list_append_xywh(list_t *rects, int x, int y, int w, int h)
161 rect_init(&r, x, y, w, h);
162 rect_list_append(rects, r);
166 rect_list_concat(list_t *rects, list_t *other)
173 rects->tail->next = other->head;
174 rects->tail = other->tail;
178 rects->head = other->head;
179 rects->tail = other->tail;
181 *other = list_zeroed;
185 rect_list_unlink_next(list_t *rects, list_node_t *parent_node)
191 node = parent_node->next;
192 parent_node->next = node->next;
197 rects->head = node->next;
200 if (rects->tail == node) rects->tail = parent_node;
201 *node = list_node_zeroed;
206 rect_list_del_next(list_t *rects, list_node_t *parent_node)
210 node = rect_list_unlink_next(rects, parent_node);
211 rect_list_node_pool_put(node);
215 rect_list_clear(list_t *rects)
225 rect_list_node_pool_put(node);
228 *rects = list_zeroed;
232 _calc_intra_rect_area(const rect_t a, const rect_t b, int *width, int *height)
234 int max_left, min_right, max_top, min_bottom;
236 if (a.left < b.left) max_left = b.left;
237 else max_left = a.left;
239 if (a.right < b.right) min_right = a.right;
240 else min_right = b.right;
242 *width = min_right - max_left;
244 if (a.top < b.top) max_top = b.top;
245 else max_top = a.top;
247 if (a.bottom < b.bottom) min_bottom = a.bottom;
248 else min_bottom = b.bottom;
250 *height = min_bottom - max_top;
254 _split_strict(list_t *dirty, const rect_t current, rect_t r)
256 int h_1, h_2, w_1, w_2;
258 h_1 = current.top - r.top;
259 h_2 = r.bottom - current.bottom;
260 w_1 = current.left - r.left;
261 w_2 = r.right - current.right;
267 * .-------.cur (a) .---.r '---'
272 rect_list_append_xywh(dirty, r.left, r.top, r.width, h_1);
282 * `-------' `---' + .---.r2
286 rect_list_append_xywh(dirty, r.left, current.bottom, r.width, h_2);
292 /* (b) r .----.cur (a)
293 * .--|-. | .--.r2 .-.r
294 * | | | | -> | | + | |
298 rect_list_append_xywh(dirty, r.left, r.top, w_1, r.height);
299 /* not necessary to keep these, r (b) will be destroyed */
300 /* r.width -= w_1; */
301 /* r.left = current.left; */
308 * | .-|--.r (b) .-.r .--.r2
309 * | | | | -> | | + | |
313 rect_list_append_xywh(dirty, current.right, r.top, w_2, r.height);
314 /* not necessary to keep this, r (b) will be destroyed */
315 /* r.width -= w_2; */
320 rect_list_del_split_strict(list_t *rects, const rect_t del_r)
322 list_t modified = list_zeroed;
323 list_node_t *cur_node, *prev_node;
326 cur_node = rects->head;
329 int intra_width, intra_height;
332 current = ((rect_node_t*)cur_node)->rect;
334 _calc_intra_rect_area(del_r, current, &intra_width, &intra_height);
335 if ((intra_width <= 0) || (intra_height <= 0))
337 /* .---.current .---.del_r
339 * `---+---.del_r `---+---.current
342 * no interception, nothing to do
344 prev_node = cur_node;
345 cur_node = cur_node->next;
347 else if ((intra_width == current.width) &&
348 (intra_height == current.height))
355 * current is contained, remove from rects
357 cur_node = cur_node->next;
358 rect_list_del_next(rects, prev_node);
362 _split_strict(&modified, del_r, current);
363 cur_node = cur_node->next;
364 rect_list_del_next(rects, prev_node);
368 rect_list_concat(rects, &modified);
372 rect_list_add_split_strict(list_t *rects, list_node_t *node)
374 list_t dirty = list_zeroed;
375 list_t new_dirty = list_zeroed;
376 list_node_t *cur_node;
380 rect_list_append_node(rects, node);
384 rect_list_append_node(&dirty, node);
386 cur_node = rects->head;
393 rect_list_concat(rects, &dirty);
397 current = ((rect_node_t*)cur_node)->rect;
401 int intra_width, intra_height;
404 r = ((rect_node_t *)dirty.head)->rect;
405 _calc_intra_rect_area(r, current, &intra_width, &intra_height);
406 if ((intra_width == r.width) && (intra_height == r.height))
413 rect_list_del_next(&dirty, NULL);
414 else if ((intra_width <= 0) || (intra_height <= 0))
418 * `---+---.r `---+---.cur
423 tmp = rect_list_unlink_next(&dirty, NULL);
424 rect_list_append_node(&new_dirty, tmp);
428 _split_strict(&new_dirty, current, r);
429 rect_list_del_next(&dirty, NULL);
433 new_dirty = list_zeroed;
435 cur_node = cur_node->next;
440 _calc_intra_outer_rect_area(const rect_t a, const rect_t b,
441 rect_t *intra, rect_t *outer)
443 int min_left, max_left, min_right, max_right;
444 int min_top, max_top, min_bottom, max_bottom;
457 if (a.right < b.right)
468 intra->left = max_left;
469 intra->right = min_right;
470 intra->width = min_right - max_left;
472 outer->left = min_left;
473 outer->right = max_right;
474 outer->width = max_right - min_left;
487 if (a.bottom < b.bottom)
489 min_bottom = a.bottom;
490 max_bottom = b.bottom;
494 min_bottom = b.bottom;
495 max_bottom = a.bottom;
498 intra->top = max_top;
499 intra->bottom = min_bottom;
500 intra->height = min_bottom - max_top;
501 if ((intra->width > 0) && (intra->height > 0))
502 intra->area = intra->width * intra->height;
506 outer->top = min_top;
507 outer->bottom = max_bottom;
508 outer->height = max_bottom - min_top;
509 outer->area = outer->width * outer->height;
514 SPLIT_FUZZY_ACTION_NONE,
515 SPLIT_FUZZY_ACTION_SPLIT,
516 SPLIT_FUZZY_ACTION_MERGE
520 _split_fuzzy(list_t *dirty, const rect_t a, rect_t *b)
522 int h_1, h_2, w_1, w_2, action;
524 h_1 = a.top - b->top;
525 h_2 = b->bottom - a.bottom;
526 w_1 = a.left - b->left;
527 w_2 = b->right - a.right;
529 action = SPLIT_FUZZY_ACTION_NONE;
535 * .-------.cur (a) .---.r '---'
540 rect_list_append_xywh(dirty, b->left, b->top, b->width, h_1);
543 action = SPLIT_FUZZY_ACTION_SPLIT;
551 * `-------' `---' + .---.r2
555 rect_list_append_xywh(dirty, b->left, a.bottom, b->width, h_2);
557 action = SPLIT_FUZZY_ACTION_SPLIT;
560 if (((w_1 > 0) || (w_2 > 0)) && (a.height == b->height))
561 return SPLIT_FUZZY_ACTION_MERGE;
565 /* (b) r .----.cur (a)
566 * .--|-. | .--.r2 .-.r
567 * | | | | -> | | + | |
571 rect_list_append_xywh(dirty, b->left, b->top, w_1, b->height);
572 /* not necessary to keep these, r (b) will be destroyed */
573 /* b->width -= w_1; */
574 /* b->left = a.left; */
575 action = SPLIT_FUZZY_ACTION_SPLIT;
582 * | .-|--.r (b) .-.r .--.r2
583 * | | | | -> | | + | |
587 rect_list_append_xywh(dirty, a.right, b->top, w_2, b->height);
588 /* not necessary to keep these, r (b) will be destroyed */
589 /* b->width -= w_2; */
590 action = SPLIT_FUZZY_ACTION_SPLIT;
597 rect_list_add_split_fuzzy(list_t *rects, list_node_t *node, int accepted_error)
599 list_t dirty = list_zeroed;
600 list_node_t *old_last;
602 old_last = rects->tail;
606 rect_list_append_node(rects, node);
610 rect_list_append_node(&dirty, node);
613 list_node_t *d_node, *cur_node, *prev_cur_node;
617 d_node = rect_list_unlink_next(&dirty, NULL);
618 r = ((rect_node_t *)d_node)->rect;
620 prev_cur_node = NULL;
621 cur_node = rects->head;
626 rect_t current, intra, outer;
628 current = ((rect_node_t *)cur_node)->rect;
630 _calc_intra_outer_rect_area(r, current, &intra, &outer);
631 area = current.area + r.area - intra.area;
633 if ((intra.width == r.width) && (intra.height == r.height))
644 else if ((intra.width == current.width) &&
645 (intra.height == current.height))
653 if (old_last == cur_node)
654 old_last = prev_cur_node;
655 cur_node = cur_node->next;
656 rect_list_del_next(rects, prev_cur_node);
658 else if ((outer.area - area) <= accepted_error)
660 /* .-----------. bounding box (outer)
666 * merge them, remove both and add merged
670 if (old_last == cur_node)
671 old_last = prev_cur_node;
673 n = (rect_node_t *)rect_list_unlink_next(rects, prev_cur_node);
675 rect_list_append_node(&dirty, (list_node_t *)n);
680 else if (intra.area <= accepted_error)
684 * `---+---.r `---+---.cur
689 prev_cur_node = cur_node;
690 cur_node = cur_node->next;
694 /* split is required */
695 action = _split_fuzzy(&dirty, current, &r);
696 if (action == SPLIT_FUZZY_ACTION_MERGE)
698 /* horizontal merge is possible: remove both, add merged */
701 if (old_last == cur_node)
702 old_last = prev_cur_node;
705 rect_list_unlink_next(rects, prev_cur_node);
707 n->rect.left = outer.left;
708 n->rect.width = outer.width;
709 n->rect.right = outer.right;
710 n->rect.area = outer.width * r.height;
711 rect_list_append_node(&dirty, (list_node_t *)n);
713 else if (action == SPLIT_FUZZY_ACTION_NONE)
716 * this rect check was totally useless,
717 * should never happen
719 /* prev_cur_node = cur_node; */
720 /* cur_node = cur_node->next; */
721 printf("Should not get here!\n");
730 if (UNLIKELY(keep_dirty)) rect_list_append_node(rects, d_node);
731 else rect_list_node_pool_put(d_node);
738 _calc_outer_rect_area(const rect_t a, const rect_t b, rect_t *outer)
740 int min_left, max_right;
741 int min_top, max_bottom;
743 if (a.left < b.left) min_left = a.left;
744 else min_left = b.left;
746 if (a.right < b.right) max_right = b.right;
747 else max_right = a.right;
749 outer->left = min_left;
750 outer->right = max_right;
751 outer->width = max_right - min_left;
753 if (a.top < b.top) min_top = a.top;
754 else min_top = b.top;
756 if (a.bottom < b.bottom) max_bottom = b.bottom;
757 else max_bottom = a.bottom;
759 outer->top = min_top;
760 outer->bottom = max_bottom;
761 outer->height = max_bottom - min_top;
763 outer->area = outer->width * outer->height;
767 rect_list_merge_rects(list_t *rects, list_t *to_merge, int accepted_error)
769 while (to_merge->head)
771 list_node_t *node, *parent_node;
775 r1 = ((rect_node_t *)to_merge->head)->rect;
785 r2 = ((rect_node_t *)node)->rect;
787 _calc_outer_rect_area(r1, r2, &outer);
788 area = r1.area + r2.area; /* intra area is taken as 0 */
789 if (outer.area - area <= accepted_error)
792 * remove both r1 and r2, create r3
793 * actually r3 uses r2 instance, saves memory
797 n = (rect_node_t *)rect_list_unlink_next(rects, parent_node);
799 rect_list_append_node(to_merge, (list_node_t *)n);
811 n = rect_list_unlink_next(to_merge, NULL);
812 rect_list_append_node(rects, n);
815 rect_list_del_next(to_merge, NULL);
820 rect_list_add_split_fuzzy_and_merge(list_t *rects,
822 int split_accepted_error,
823 int merge_accepted_error)
827 n = rect_list_add_split_fuzzy(rects, node, split_accepted_error);
832 /* split list into 2 segments, already merged and to merge */
833 to_merge.head = n->next;
834 to_merge.tail = rects->tail;
838 rect_list_merge_rects(rects, &to_merge, merge_accepted_error);
841 #endif /* EVAS_RECT_SPLIT */
843 #define TILE(tb, x, y) ((tb)->tiles.tiles[((y) * (tb)->tiles.w) + (x)])
846 #elif defined(EVAS_RECT_SPLIT)
848 static int tilebuf_x_intersect(Tilebuf *tb, int x, int w, int *x1, int *x2, int *x1_fill, int *x2_fill);
849 static int tilebuf_y_intersect(Tilebuf *tb, int y, int h, int *y1, int *y2, int *y1_fill, int *y2_fill);
850 static int tilebuf_intersect(int tsize, int tlen, int tnum, int x, int w, int *x1, int *x2, int *x1_fill, int *x2_fill);
852 static void tilebuf_setup(Tilebuf *tb);
855 evas_common_tilebuf_init(void)
860 evas_common_tilebuf_new(int w, int h)
864 tb = calloc(1, sizeof(Tilebuf));
865 if (!tb) return NULL;
876 evas_common_tilebuf_free(Tilebuf *tb)
879 evas_common_regionbuf_free(tb->rb);
880 #elif defined(EVAS_RECT_SPLIT)
881 rect_list_clear(&tb->rects);
882 rect_list_node_pool_flush();
884 if (tb->tiles.tiles) free(tb->tiles.tiles);
890 evas_common_tilebuf_set_tile_size(Tilebuf *tb, int tw, int th)
892 tb->tile_size.w = tw;
893 tb->tile_size.h = th;
898 evas_common_tilebuf_get_tile_size(Tilebuf *tb, int *tw, int *th)
900 if (tw) *tw = tb->tile_size.w;
901 if (th) *th = tb->tile_size.h;
904 #ifdef EVAS_RECT_SPLIT
906 _add_redraw(list_t *rects, int max_w, int max_h, int x, int y, int w, int h)
910 if ((w <= 0) || (h <= 0)) return 0;
911 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, max_w, max_h);
912 if ((w <= 0) || (h <= 0)) return 0;
921 rn = (rect_node_t *)rect_list_node_pool_get();
922 rn->_lst = list_node_zeroed;
923 rect_init(&rn->rect, x, y, w, h);
924 //fprintf(stderr, "ACCOUNTING: add_redraw: %4d,%4d %3dx%3d\n", x, y, w, h);
925 //testing on my core2 duo desktop - fuzz of 32 or 48 is best.
927 rect_list_add_split_fuzzy_and_merge(rects, (list_node_t *)rn,
928 FUZZ * FUZZ, FUZZ * FUZZ);
934 evas_common_tilebuf_add_redraw(Tilebuf *tb, int x, int y, int w, int h)
939 if ((w <= 0) || (h <= 0)) return 0;
940 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
941 if ((w <= 0) || (h <= 0)) return 0;
942 for (i = 0; i < h; i++)
943 evas_common_regionbuf_span_add(tb->rb, x, x + w - 1, y + i);
945 #elif defined(EVAS_RECT_SPLIT)
946 return _add_redraw(&tb->rects, tb->outbuf_w, tb->outbuf_h, x, y, w, h);
948 int tx1, tx2, ty1, ty2, tfx1, tfx2, tfy1, tfy2, xx, yy;
951 if ((w <= 0) || (h <= 0)) return 0;
952 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
953 if ((w <= 0) || (h <= 0)) return 0;
955 /* wipes out any motion vectors in tiles it touches into redraws */
956 if (tilebuf_x_intersect(tb, x, w, &tx1, &tx2, &tfx1, &tfx2) &&
957 tilebuf_y_intersect(tb, y, h, &ty1, &ty2, &tfy1, &tfy2))
963 tbt = &(TILE(tb, tx1, ty1));
964 delta_x = tx2 - tx1 + 1;
965 delta_y = ty2 - ty1 + 1;
966 for (yy = delta_y; yy > 0; yy--)
971 for (xx = delta_x; xx > 0; xx--)
978 num = (tx2 - tx1 + 1) * (ty2 - ty1 + 1);
985 evas_common_tilebuf_del_redraw(Tilebuf *tb, int x, int y, int w, int h)
990 for (i = 0; i < h; i++)
991 evas_common_regionbuf_span_del(tb->rb, x, x + w - 1, y + i);
992 #elif defined(EVAS_RECT_SPLIT)
995 if (!tb->rects.head) return 0;
996 if ((w <= 0) || (h <= 0)) return 0;
997 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
998 if ((w <= 0) || (h <= 0)) return 0;
1009 if ((w <= 0) || (h <= 0)) return 0;
1011 rect_init(&r, x, y, w, h);
1012 //fprintf(stderr, "ACCOUNTING: del_redraw: %4d,%4d %3dx%3d\n", x, y, w, h);
1014 rect_list_del_split_strict(&tb->rects, r);
1018 int tx1, tx2, ty1, ty2, tfx1, tfx2, tfy1, tfy2, xx, yy;
1022 /* wipes out any motion vectors in tiles it touches into redraws */
1023 if (tilebuf_x_intersect(tb, x, w, &tx1, &tx2, &tfx1, &tfx2) &&
1024 tilebuf_y_intersect(tb, y, h, &ty1, &ty2, &tfy1, &tfy2))
1035 tbt = &(TILE(tb, tx1, ty1));
1036 delta_x = tx2 - tx1 + 1;
1037 delta_y = ty2 - ty1 + 1;
1038 for (yy = delta_y; yy > 0; yy--)
1043 for (xx = delta_x; xx > 0; xx--)
1050 num = (tx2 - tx1 + 1) * (ty2 - ty1 + 1);
1057 evas_common_tilebuf_add_motion_vector(Tilebuf *tb, int x, int y, int w, int h, int dx, int dy, int alpha)
1059 #ifdef EVAS_RECT_SPLIT
1060 list_t lr = list_zeroed;
1063 num = _add_redraw(&lr, tb->outbuf_w, tb->outbuf_h, x, y, w, h);
1064 num += _add_redraw(&lr, tb->outbuf_w, tb->outbuf_h, x + dx, y + dy, w, h);
1065 while (lr.head != NULL)
1067 list_node_t *node = rect_list_unlink_next(&lr, NULL);
1068 rect_list_add_split_fuzzy_and_merge(&tb->rects, node,
1069 FUZZ * FUZZ, FUZZ * FUZZ);
1073 /* FIXME: need to actually impliment motion vectors. for now it just */
1074 /* implements redraws */
1077 num = evas_common_tilebuf_add_redraw(tb, x, y, w, h);
1078 num += evas_common_tilebuf_add_redraw(tb, x + dx, y + dy, w, h);
1084 evas_common_tilebuf_clear(Tilebuf *tb)
1087 evas_common_regionbuf_clear(tb->rb);
1088 #elif defined(EVAS_RECT_SPLIT)
1089 rect_list_clear(&tb->rects);
1092 if (!tb->tiles.tiles) return;
1093 memset(tb->tiles.tiles, 0, tb->tiles.w * tb->tiles.h * sizeof(Tilebuf_Tile));
1098 evas_common_tilebuf_get_render_rects(Tilebuf *tb)
1101 return evas_common_regionbuf_rects_get(tb->rb);
1102 #elif defined(EVAS_RECT_SPLIT)
1104 Tilebuf_Rect *rects = NULL;
1106 if (tb->need_merge) {
1108 to_merge = tb->rects;
1109 tb->rects = list_zeroed;
1110 rect_list_merge_rects(&tb->rects, &to_merge, FUZZ * FUZZ);
1114 for (n = tb->rects.head; n != NULL; n = n->next) {
1117 cur = ((rect_node_t *)n)->rect;
1124 RECTS_CLIP_TO_RECT(cur.left, cur.top, cur.width, cur.height,
1125 0, 0, tb->outbuf_w, tb->outbuf_h);
1126 if ((cur.width > 0) && (cur.height > 0))
1130 r = malloc(sizeof(Tilebuf_Rect));
1131 r->_list_data.next = NULL;
1132 r->_list_data.prev = NULL;
1133 r->_list_data.last = NULL;
1139 rects = evas_object_list_append(rects, r);
1145 Tilebuf_Rect *rects = NULL;
1149 tbt = &(TILE(tb, 0, 0));
1150 for (y = 0; y < tb->tiles.h; y++)
1152 for (x = 0; x < tb->tiles.w; x++, tbt++)
1157 int can_expand_x = 1, can_expand_y = 1;
1158 Tilebuf_Rect *r = NULL;
1160 r = malloc(sizeof(Tilebuf_Rect));
1161 r->_list_data.next = NULL;
1162 r->_list_data.prev = NULL;
1163 r->_list_data.last = NULL;
1165 /* amalgamate tiles */
1168 while (can_expand_x)
1172 if ((x + xx) >= tb->tiles.w)
1174 else if (!(tbti->redraw))
1180 while (can_expand_y)
1184 tbti += tb->tiles.w;
1186 if ((y + yy) >= tb->tiles.h)
1193 for (i = x; i < x + xx; i++, tbtj++)
1195 if (!(tbtj->redraw))
1207 for (i = x; i < x + xx; i++, tbtj++)
1216 r->x = x * tb->tile_size.w;
1217 r->y = y * tb->tile_size.h;
1218 r->w = (xx) * tb->tile_size.w;
1219 r->h = (yy) * tb->tile_size.h;
1220 rects = evas_object_list_append(rects, r);
1231 evas_common_tilebuf_free_render_rects(Tilebuf_Rect *rects)
1238 rects = evas_object_list_remove(rects, r);
1243 /* need a way of getting rectangles to: blit, re-render */
1249 /* internal usage */
1252 tilebuf_setup(Tilebuf *tb)
1254 if ((tb->outbuf_w <= 0) || (tb->outbuf_h <= 0)) return;
1256 tb->rb = evas_common_regionbuf_new(tb->outbuf_w, tb->outbuf_h);
1257 #elif defined(EVAS_RECT_SPLIT)
1258 tb->rects = list_zeroed;
1260 if (tb->tiles.tiles) free(tb->tiles.tiles);
1261 tb->tiles.tiles = NULL;
1263 tb->tiles.w = (tb->outbuf_w + (tb->tile_size.w - 1)) / tb->tile_size.w;
1264 tb->tiles.h = (tb->outbuf_h + (tb->tile_size.h - 1)) / tb->tile_size.h;
1266 tb->tiles.tiles = malloc(tb->tiles.w * tb->tiles.h * sizeof(Tilebuf_Tile));
1268 if (!tb->tiles.tiles)
1274 memset(tb->tiles.tiles, 0, tb->tiles.w * tb->tiles.h * sizeof(Tilebuf_Tile));
1279 #elif defined(EVAS_RECT_SPLIT)
1282 tilebuf_x_intersect(Tilebuf *tb, int x, int w, int *x1, int *x2, int *x1_fill, int *x2_fill)
1284 return tilebuf_intersect(tb->tile_size.w, tb->outbuf_w, tb->tiles.w,
1285 x, w, x1, x2, x1_fill, x2_fill);
1289 tilebuf_y_intersect(Tilebuf *tb, int y, int h, int *y1, int *y2, int *y1_fill, int *y2_fill)
1291 return tilebuf_intersect(tb->tile_size.h, tb->outbuf_h, tb->tiles.h,
1292 y, h, y1, y2, y1_fill, y2_fill);
1296 tilebuf_intersect(int tsize, int tlen, int tnum, int x, int w, int *x1, int *x2, int *x1_fill, int *x2_fill)
1300 /* initial clip out of region */
1301 if ((x + w) <= 0) return 0;
1302 if (x >= tlen) return 0;
1304 /* adjust x & w so it all fits in region */
1310 if (w < 0) return 0;
1311 if ((x + w) > tlen) w = tlen - x;
1313 /* now figure if the first edge is fully filling its tile */
1315 if ((p1 * tsize) == (x)) *x1_fill = 1;
1319 /* now figure if the last edge is fully filling its tile */
1320 p2 = (x + w - 1) / tsize;
1321 if (((p2 + 1) * tsize) == (x + w)) *x2_fill = 1;