move around - flatter.
[profile/ivi/evas.git] / src / lib / engines / common_16 / evas_soft16_rectangle.c
1 #include "evas_common_soft16.h"
2 #include "evas_soft16_scanline_fill.c"
3
4 static inline int
5 _is_empty_rectangle(const Evas_Rectangle *r)
6 {
7    return (r->w < 1) || (r->h < 1);
8 }
9
10 static inline void
11 _soft16_rectangle_draw_solid_solid(Soft16_Image *dst, int offset, int w, int h,
12                                    DATA16 rgb565)
13 {
14    DATA16 *dst_itr;
15    int i;
16
17    dst_itr = dst->pixels + offset;
18
19    for (i = 0; i < h; i++, dst_itr += dst->stride)
20       _soft16_scanline_fill_solid_solid(dst_itr, w, rgb565);
21 }
22
23 static inline void
24 _soft16_rectangle_draw_transp_solid(Soft16_Image *dst, int offset, int w, int h,
25                                     DATA16 rgb565, DATA8 alpha)
26 {
27    DATA16 *dst_itr;
28    DATA32 rgb565_unpack;
29    int i;
30
31    dst_itr = dst->pixels + offset;
32    rgb565_unpack = RGB_565_UNPACK(rgb565);
33    alpha++;
34
35    for (i = 0; i < h; i++, dst_itr += dst->stride)
36      _soft16_scanline_fill_transp_solid(dst_itr, w, rgb565_unpack, alpha);
37 }
38
39 static void
40 _soft16_rectangle_draw_int(Soft16_Image *dst, RGBA_Draw_Context *dc,
41                            Evas_Rectangle dr)
42 {
43    int dst_offset;
44
45    if (_is_empty_rectangle(&dr)) return;
46    RECTS_CLIP_TO_RECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
47    if (_is_empty_rectangle(&dr)) return;
48
49    if (dc->clip.use)
50       RECTS_CLIP_TO_RECT(dr.x, dr.y, dr.w, dr.h, dc->clip.x,
51                          dc->clip.y, dc->clip.w, dc->clip.h);
52    if (_is_empty_rectangle(&dr)) return;
53    if (A_VAL(&dc->col.col) == 0) return;
54
55    dst_offset = dr.x + (dr.y * dst->cache_entry.w);
56
57    if (!dst->cache_entry.flags.alpha)
58       {
59          DATA16 rgb565;
60          DATA8 alpha;
61
62          alpha = A_VAL(&dc->col.col) >> 3;
63          rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
64                                           G_VAL(&dc->col.col),
65                                           B_VAL(&dc->col.col));
66          if (alpha == 31)
67            _soft16_rectangle_draw_solid_solid
68              (dst, dst_offset, dr.w, dr.h, rgb565);
69          else if (alpha > 0)
70            _soft16_rectangle_draw_transp_solid
71              (dst, dst_offset, dr.w, dr.h, rgb565, alpha);
72       }
73    else
74       fprintf(stderr,
75               "Unsupported feature: drawing rectangle to non-opaque "
76               "destination.\n");
77 }
78
79 void
80 soft16_rectangle_draw(Soft16_Image *dst, RGBA_Draw_Context *dc,
81                       int x, int y, int w, int h)
82 {
83    Evas_Rectangle dr;
84    Cutout_Rects *rects;
85    Cutout_Rect  *r;
86    struct RGBA_Draw_Context_clip c_bkp;
87    int i;
88
89    /* handle cutouts here! */
90    dr.x = x;
91    dr.y = y;
92    dr.w = w;
93    dr.h = h;
94
95    if (_is_empty_rectangle(&dr)) return;
96    if (!(RECTS_INTERSECT(dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
97      return;
98
99    /* no cutouts - cut right to the chase */
100    if (!dc->cutout.rects)
101      {
102         _soft16_rectangle_draw_int(dst, dc, dr);
103         return;
104      }
105
106    c_bkp = dc->clip;
107
108    evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
109    evas_common_draw_context_clip_clip(dc, x, y, w, h);
110    /* our clip is 0 size.. abort */
111    if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
112      {
113         dc->clip = c_bkp;
114         return;
115      }
116    rects = evas_common_draw_context_apply_cutouts(dc);
117    for (i = 0; i < rects->active; ++i)
118      {
119         r = rects->rects + i;
120         evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
121         _soft16_rectangle_draw_int(dst, dc, dr);
122      }
123    evas_common_draw_context_apply_clear_cutouts(rects);
124    dc->clip = c_bkp;
125 }
126