forked from enlightenment/efl
Line, Polygon and minor fixes for software_16.
Line is a complete rewrite based on my university works. It's much cleaner than the engine/common and works better (the later is producing weird results, I still have to debug why), but I don't provide anti-aliased drawings. Polygon is almost the same code, with minor changes to draw the spans as soon as possible and then no malloc/free is required for each of them. Minor fixes to remove unused variables, gotos... SVN revision: 32161
This commit is contained in:
parent
06e02b3f6b
commit
e12c298619
|
@ -17,7 +17,9 @@ evas_soft16_main.c \
|
|||
evas_soft16_image_unscaled.c \
|
||||
evas_soft16_image_scaled_sampled.c \
|
||||
evas_soft16_font.c \
|
||||
evas_soft16_rectangle.c
|
||||
evas_soft16_rectangle.c \
|
||||
evas_soft16_polygon.c \
|
||||
evas_soft16_line.c
|
||||
|
||||
module_la_LIBADD = $(top_builddir)/src/lib/libevas.la
|
||||
module_la_LDFLAGS = @create_shared_lib@ -module -avoid-version -L$(top_builddir)/src/lib -L$(top_builddir)/src/lib/.libs
|
||||
|
@ -34,6 +36,8 @@ evas_soft16_image_unscaled.c \
|
|||
evas_soft16_image_scaled_sampled.c \
|
||||
evas_soft16_font.c \
|
||||
evas_soft16_rectangle.c \
|
||||
evas_soft16_polygon.c \
|
||||
evas_soft16_line.c \
|
||||
evas_soft16_scanline_fill.c \
|
||||
evas_soft16_scanline_blend.c
|
||||
|
||||
|
|
|
@ -148,39 +148,31 @@ eng_context_render_op_get(void *data, void *context)
|
|||
static void
|
||||
eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h)
|
||||
{
|
||||
soft16_rectangle_draw(surface, context, x, y, w, h);
|
||||
soft16_rectangle_draw(surface, context, x, y, w, h);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
NOT_IMPLEMENTED();
|
||||
// evas_common_line_draw(surface, context, x1, y1, x2, y2);
|
||||
// evas_common_cpu_end_opt();
|
||||
soft16_line_draw(surface, context, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_polygon_point_add(void *data, void *context, void *polygon, int x, int y)
|
||||
{
|
||||
NOT_IMPLEMENTED();
|
||||
return NULL;
|
||||
// return evas_common_polygon_point_add(polygon, x, y);
|
||||
return evas_common_polygon_point_add(polygon, x, y);
|
||||
}
|
||||
|
||||
static void *
|
||||
eng_polygon_points_clear(void *data, void *context, void *polygon)
|
||||
{
|
||||
NOT_IMPLEMENTED();
|
||||
return NULL;
|
||||
// return evas_common_polygon_points_clear(polygon);
|
||||
return evas_common_polygon_points_clear(polygon);
|
||||
}
|
||||
|
||||
static void
|
||||
eng_polygon_draw(void *data, void *context, void *surface, void *polygon)
|
||||
{
|
||||
NOT_IMPLEMENTED();
|
||||
// evas_common_polygon_draw(surface, context, polygon);
|
||||
// evas_common_cpu_end_opt();
|
||||
soft16_polygon_draw(surface, context, polygon);
|
||||
}
|
||||
|
||||
static void *
|
||||
|
|
|
@ -105,6 +105,18 @@ void soft16_image_convert_from_rgba(Soft16_Image *im, const DATA32 *src);
|
|||
*/
|
||||
void soft16_rectangle_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
|
||||
|
||||
/**
|
||||
* Polygon (evas_soft16_polygon.c)
|
||||
*/
|
||||
void
|
||||
soft16_polygon_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points);
|
||||
|
||||
/**
|
||||
* Line (evas_soft16_line.c)
|
||||
*/
|
||||
void
|
||||
soft16_line_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1);
|
||||
|
||||
|
||||
/**
|
||||
* Font (evas_soft16_font.c)
|
||||
|
|
|
@ -283,7 +283,7 @@ soft16_image_convert_from_rgb(Soft16_Image *im, const DATA32 *src)
|
|||
{
|
||||
const DATA32 *sp;
|
||||
DATA16 *dp;
|
||||
int x, y, pad;
|
||||
int y, pad;
|
||||
|
||||
sp = src;
|
||||
dp = im->pixels;
|
||||
|
|
|
@ -0,0 +1,444 @@
|
|||
#include "evas_soft16.h"
|
||||
#include "evas_soft16_scanline_fill.c"
|
||||
|
||||
/*
|
||||
* All functions except by soft16_line_draw() expect x0 <= x1.
|
||||
*/
|
||||
|
||||
static inline int
|
||||
_in_range(int value, int min, int max)
|
||||
{
|
||||
return min <= value && value <= max;
|
||||
}
|
||||
|
||||
static inline int
|
||||
_is_xy_inside_clip(int x, int y, const struct RGBA_Draw_Context_clip clip)
|
||||
{
|
||||
if (!clip.use)
|
||||
return 1;
|
||||
|
||||
if (!_in_range(x, clip.x, clip.x + clip.w - 1))
|
||||
return 0;
|
||||
|
||||
if (!_in_range(y, clip.y, clip.y + clip.h - 1))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
_is_x_inside_clip(int x, const struct RGBA_Draw_Context_clip clip)
|
||||
{
|
||||
if (!clip.use)
|
||||
return 1;
|
||||
|
||||
return _in_range(x, clip.x, clip.x + clip.w - 1);
|
||||
}
|
||||
|
||||
static inline int
|
||||
_is_y_inside_clip(int y, const struct RGBA_Draw_Context_clip clip)
|
||||
{
|
||||
if (!clip.use)
|
||||
return 1;
|
||||
|
||||
return _in_range(y, clip.y, clip.y + clip.h - 1);
|
||||
}
|
||||
|
||||
static inline int
|
||||
_is_xy_inside_rect(int x, int y, int w, int h)
|
||||
{
|
||||
return _in_range(x, 0, w - 1) && _in_range(y, 0, h - 1);
|
||||
}
|
||||
|
||||
static inline int
|
||||
_is_empty_clip(const struct RGBA_Draw_Context_clip clip)
|
||||
{
|
||||
return clip.w < 1 || clip.h < 1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_soft16_line_point(Soft16_Image *dst, RGBA_Draw_Context *dc, int x, int y)
|
||||
{
|
||||
DATA16 rgb565, *dst_itr;
|
||||
DATA8 alpha;
|
||||
|
||||
if (!_is_xy_inside_rect(x, y, dst->w, dst->h))
|
||||
return;
|
||||
|
||||
if (!_is_xy_inside_clip(x, y, dc->clip))
|
||||
return;
|
||||
|
||||
dst_itr = dst->pixels + (dst->stride * y) + x;
|
||||
alpha = A_VAL(&dc->col.col) >> 3;
|
||||
rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
|
||||
G_VAL(&dc->col.col),
|
||||
B_VAL(&dc->col.col));
|
||||
|
||||
if (alpha == 31)
|
||||
_soft16_pt_fill_solid_solid(dst_itr, rgb565);
|
||||
else if (alpha > 0)
|
||||
{
|
||||
DATA32 rgb565_unpack;
|
||||
|
||||
rgb565_unpack = RGB_565_UNPACK(rgb565);
|
||||
alpha++;
|
||||
_soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_soft16_line_horiz(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int x1, int y)
|
||||
{
|
||||
DATA16 rgb565, *dst_itr;
|
||||
DATA8 alpha;
|
||||
int w;
|
||||
|
||||
if (!_is_y_inside_clip(y, dc->clip))
|
||||
return;
|
||||
|
||||
if (x0 < dc->clip.x)
|
||||
x0 = dc->clip.x;
|
||||
|
||||
if (x1 >= dc->clip.x + dc->clip.w)
|
||||
x1 = dc->clip.x + dc->clip.w - 1;
|
||||
|
||||
w = x1 - x0;
|
||||
if (w < 1)
|
||||
return;
|
||||
|
||||
dst_itr = dst->pixels + (dst->stride * y) + x0;
|
||||
alpha = A_VAL(&dc->col.col) >> 3;
|
||||
rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
|
||||
G_VAL(&dc->col.col),
|
||||
B_VAL(&dc->col.col));
|
||||
|
||||
if (alpha == 31)
|
||||
_soft16_scanline_fill_solid_solid(dst_itr, w, rgb565);
|
||||
else if (alpha > 0)
|
||||
{
|
||||
DATA32 rgb565_unpack;
|
||||
|
||||
rgb565_unpack = RGB_565_UNPACK(rgb565);
|
||||
alpha++;
|
||||
_soft16_scanline_fill_transp_solid(dst_itr, w, rgb565_unpack, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_soft16_line_vert(Soft16_Image *dst, RGBA_Draw_Context *dc, int x, int y0, int y1)
|
||||
{
|
||||
DATA16 rgb565, *dst_itr;
|
||||
DATA8 alpha;
|
||||
int h;
|
||||
|
||||
if (!_is_x_inside_clip(x, dc->clip))
|
||||
return;
|
||||
|
||||
if (y1 < y0)
|
||||
{
|
||||
int t;
|
||||
t = y0;
|
||||
y0 = y1;
|
||||
y1 = t;
|
||||
}
|
||||
|
||||
if (y0 < dc->clip.y)
|
||||
y0 = dc->clip.y;
|
||||
|
||||
if (y1 >= dc->clip.y + dc->clip.h)
|
||||
y1 = dc->clip.y + dc->clip.h - 1;
|
||||
|
||||
h = y1 - y0;
|
||||
if (h < 1)
|
||||
return;
|
||||
|
||||
dst_itr = dst->pixels + (dst->stride * y0) + x;
|
||||
alpha = A_VAL(&dc->col.col) >> 3;
|
||||
rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
|
||||
G_VAL(&dc->col.col),
|
||||
B_VAL(&dc->col.col));
|
||||
|
||||
if (alpha == 31)
|
||||
{
|
||||
for (; h > 0; h--, dst_itr += dst->stride)
|
||||
_soft16_pt_fill_solid_solid(dst_itr, rgb565);
|
||||
}
|
||||
else if (alpha > 0)
|
||||
{
|
||||
DATA32 rgb565_unpack;
|
||||
|
||||
rgb565_unpack = RGB_565_UNPACK(rgb565);
|
||||
alpha++;
|
||||
|
||||
for (; h > 0; h--, dst_itr += dst->stride)
|
||||
_soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_soft16_line_45deg_adjust_boundaries(const struct RGBA_Draw_Context_clip clip, int *p_x0, int *p_y0, int *p_x1, int *p_y1)
|
||||
{
|
||||
int diff, dy, x0, y0, x1, y1;
|
||||
|
||||
x0 = *p_x0;
|
||||
y0 = *p_y0;
|
||||
x1 = *p_x1;
|
||||
y1 = *p_y1;
|
||||
|
||||
dy = y1 - y0;
|
||||
|
||||
diff = clip.x - x0;
|
||||
if (diff > 0)
|
||||
{
|
||||
x0 = clip.x;
|
||||
y0 += (dy > 0) ? diff : -diff;
|
||||
}
|
||||
|
||||
diff = x1 - (clip.x + clip.w);
|
||||
if (diff > 0)
|
||||
{
|
||||
x1 = clip.x + clip.w;
|
||||
y1 += (dy > 0) ? -diff : diff;
|
||||
}
|
||||
|
||||
if (dy > 0)
|
||||
{
|
||||
diff = clip.y - y0;
|
||||
if (diff > 0)
|
||||
{
|
||||
y0 = clip.y;
|
||||
x0 += diff;
|
||||
}
|
||||
|
||||
diff = y1 - (clip.y + clip.h);
|
||||
if (diff > 0)
|
||||
{
|
||||
y1 = clip.y + clip.h;
|
||||
x1 -= diff;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
diff = clip.y - y1;
|
||||
if (diff > 0)
|
||||
{
|
||||
y1 = clip.y;
|
||||
x1 -= diff;
|
||||
}
|
||||
|
||||
diff = y0 - (clip.y + clip.h - 1);
|
||||
if (diff > 0)
|
||||
{
|
||||
y0 = clip.y + clip.h - 1;
|
||||
x0 += diff;
|
||||
}
|
||||
}
|
||||
|
||||
*p_x0 = x0;
|
||||
*p_y0 = y0;
|
||||
*p_x1 = x1;
|
||||
*p_y1 = y1;
|
||||
}
|
||||
|
||||
static void
|
||||
_soft16_line_45deg(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1)
|
||||
{
|
||||
int dy, step_dst_itr, len;
|
||||
DATA8 alpha;
|
||||
DATA16 *dst_itr, rgb565;
|
||||
|
||||
alpha = A_VAL(&dc->col.col) >> 3;
|
||||
if (alpha < 1)
|
||||
return;
|
||||
|
||||
rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
|
||||
G_VAL(&dc->col.col),
|
||||
B_VAL(&dc->col.col));
|
||||
|
||||
dy = y1 - y0;
|
||||
step_dst_itr = 1 + ((dy > 0) ? dst->stride : -dst->stride);
|
||||
|
||||
_soft16_line_45deg_adjust_boundaries(dc->clip, &x0, &y0, &x1, &y1);
|
||||
|
||||
len = (dy > 0) ? (y1 - y0) : (y0 - y1);
|
||||
if (len < 1)
|
||||
return;
|
||||
|
||||
dst_itr = dst->pixels + dst->stride * y0 + x0;
|
||||
if (alpha == 31)
|
||||
{
|
||||
for (; len > 0; len--, dst_itr += step_dst_itr)
|
||||
_soft16_pt_fill_solid_solid(dst_itr, rgb565);
|
||||
}
|
||||
else
|
||||
{
|
||||
DATA32 rgb565_unpack;
|
||||
|
||||
rgb565_unpack = RGB_565_UNPACK(rgb565);
|
||||
alpha++;
|
||||
for (; len > 0; len--, dst_itr += step_dst_itr)
|
||||
_soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_soft16_line_aliased_pt(DATA16 *dst_itr, DATA16 rgb565, DATA32 rgb565_unpack, DATA8 alpha)
|
||||
{
|
||||
if (alpha == 32)
|
||||
_soft16_pt_fill_solid_solid(dst_itr, rgb565);
|
||||
else
|
||||
_soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_soft16_line_aliased(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1)
|
||||
{
|
||||
int dx, dy, step_y, step_dst_itr;
|
||||
DATA32 rgb565_unpack;
|
||||
DATA16 rgb565;
|
||||
DATA8 alpha;
|
||||
|
||||
alpha = A_VAL(&dc->col.col) >> 3;
|
||||
if (alpha == 0)
|
||||
return;
|
||||
alpha++;
|
||||
|
||||
rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
|
||||
G_VAL(&dc->col.col),
|
||||
B_VAL(&dc->col.col));
|
||||
rgb565_unpack = RGB_565_UNPACK(rgb565);
|
||||
|
||||
dx = x1 - x0;
|
||||
dy = y1 - y0;
|
||||
|
||||
if (dy >= 0)
|
||||
{
|
||||
step_y = 1;
|
||||
step_dst_itr = dst->stride;
|
||||
}
|
||||
else
|
||||
{
|
||||
dy = -dy;
|
||||
step_y = -1;
|
||||
step_dst_itr = -dst->stride;
|
||||
}
|
||||
|
||||
if (dx > dy)
|
||||
{
|
||||
DATA16 *dst_itr;
|
||||
int e, x, y;
|
||||
|
||||
e = - (dx / 2);
|
||||
y = y0;
|
||||
dst_itr = dst->pixels + dst->stride * y0 + x0;
|
||||
for (x=x0; x <= x1; x++, dst_itr++)
|
||||
{
|
||||
if (_is_xy_inside_clip(x, y, dc->clip))
|
||||
_soft16_line_aliased_pt(dst_itr, rgb565, rgb565_unpack, alpha);
|
||||
|
||||
e += dy;
|
||||
if (e >= 0)
|
||||
{
|
||||
dst_itr += step_dst_itr;
|
||||
y += step_y;
|
||||
e -= dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DATA16 *dst_itr;
|
||||
int e, x, y;
|
||||
|
||||
e = - (dy / 2);
|
||||
x = x0;
|
||||
dst_itr = dst->pixels + dst->stride * y0 + x0;
|
||||
for (y=y0; y != y1; y += step_y, dst_itr += step_dst_itr)
|
||||
{
|
||||
if (_is_xy_inside_clip(x, y, dc->clip))
|
||||
_soft16_line_aliased_pt(dst_itr, rgb565, rgb565_unpack, alpha);
|
||||
|
||||
e += dx;
|
||||
if (e >= 0)
|
||||
{
|
||||
dst_itr++;
|
||||
x++;
|
||||
e -= dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
soft16_line_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1)
|
||||
{
|
||||
struct RGBA_Draw_Context_clip c_bkp, c_tmp;
|
||||
int dx, dy;
|
||||
int x, y, w, h;
|
||||
|
||||
c_tmp.use = 1;
|
||||
c_tmp.x = 0;
|
||||
c_tmp.y = 0;
|
||||
c_tmp.w = dst->w;
|
||||
c_tmp.h = dst->h;
|
||||
|
||||
/* save out clip info */
|
||||
c_bkp = dc->clip;
|
||||
if (c_bkp.use)
|
||||
{
|
||||
RECTS_CLIP_TO_RECT(c_tmp.x, c_tmp.y, c_tmp.w, c_tmp.h,
|
||||
c_bkp.x, c_bkp.y, c_bkp.w, c_bkp.h);
|
||||
if (_is_empty_clip(c_tmp))
|
||||
return;
|
||||
}
|
||||
|
||||
x = MIN(x0, x1);
|
||||
y = MIN(y0, y1);
|
||||
w = MAX(x0, x1) - x + 1;
|
||||
h = MAX(y0, y1) - y + 1;
|
||||
|
||||
RECTS_CLIP_TO_RECT(c_tmp.x, c_tmp.y, c_tmp.w, c_tmp.h, x, y, w, h);
|
||||
if (_is_empty_clip(c_tmp))
|
||||
return;
|
||||
|
||||
/* Check if the line doesn't cross the clip area */
|
||||
if (x0 < c_tmp.x && x1 < c_tmp.x)
|
||||
return;
|
||||
if (x0 >= c_tmp.x + c_tmp.w && x1 >= c_tmp.x + c_tmp.w)
|
||||
return;
|
||||
if (y0 < c_tmp.y && y1 < c_tmp.y)
|
||||
return;
|
||||
if (y0 >= c_tmp.y + c_tmp.h && y1 >= c_tmp.y + c_tmp.h)
|
||||
return;
|
||||
|
||||
dc->clip = c_tmp;
|
||||
dx = x1 - x0;
|
||||
dy = y1 - y0;
|
||||
|
||||
if (dx < 0)
|
||||
{
|
||||
int t;
|
||||
|
||||
t = x0;
|
||||
x0 = x1;
|
||||
x1 = t;
|
||||
|
||||
t = y0;
|
||||
y0 = y1;
|
||||
y1 = y0;
|
||||
}
|
||||
|
||||
if (dx == 0 && dy == 0)
|
||||
_soft16_line_point(dst, dc, x0, y0);
|
||||
else if (dx == 0)
|
||||
_soft16_line_vert(dst, dc, x0, y0, y1);
|
||||
else if (dy == 0)
|
||||
_soft16_line_horiz(dst, dc, x0, x1, y0);
|
||||
else if (dy == dx || dy == -dx)
|
||||
_soft16_line_45deg(dst, dc, x0, y0, x1, y1);
|
||||
else
|
||||
_soft16_line_aliased(dst, dc, x0, y0, x1, y1);
|
||||
|
||||
/* restore clip info */
|
||||
dc->clip = c_bkp;
|
||||
}
|
|
@ -230,7 +230,6 @@ soft16_image_load_data(Soft16_Image *im)
|
|||
if (!im->pixels) soft16_image_alloc_pixels(im);
|
||||
if (im->pixels) _soft16_image_rgba32_import(im, im->source_im->image->data);
|
||||
}
|
||||
done:
|
||||
evas_cache_image_drop(im->source_im);
|
||||
im->source_im = NULL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
#include <evas_soft16.h>
|
||||
#include "evas_soft16_scanline_fill.c"
|
||||
#include <math.h>
|
||||
|
||||
typedef struct _RGBA_Edge RGBA_Edge;
|
||||
typedef struct _RGBA_Vertex RGBA_Vertex;
|
||||
|
||||
struct _RGBA_Edge
|
||||
{
|
||||
float x, dx;
|
||||
int i;
|
||||
};
|
||||
|
||||
struct _RGBA_Vertex
|
||||
{
|
||||
float x, y;
|
||||
int i;
|
||||
};
|
||||
|
||||
#define POLY_EDGE_DEL(_i) \
|
||||
{ \
|
||||
int _j; \
|
||||
\
|
||||
for (_j = 0; (_j < num_active_edges) && (edges[_j].i != _i); _j++); \
|
||||
if (_j < num_active_edges) \
|
||||
{ \
|
||||
num_active_edges--; \
|
||||
memmove(&(edges[_j]), &(edges[_j + 1]), \
|
||||
(num_active_edges - _j) * sizeof(RGBA_Edge)); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define POLY_EDGE_ADD(_i, _y) \
|
||||
{ \
|
||||
int _j; \
|
||||
float _dx; \
|
||||
RGBA_Vertex *_p, *_q; \
|
||||
if (_i < (n - 1)) _j = _i + 1; \
|
||||
else _j = 0; \
|
||||
if (point[_i].y < point[_j].y) \
|
||||
{ \
|
||||
_p = &(point[_i]); \
|
||||
_q = &(point[_j]); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_p = &(point[_j]); \
|
||||
_q = &(point[_i]); \
|
||||
} \
|
||||
edges[num_active_edges].dx = _dx = (_q->x - _p->x) / (_q->y - _p->y); \
|
||||
edges[num_active_edges].x = (_dx * ((float)_y + 0.5 - _p->y)) + _p->x; \
|
||||
edges[num_active_edges].i = _i; \
|
||||
num_active_edges++; \
|
||||
}
|
||||
|
||||
static int
|
||||
polygon_point_sorter(const void *a, const void *b)
|
||||
{
|
||||
RGBA_Vertex *p, *q;
|
||||
|
||||
p = (RGBA_Vertex *)a;
|
||||
q = (RGBA_Vertex *)b;
|
||||
if (p->y <= q->y) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
polygon_edge_sorter(const void *a, const void *b)
|
||||
{
|
||||
RGBA_Edge *p, *q;
|
||||
|
||||
p = (RGBA_Edge *)a;
|
||||
q = (RGBA_Edge *)b;
|
||||
if (p->x <= q->x) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
soft16_polygon_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points)
|
||||
{
|
||||
RGBA_Polygon_Point *pt;
|
||||
RGBA_Vertex *point;
|
||||
RGBA_Edge *edges;
|
||||
Evas_Object_List *l;
|
||||
int num_active_edges;
|
||||
int n;
|
||||
int i, j, k;
|
||||
int y0, y1, y;
|
||||
int ext_x, ext_y, ext_w, ext_h;
|
||||
int *sorted_index;
|
||||
DATA8 alpha;
|
||||
DATA16 rgb565;
|
||||
DATA32 rgb565_unpack;
|
||||
|
||||
alpha = A_VAL(&dc->col.col) >> 3;
|
||||
if (alpha == 0)
|
||||
return;
|
||||
alpha++;
|
||||
|
||||
rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
|
||||
G_VAL(&dc->col.col),
|
||||
B_VAL(&dc->col.col));
|
||||
rgb565_unpack = RGB_565_UNPACK(rgb565);
|
||||
|
||||
ext_x = 0;
|
||||
ext_y = 0;
|
||||
ext_w = dst->w;
|
||||
ext_h = dst->h;
|
||||
if (dc->clip.use)
|
||||
RECTS_CLIP_TO_RECT(ext_x, ext_y, ext_w, ext_h,
|
||||
dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
|
||||
|
||||
if ((ext_w <= 0) || (ext_h <= 0))
|
||||
return;
|
||||
|
||||
n = 0;
|
||||
for (l = (Evas_Object_List *)points; l; l = l->next)
|
||||
n++;
|
||||
|
||||
if (n < 3)
|
||||
return;
|
||||
|
||||
edges = malloc(sizeof(RGBA_Edge) * n);
|
||||
if (!edges)
|
||||
return;
|
||||
|
||||
point = malloc(sizeof(RGBA_Vertex) * n);
|
||||
if (!point)
|
||||
{
|
||||
free(edges);
|
||||
return;
|
||||
}
|
||||
|
||||
sorted_index = malloc(sizeof(int) * n);
|
||||
if (!sorted_index)
|
||||
{
|
||||
free(edges);
|
||||
free(point);
|
||||
return;
|
||||
}
|
||||
|
||||
for (k = 0, l = (Evas_Object_List *)points; l; k++, l = l->next)
|
||||
{
|
||||
pt = (RGBA_Polygon_Point *)l;
|
||||
point[k].x = pt->x;
|
||||
point[k].y = pt->y;
|
||||
point[k].i = k;
|
||||
}
|
||||
qsort(point, n, sizeof(RGBA_Vertex), polygon_point_sorter);
|
||||
|
||||
for (k = 0; k < n; k++)
|
||||
sorted_index[k] = point[k].i;
|
||||
|
||||
for (k = 0, l = (Evas_Object_List *)points; l; k++, l = l->next)
|
||||
{
|
||||
pt = (RGBA_Polygon_Point *)l;
|
||||
point[k].x = pt->x;
|
||||
point[k].y = pt->y;
|
||||
point[k].i = k;
|
||||
}
|
||||
|
||||
y0 = MAX(ext_y, ceil(point[sorted_index[0]].y - 0.5));
|
||||
y1 = MIN(ext_y + ext_h - 1, floor(point[sorted_index[n - 1]].y - 0.5));
|
||||
|
||||
k = 0;
|
||||
num_active_edges = 0;
|
||||
|
||||
for (y = y0; y <= y1; y++)
|
||||
{
|
||||
for (; (k < n) && (point[sorted_index[k]].y <= ((float)y + 0.5)); k++)
|
||||
{
|
||||
i = sorted_index[k];
|
||||
|
||||
if (i > 0) j = i - 1;
|
||||
else j = n - 1;
|
||||
if (point[j].y <= ((float)y - 0.5))
|
||||
{
|
||||
POLY_EDGE_DEL(j)
|
||||
}
|
||||
else if (point[j].y > ((float)y + 0.5))
|
||||
{
|
||||
POLY_EDGE_ADD(j, y)
|
||||
}
|
||||
if (i < (n - 1)) j = i + 1;
|
||||
else j = 0;
|
||||
if (point[j].y <= ((float)y - 0.5))
|
||||
{
|
||||
POLY_EDGE_DEL(i)
|
||||
}
|
||||
else if (point[j].y > ((float)y + 0.5))
|
||||
{
|
||||
POLY_EDGE_ADD(i, y)
|
||||
}
|
||||
}
|
||||
|
||||
qsort(edges, num_active_edges, sizeof(RGBA_Edge), polygon_edge_sorter);
|
||||
|
||||
for (j = 0; j < num_active_edges; j += 2)
|
||||
{
|
||||
int x0, x1;
|
||||
|
||||
x0 = ceil(edges[j].x - 0.5);
|
||||
if (j < (num_active_edges - 1))
|
||||
x1 = floor(edges[j + 1].x - 0.5);
|
||||
else
|
||||
x1 = x0;
|
||||
if ((x1 >= ext_x) && (x0 < (ext_x + ext_w)) && (x0 <= x1))
|
||||
{
|
||||
DATA16 *dst_itr;
|
||||
int w;
|
||||
|
||||
if (x0 < ext_x) x0 = ext_x;
|
||||
if (x1 >= (ext_x + ext_w)) x1 = ext_x + ext_w - 1;
|
||||
|
||||
w = (x1 - x0) + 1;
|
||||
dst_itr = dst->pixels + (y * dst->stride) + x0;
|
||||
|
||||
if (alpha == 32)
|
||||
_soft16_scanline_fill_solid_solid(dst_itr, w, rgb565);
|
||||
else
|
||||
_soft16_scanline_fill_transp_solid(dst_itr, w, rgb565_unpack, alpha);
|
||||
}
|
||||
edges[j].x += edges[j].dx;
|
||||
edges[j + 1].x += edges[j + 1].dx;
|
||||
}
|
||||
}
|
||||
|
||||
free(edges);
|
||||
free(point);
|
||||
free(sorted_index);
|
||||
}
|
|
@ -8,45 +8,32 @@ _is_empty_rectangle(const Evas_Rectangle *r)
|
|||
}
|
||||
|
||||
static inline void
|
||||
_soft16_rectangle_draw_solid_solid(Soft16_Image *dst, RGBA_Draw_Context *dc,
|
||||
int offset, int w, int h)
|
||||
_soft16_rectangle_draw_solid_solid(Soft16_Image *dst, int offset, int w, int h,
|
||||
DATA16 rgb565)
|
||||
{
|
||||
DATA16 *dst_itr, rgb565;
|
||||
DATA16 *dst_itr;
|
||||
int i;
|
||||
|
||||
dst_itr = dst->pixels + offset;
|
||||
rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
|
||||
G_VAL(&dc->col.col),
|
||||
B_VAL(&dc->col.col));
|
||||
|
||||
for (i = 0; i < h; i++, dst_itr += dst->stride)
|
||||
_soft16_scanline_fill_solid_solid(dst_itr, w, rgb565);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_soft16_rectangle_draw_transp_solid(Soft16_Image *dst, RGBA_Draw_Context *dc,
|
||||
int offset, int w, int h)
|
||||
_soft16_rectangle_draw_transp_solid(Soft16_Image *dst, int offset, int w, int h,
|
||||
DATA16 rgb565, DATA8 alpha)
|
||||
{
|
||||
char alpha;
|
||||
DATA16 *dst_itr;
|
||||
DATA32 rgb565_unpack;
|
||||
int i;
|
||||
|
||||
alpha = A_VAL(&dc->col.col) >> 3;
|
||||
if (alpha == 31) _soft16_rectangle_draw_solid_solid(dst, dc, offset, w, h);
|
||||
else if (alpha != 0)
|
||||
{
|
||||
DATA16 *dst_itr;
|
||||
DATA32 rgb565;
|
||||
int i;
|
||||
dst_itr = dst->pixels + offset;
|
||||
rgb565_unpack = RGB_565_UNPACK(rgb565);
|
||||
alpha++;
|
||||
|
||||
dst_itr = dst->pixels + offset;
|
||||
rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
|
||||
G_VAL(&dc->col.col),
|
||||
B_VAL(&dc->col.col));
|
||||
rgb565 = RGB_565_UNPACK(rgb565);
|
||||
alpha++;
|
||||
|
||||
for (i = 0; i < h; i++, dst_itr += dst->stride)
|
||||
_soft16_scanline_fill_transp_solid(dst_itr, w, rgb565, alpha);
|
||||
}
|
||||
for (i = 0; i < h; i++, dst_itr += dst->stride)
|
||||
_soft16_scanline_fill_transp_solid(dst_itr, w, rgb565_unpack, alpha);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -69,12 +56,19 @@ _soft16_rectangle_draw_int(Soft16_Image *dst, RGBA_Draw_Context *dc,
|
|||
|
||||
if (!dst->have_alpha)
|
||||
{
|
||||
if (A_VAL(&dc->col.col) == 255)
|
||||
_soft16_rectangle_draw_solid_solid
|
||||
(dst, dc, dst_offset, dr.w, dr.h);
|
||||
else
|
||||
_soft16_rectangle_draw_transp_solid
|
||||
(dst, dc, dst_offset, dr.w, dr.h);
|
||||
DATA16 rgb565;
|
||||
DATA8 alpha;
|
||||
|
||||
alpha = A_VAL(&dc->col.col) >> 3;
|
||||
rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
|
||||
G_VAL(&dc->col.col),
|
||||
B_VAL(&dc->col.col));
|
||||
if (alpha == 31)
|
||||
_soft16_rectangle_draw_solid_solid
|
||||
(dst, dst_offset, dr.w, dr.h, rgb565);
|
||||
else if (alpha > 0)
|
||||
_soft16_rectangle_draw_transp_solid
|
||||
(dst, dst_offset, dr.w, dr.h, rgb565, alpha);
|
||||
}
|
||||
else
|
||||
fprintf(stderr,
|
||||
|
|
|
@ -19,8 +19,6 @@ _soft16_pt_blend_transp_solid(DATA16 *p_dst, DATA16 src, DATA8 alpha)
|
|||
{
|
||||
DATA32 a, b;
|
||||
|
||||
DATA32 dst = *p_dst;
|
||||
|
||||
a = RGB_565_UNPACK(src);
|
||||
b = RGB_565_UNPACK(*p_dst);
|
||||
b = RGB_565_UNPACKED_BLEND(a, b, alpha);
|
||||
|
|
|
@ -58,7 +58,6 @@ static inline void
|
|||
_soft16_scanline_fill_transp_solid(DATA16 *dst, int size, DATA32 rgb565_unpack, DATA8 alpha)
|
||||
{
|
||||
DATA16 *start, *end;
|
||||
DATA32 a;
|
||||
|
||||
start = dst;
|
||||
pld(start, 0);
|
||||
|
|
Loading…
Reference in New Issue