remove ector software engine.
Change-Id: If28abc6060426a794d30d9415c84250f323dce09
#ifdef EFL_BETA_API_SUPPORT
-#include "software/ector_software_surface.eo.h"
#include "software/ector_software_buffer.eo.h"
#include "software/ector_software_buffer_base.eo.h"
-#include "software/ector_renderer_software.eo.h"
-#include "software/ector_renderer_software_shape.eo.h"
-#include "software/ector_renderer_software_image.eo.h"
-#include "software/ector_renderer_software_gradient_linear.eo.h"
-#include "software/ector_renderer_software_gradient_radial.eo.h"
#endif
+++ /dev/null
-abstract @beta Ector.Renderer.Software extends Ector.Renderer
-{
- [[Ector software renderer class]]
- data: null;
- methods {
- op_fill @pure_virtual {
- [[Renderer fill operation]]
- return: bool; [[$true on success, $false otherwise]]
- }
- }
-}
+++ /dev/null
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <Eina.h>
-#include <Ector.h>
-#include <software/Ector_Software.h>
-
-#include "ector_private.h"
-#include "ector_software_private.h"
-#include "ector_software_gradient.h"
-
-static Eina_Bool
-_ector_renderer_software_gradient_linear_ector_renderer_prepare(Eo *obj,
- Ector_Renderer_Software_Gradient_Data *pd)
-{
- pd->ctable_status = CTABLE_NOT_READY;
-
- if (!pd->surface)
- {
- Ector_Renderer_Data *base = efl_data_scope_get(obj, ECTOR_RENDERER_CLASS);
- pd->surface = efl_data_xref(base->surface, ECTOR_SOFTWARE_SURFACE_CLASS, obj);
- }
- ector_software_gradient_color_update(pd);
-
- pd->linear.x1 = pd->gld->start.x;
- pd->linear.y1 = pd->gld->start.y;
-
- pd->linear.x2 = pd->gld->end.x;
- pd->linear.y2 = pd->gld->end.y;
-
- pd->linear.dx = pd->linear.x2 - pd->linear.x1;
- pd->linear.dy = pd->linear.y2 - pd->linear.y1;
- pd->linear.l = pd->linear.dx * pd->linear.dx + pd->linear.dy * pd->linear.dy;
- pd->linear.off = 0;
-
- if (!EINA_DBL_EQ(pd->linear.l, 0.0))
- {
- pd->linear.dx /= pd->linear.l;
- pd->linear.dy /= pd->linear.l;
- pd->linear.off = -pd->linear.dx * pd->linear.x1 - pd->linear.dy * pd->linear.y1;
- }
-
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_ector_renderer_software_gradient_linear_ector_renderer_draw(Eo *obj EINA_UNUSED,
- Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
- Efl_Gfx_Render_Op op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
- unsigned int mul_col EINA_UNUSED)
-{
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_ector_renderer_software_gradient_linear_ector_renderer_software_op_fill(Eo *obj EINA_UNUSED,
- Ector_Renderer_Software_Gradient_Data *pd)
-{
- ector_software_rasterizer_linear_gradient_set(pd->surface->rasterizer, pd);
- ector_software_gradient_color_update(pd);
-
- return EINA_TRUE;
-}
-
-static Eo *
-_ector_renderer_software_gradient_linear_efl_object_constructor(Eo *obj,
- Ector_Renderer_Software_Gradient_Data *pd)
-{
- obj = efl_constructor(efl_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS));
- if (!obj) return NULL;
-
- pd->gd = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_MIXIN, obj);
- pd->gld = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_LINEAR_MIXIN, obj);
- pd->ctable_status = CTABLE_NOT_READY;
-
- return obj;
-}
-
-static void
-_ector_renderer_software_gradient_linear_efl_object_destructor(Eo *obj,
- Ector_Renderer_Software_Gradient_Data *pd)
-{
- Ector_Renderer_Data *base;
-
- destroy_color_table(pd);
-
- base = efl_data_scope_get(obj, ECTOR_RENDERER_CLASS);
- efl_data_xunref(base->surface, pd->surface, obj);
-
- efl_data_xunref(obj, pd->gd, obj);
- efl_data_xunref(obj, pd->gld, obj);
-
- efl_destructor(efl_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS));
-}
-
-void
-_ector_renderer_software_gradient_linear_efl_gfx_gradient_stop_set(Eo *obj, Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
- const Efl_Gfx_Gradient_Stop *colors, unsigned int length)
-{
- efl_gfx_gradient_stop_set(efl_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS), colors, length);
-}
-
-static unsigned int
-_ector_renderer_software_gradient_linear_ector_renderer_crc_get(const Eo *obj, Ector_Renderer_Software_Gradient_Data *pd)
-{
- unsigned int crc;
-
- crc = ector_renderer_crc_get(efl_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS));
-
- crc = eina_crc((void*) pd->gd->s, sizeof (Efl_Gfx_Gradient_Spread), crc, EINA_FALSE);
- if (pd->gd->colors_count)
- crc = eina_crc((void*) pd->gd->colors, sizeof (Efl_Gfx_Gradient_Stop) * pd->gd->colors_count, crc, EINA_FALSE);
- crc = eina_crc((void*) pd->gld, sizeof (Ector_Renderer_Gradient_Linear_Data), crc, EINA_FALSE);
-
- return crc;
-}
-
-#include "ector_renderer_software_gradient_linear.eo.c"
+++ /dev/null
-class @beta Ector.Renderer.Software.Gradient.Linear extends Ector.Renderer.Software implements Ector.Renderer.Gradient, Ector.Renderer.Gradient.Linear
-{
- [[Ector software renderer gradient linear class]]
- c_prefix: ector_renderer_software_gradient_linear;
- data: Ector_Renderer_Software_Gradient_Data;
- implements {
- Ector.Renderer.prepare;
- Ector.Renderer.draw;
- Ector.Renderer.crc { get; }
- Ector.Renderer.Software.op_fill;
- Efl.Object.constructor;
- Efl.Object.destructor;
- Efl.Gfx.Gradient.stop { set; }
- }
-}
+++ /dev/null
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <Eina.h>
-#include <Ector.h>
-#include <software/Ector_Software.h>
-
-#include "ector_private.h"
-#include "ector_software_private.h"
-#include "ector_software_gradient.h"
-
-static Eina_Bool
-_ector_renderer_software_gradient_radial_ector_renderer_prepare(Eo *obj, Ector_Renderer_Software_Gradient_Data *pd)
-{
- pd->ctable_status = CTABLE_NOT_READY;
-
- if (!pd->surface)
- {
- Ector_Renderer_Data *base = efl_data_scope_get(obj, ECTOR_RENDERER_CLASS);
- pd->surface = efl_data_xref(base->surface, ECTOR_SOFTWARE_SURFACE_CLASS, obj);
- }
-
- ector_software_gradient_color_update(pd);
-
- pd->radial.cx = pd->grd->radial.x;
- pd->radial.cy = pd->grd->radial.y;
- pd->radial.cradius = pd->grd->radius;
-
- if (EINA_DBL_EQ(pd->grd->focal.x, 0.0))
- pd->radial.fx = pd->grd->radial.x;
- else
- pd->radial.fx = pd->grd->focal.x;
-
- if (EINA_DBL_EQ(pd->grd->focal.y, 0.0))
- pd->radial.fy = pd->grd->radial.y;
- else
- pd->radial.fy = pd->grd->focal.y;
-
- pd->radial.fradius = 0;
-
- pd->radial.dx = pd->radial.cx - pd->radial.fx;
- pd->radial.dy = pd->radial.cy - pd->radial.fy;
-
- pd->radial.dr = pd->radial.cradius - pd->radial.fradius;
- pd->radial.sqrfr = pd->radial.fradius * pd->radial.fradius;
-
- pd->radial.a = pd->radial.dr * pd->radial.dr -
- pd->radial.dx * pd->radial.dx -
- pd->radial.dy * pd->radial.dy;
- pd->radial.inv2a = 1 / (2 * pd->radial.a);
-
- pd->radial.extended = (pd->radial.fradius >= 0.00001f) || pd->radial.a >= 0.00001f;
-
- return EINA_FALSE;
-}
-
-// Clearly duplicated and should be in a common place...
-static Eina_Bool
-_ector_renderer_software_gradient_radial_ector_renderer_draw(Eo *obj EINA_UNUSED,
- Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
- Efl_Gfx_Render_Op op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
- unsigned int mul_col EINA_UNUSED)
-{
- return EINA_TRUE;
-}
-
-// Clearly duplicated and should be in a common place...
-static Eina_Bool
-_ector_renderer_software_gradient_radial_ector_renderer_software_op_fill(Eo *obj EINA_UNUSED, Ector_Renderer_Software_Gradient_Data *pd)
-{
- ector_software_rasterizer_radial_gradient_set(pd->surface->rasterizer, pd);
- ector_software_gradient_color_update(pd);
-
- return EINA_TRUE;
-}
-
-Eo *
-_ector_renderer_software_gradient_radial_efl_object_constructor(Eo *obj,
- Ector_Renderer_Software_Gradient_Data *pd)
-{
- obj = efl_constructor(efl_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS));
- pd->gd = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_MIXIN, obj);
- pd->gld = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_RADIAL_MIXIN, obj);
- pd->ctable_status = CTABLE_NOT_READY;
-
- return obj;
-}
-
-void
-_ector_renderer_software_gradient_radial_efl_object_destructor(Eo *obj,
- Ector_Renderer_Software_Gradient_Data *pd)
-{
- Ector_Renderer_Data *base;
-
- destroy_color_table(pd);
-
- base = efl_data_scope_get(obj, ECTOR_RENDERER_CLASS);
- efl_data_xunref(base->surface, pd->surface, obj);
-
- efl_data_xunref(obj, pd->gd, obj);
- efl_data_xunref(obj, pd->gld, obj);
-
- efl_destructor(efl_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS));
-}
-
-void
-_ector_renderer_software_gradient_radial_efl_gfx_gradient_stop_set(Eo *obj, Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
- const Efl_Gfx_Gradient_Stop *colors, unsigned int length)
-{
- efl_gfx_gradient_stop_set(efl_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS), colors, length);
-}
-
-static unsigned int
-_ector_renderer_software_gradient_radial_ector_renderer_crc_get(const Eo *obj, Ector_Renderer_Software_Gradient_Data *pd)
-{
- unsigned int crc;
-
- crc = ector_renderer_crc_get(efl_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS));
-
- crc = eina_crc((void*) pd->gd->s, sizeof (Efl_Gfx_Gradient_Spread), crc, EINA_FALSE);
- if (pd->gd->colors_count)
- crc = eina_crc((void*) pd->gd->colors, sizeof (Efl_Gfx_Gradient_Stop) * pd->gd->colors_count, crc, EINA_FALSE);
- crc = eina_crc((void*) pd->gld, sizeof (Ector_Renderer_Gradient_Radial_Data), crc, EINA_FALSE);
-
- return crc;
-}
-
-#include "ector_renderer_software_gradient_radial.eo.c"
+++ /dev/null
-class @beta Ector.Renderer.Software.Gradient.Radial extends Ector.Renderer.Software implements Ector.Renderer.Gradient, Ector.Renderer.Gradient.Radial
-{
- [[Ector software renderer gradient radial]]
- c_prefix: ector_renderer_software_gradient_radial;
- data: Ector_Renderer_Software_Gradient_Data;
- implements {
- Ector.Renderer.prepare;
- Ector.Renderer.draw;
- Ector.Renderer.crc { get; }
- Ector.Renderer.Software.op_fill;
- Efl.Object.constructor;
- Efl.Object.destructor;
- Efl.Gfx.Gradient.stop { set; }
- }
-}
+++ /dev/null
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <math.h>
-#include <float.h>
-
-#include <Eina.h>
-#include <Ector.h>
-#include <software/Ector_Software.h>
-
-#include "ector_private.h"
-#include "ector_software_private.h"
-
-#define MY_CLASS ECTOR_RENDERER_SOFTWARE_IMAGE_CLASS
-
-typedef struct _Ector_Renderer_Software_Image_Data Ector_Renderer_Software_Image_Data;
-
-struct _Ector_Renderer_Software_Image_Data
-{
- Ector_Software_Surface_Data *surface;
- Ector_Renderer_Image_Data *image;
- Ector_Renderer_Data *base;
- Ector_Buffer *comp;
- Efl_Gfx_Vg_Composite_Method comp_method;
- int opacity;
- Eina_Matrix3 inv_m;
- struct {
- int x1, y1, x2, y2;
- } boundary;
-};
-
-static Eina_Bool
-_ector_renderer_software_image_ector_renderer_prepare(Eo *obj,
- Ector_Renderer_Software_Image_Data *pd)
-{
- if (!pd->surface)
- pd->surface = efl_data_xref(pd->base->surface, ECTOR_SOFTWARE_SURFACE_CLASS, obj);
-
- if (!pd->image->buffer || !pd->surface->rasterizer->fill_data.raster_buffer)
- return EINA_FALSE;
-
- Eina_Matrix3 m;
- double m11, m12, m21, m22, m31, m32;
- int x = pd->surface->x + (int)pd->base->origin.x;
- int y = pd->surface->y + (int)pd->base->origin.y;
- int image_w, image_h;
- ector_buffer_size_get(pd->image->buffer, &image_w, &image_h);
-
- double px[4] = {x, x + image_w, x, x + image_w};
- double py[4] = {y, y, y + image_h, y + image_h};
-
- //Only use alpha color
- pd->opacity = pd->base->color.a;
- /*ector_software_rasterizer_color_set(pd->surface->rasterizer,
- pd->base->color.r,
- pd->base->color.g,
- pd->base->color.b,
- pd->base->color.a);*/
-
- if (!pd->base->m)
- {
- eina_matrix3_identity(&m);
- eina_matrix3_scale(&m, (double)pd->surface->rasterizer->fill_data.raster_buffer->generic->w / (double)image_w,
- (double)pd->surface->rasterizer->fill_data.raster_buffer->generic->h / (double)image_h);
- }
- else
- eina_matrix3_copy(&m, pd->base->m);
- eina_matrix3_values_get(&m, &m11, &m12, NULL,
- &m21, &m22, NULL,
- &m31, &m32, NULL);
- //Calc draw boundbox
- pd->boundary.x1 = MAX(pd->surface->rasterizer->fill_data.raster_buffer->generic->w , (unsigned int)image_w);
- pd->boundary.y1 = MAX(pd->surface->rasterizer->fill_data.raster_buffer->generic->h , (unsigned int)image_h);
- pd->boundary.x2 = 0; pd->boundary.y2 = 0;
- for (int i = 0; i < 4; i++)
- {
- pd->boundary.x1 = MIN(pd->boundary.x1, (int)(((px[i] * m11) + (py[i] * m21) + m31) + 0.5));
- pd->boundary.y1 = MIN(pd->boundary.y1, (int)(((px[i] * m12) + (py[i] * m22) + m32) + 0.5));
-
- pd->boundary.x2 = MAX(pd->boundary.x2, (int)(((px[i] * m11) + (py[i] * m21) + m31) + 0.5));
- pd->boundary.y2 = MAX(pd->boundary.y2, (int)(((px[i] * m12) + (py[i] * m22) + m32) + 0.5));
- }
-
- eina_matrix3_inverse(&m, &pd->inv_m);
-
- return EINA_TRUE;
-}
-
-//FIXME: We need to implement that apply op, clips and mul_col.
-static Eina_Bool
-_ector_renderer_software_image_ector_renderer_draw(Eo *obj EINA_UNUSED,
- Ector_Renderer_Software_Image_Data *pd,
- Efl_Gfx_Render_Op op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
- unsigned int mul_col EINA_UNUSED)
-{
- if (!pd->image->buffer || !pd->surface->rasterizer->fill_data.raster_buffer->pixels.u32)
- return EINA_FALSE;
-
- if (pd->opacity == 0)
- return EINA_TRUE;
-
- const int pix_stride = pd->surface->rasterizer->fill_data.raster_buffer->stride / 4;
- Ector_Software_Buffer_Base_Data *comp = pd->comp ? efl_data_scope_get(pd->comp, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN) : NULL;
- Ector_Software_Buffer_Base_Data *bpd = efl_data_scope_get(pd->image->buffer, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
- double im11, im12, im21, im22, im31, im32;
- uint32_t *dst_buf, *src_buf;
- int image_w, image_h;
-
- int dst_buf_width = MIN(pd->boundary.x2, (int)pd->surface->rasterizer->fill_data.raster_buffer->generic->w);
- int dst_buf_height = MIN(pd->boundary.y2, (int)pd->surface->rasterizer->fill_data.raster_buffer->generic->h);
-
- ector_buffer_size_get(pd->image->buffer, &image_w, &image_h);
-
- dst_buf = pd->surface->rasterizer->fill_data.raster_buffer->pixels.u32;
- src_buf = bpd->pixels.u32;
-
- eina_matrix3_values_get(&pd->inv_m, &im11, &im12, NULL,
- &im21, &im22, NULL,
- &im31, &im32, NULL);
-
- //Draw
- for (int local_y = pd->boundary.y1; local_y < dst_buf_height; local_y++)
- {
- for (int local_x = pd->boundary.x1; local_x < dst_buf_width; local_x++)
- {
- uint32_t *dst = dst_buf + ((int)local_x + ((int)local_y * pix_stride));
- int rx, ry;
- rx = (int)(((double)local_x * im11) + ((double)local_y * im21) + im31 + 0.5);
- ry = (int)(((double)local_x * im12) + ((double)local_y * im22) + im32 + 0.5);
- if (rx < 0 || rx >= image_w || ry < 0 || ry >= image_h)
- continue;
- uint32_t *src = src_buf + (rx + (ry * image_w)); //FIXME: use to stride
- uint32_t temp = 0x0;
- if (comp)
- {
- uint32_t *m = comp->pixels.u32 + ((int)local_x + ((int)local_y * comp->generic->w));
- //FIXME : This comping can work only matte case.
- // We need consider to inverse matte case.
- temp = draw_mul_256((((*m)>>24) * pd->opacity)>>8, *src);
- }
- else
- {
- temp = draw_mul_256(pd->opacity, *src);
- }
- int inv_alpha = 255 - ((temp) >> 24);
- *dst = temp + draw_mul_256(inv_alpha, *dst);
- }
- }
-
- return EINA_TRUE;
-}
-
-static Eo *
-_ector_renderer_software_image_efl_object_constructor(Eo *obj, Ector_Renderer_Software_Image_Data *pd)
-{
- obj = efl_constructor(efl_super(obj, MY_CLASS));
- if (!obj) return NULL;
-
- pd->image = efl_data_xref(obj, ECTOR_RENDERER_IMAGE_MIXIN, obj);
- pd->base = efl_data_xref(obj, ECTOR_RENDERER_CLASS, obj);
-
- return obj;
-}
-
-static void
-_ector_renderer_software_image_efl_object_destructor(Eo *obj, Ector_Renderer_Software_Image_Data *pd)
-{
- efl_data_xunref(pd->base->surface, pd->surface, obj);
- efl_data_xunref(obj, pd->base, obj);
- efl_data_xunref(obj, pd->image, obj);
-
- efl_destructor(efl_super(obj, MY_CLASS));
-}
-
-unsigned int
-_ector_renderer_software_image_ector_renderer_crc_get(const Eo *obj,
- Ector_Renderer_Software_Image_Data *pd)
-{
- unsigned int crc;
-
- crc = ector_renderer_crc_get(efl_super(obj, MY_CLASS));
-
- crc = eina_crc((void*) pd->image, sizeof (Ector_Renderer_Image_Data), crc, EINA_FALSE);
- return crc;
-}
-
-static void
-_ector_renderer_software_image_ector_renderer_comp_method_set(Eo *obj EINA_UNUSED,
- Ector_Renderer_Software_Image_Data *pd,
- Ector_Buffer *comp,
- Efl_Gfx_Vg_Composite_Method method)
-{
- pd->comp = comp;
- pd->comp_method = method;
-}
-
-#include "ector_renderer_software_image.eo.c"
+++ /dev/null
-class @beta Ector.Renderer.Software.Image extends Ector.Renderer.Software implements Ector.Renderer.Image
-{
- [[Ector software renderer image class]]
- c_prefix: ector_renderer_software_image;
- implements {
- Ector.Renderer.prepare;
- Ector.Renderer.draw;
- Ector.Renderer.comp_method { set; }
- Ector.Renderer.crc { get; }
- Efl.Object.constructor;
- Efl.Object.destructor;
- }
-}
+++ /dev/null
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <math.h>
-#include <float.h>
-
-#include <Eina.h>
-#include <Ector.h>
-#include <software/Ector_Software.h>
-
-#include "ector_private.h"
-#include "ector_software_private.h"
-
-#define MY_CLASS ECTOR_RENDERER_SOFTWARE_SHAPE_CLASS
-
-typedef struct _Ector_Renderer_Software_Shape_Data Ector_Renderer_Software_Shape_Data;
-typedef struct _Ector_Software_Shape_Task Ector_Software_Shape_Task;
-
-struct _Ector_Software_Shape_Task
-{
- Ector_Renderer_Software_Shape_Data *pd;
-
- const Efl_Gfx_Path_Command *cmds;
- const double *pts;
-
- Efl_Gfx_Fill_Rule fill_rule;
-};
-
-struct _Ector_Renderer_Software_Shape_Data
-{
- Efl_Gfx_Shape_Public *public_shape;
-
- Ector_Software_Surface_Data *surface;
- Ector_Renderer_Shape_Data *shape;
- Ector_Renderer_Data *base;
-
- Shape_Rle_Data *shape_data;
- Shape_Rle_Data *outline_data;
-
- Ector_Buffer *comp;
- Efl_Gfx_Vg_Composite_Method comp_method;
-
- Ector_Software_Shape_Task *task;
-};
-
-typedef struct _Outline
-{
- SW_FT_Outline ft_outline;
- int points_alloc;
- int contours_alloc;
-} Outline;
-
-
-#define TO_FT_COORD(x) ((x) * 64) // to freetype 26.6 coordinate.
-
-static inline void
-_grow_outline_contour(Outline *outline, int num)
-{
- if ( outline->ft_outline.n_contours + num > outline->contours_alloc)
- {
- outline->contours_alloc += 5;
- outline->ft_outline.contours = (short *) realloc(outline->ft_outline.contours,
- outline->contours_alloc * sizeof(short));
- }
-}
-
-static inline void
-_grow_outline_points(Outline *outline, int num)
-{
- if ( outline->ft_outline.n_points + num > outline->points_alloc)
- {
- outline->points_alloc += 50;
- outline->ft_outline.points = (SW_FT_Vector *) realloc(outline->ft_outline.points,
- outline->points_alloc * sizeof(SW_FT_Vector));
- outline->ft_outline.tags = (char *) realloc(outline->ft_outline.tags,
- outline->points_alloc * sizeof(char));
- }
-}
-static Outline *
-_outline_create()
-{
- Outline *outline = (Outline *) calloc(1, sizeof(Outline));
- outline->points_alloc = 0;
- outline->contours_alloc = 0;
- _grow_outline_contour(outline, 1);
- _grow_outline_points(outline, 1);
- return outline;
-}
-
-static
-void _outline_destroy(Outline *outline)
-{
- if (outline)
- {
- free(outline->ft_outline.points);
- free(outline->ft_outline.tags);
- free(outline->ft_outline.contours);
- free(outline);
- }
-}
-
-static void
-_outline_move_to(Outline *outline, double x, double y)
-{
- SW_FT_Outline *ft_outline = &outline->ft_outline;
-
- _grow_outline_points(outline, 1);
- ft_outline->points[ft_outline->n_points].x = TO_FT_COORD(x);
- ft_outline->points[ft_outline->n_points].y = TO_FT_COORD(y);
- ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_ON;
-
- if (ft_outline->n_points)
- {
- _grow_outline_contour(outline, 1);
- ft_outline->contours[ft_outline->n_contours] = ft_outline->n_points - 1;
- ft_outline->n_contours++;
- }
-
- ft_outline->n_points++;
-}
-
-static void
-_outline_end(Outline *outline)
-{
- SW_FT_Outline *ft_outline = &outline->ft_outline;
-
- _grow_outline_contour(outline, 1);
-
- if (ft_outline->n_points)
- {
- ft_outline->contours[ft_outline->n_contours] = ft_outline->n_points - 1;
- ft_outline->n_contours++;
- }
-}
-
-
-static void _outline_line_to(Outline *outline, double x, double y)
-{
- SW_FT_Outline *ft_outline = &outline->ft_outline;
-
- _grow_outline_points(outline, 1);
- ft_outline->points[ft_outline->n_points].x = TO_FT_COORD(x);
- ft_outline->points[ft_outline->n_points].y = TO_FT_COORD(y);
- ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_ON;
- ft_outline->n_points++;
-}
-
-
-static Eina_Bool
-_outline_close_path(Outline *outline)
-{
- SW_FT_Outline *ft_outline = &outline->ft_outline;
- int index ;
-
- if (ft_outline->n_contours)
- {
- index = ft_outline->contours[ft_outline->n_contours - 1] + 1;
- }
- else
- {
- // First path
- index = 0;
- }
-
- // Make sure there is at least one point in the current path
- if (ft_outline->n_points == index) return EINA_FALSE;
-
- // Close the path
- _grow_outline_points(outline, 1);
- ft_outline->points[ft_outline->n_points].x = ft_outline->points[index].x;
- ft_outline->points[ft_outline->n_points].y = ft_outline->points[index].y;
- ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_ON;
- ft_outline->n_points++;
-
- return EINA_TRUE;
-}
-
-
-static void _outline_cubic_to(Outline *outline, double cx1, double cy1,
- double cx2, double cy2, double x, double y)
-{
- SW_FT_Outline *ft_outline = &outline->ft_outline;
-
- _grow_outline_points(outline, 3);
-
- ft_outline->points[ft_outline->n_points].x = TO_FT_COORD(cx1);
- ft_outline->points[ft_outline->n_points].y = TO_FT_COORD(cy1);
- ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_CUBIC;
- ft_outline->n_points++;
-
- ft_outline->points[ft_outline->n_points].x = TO_FT_COORD(cx2);
- ft_outline->points[ft_outline->n_points].y = TO_FT_COORD(cy2);
- ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_CUBIC;
- ft_outline->n_points++;
-
- ft_outline->points[ft_outline->n_points].x = TO_FT_COORD(x);
- ft_outline->points[ft_outline->n_points].y = TO_FT_COORD(y);
- ft_outline->tags[ft_outline->n_points] = SW_FT_CURVE_TAG_ON;
- ft_outline->n_points++;
-}
-
-static void _outline_transform(Outline *outline, Eina_Matrix3 *m)
-{
- int i;
- double x, y;
- SW_FT_Outline *ft_outline = &outline->ft_outline;
-
- if (m && (eina_matrix3_type_get(m) != EINA_MATRIX_TYPE_IDENTITY))
- {
- for (i = 0; i < ft_outline->n_points; i++)
- {
- eina_matrix3_point_transform(m,
- ft_outline->points[i].x/64.0,/* convert back to normal coord.*/
- ft_outline->points[i].y/64.0,/* convert back to normal coord.*/
- &x, &y);
-
- ft_outline->points[i].x = TO_FT_COORD(x);
- ft_outline->points[i].y = TO_FT_COORD(y);
- }
- }
-}
-
-static Eina_Bool
-_generate_outline(const Efl_Gfx_Path_Command *cmds, const double *pts, Outline * outline)
-{
- Eina_Bool close_path = EINA_FALSE;
- for (; *cmds != EFL_GFX_PATH_COMMAND_TYPE_END; cmds++)
- {
- switch (*cmds)
- {
- case EFL_GFX_PATH_COMMAND_TYPE_MOVE_TO:
-
- _outline_move_to(outline, pts[0], pts[1]);
-
- pts += 2;
- break;
- case EFL_GFX_PATH_COMMAND_TYPE_LINE_TO:
-
- _outline_line_to(outline, pts[0], pts[1]);
-
- pts += 2;
- break;
- case EFL_GFX_PATH_COMMAND_TYPE_CUBIC_TO:
-
- _outline_cubic_to(outline,
- pts[0], pts[1], pts[2], pts[3], // control points
- pts[4], pts[5]); // destination point
- pts += 6;
- break;
-
- case EFL_GFX_PATH_COMMAND_TYPE_CLOSE:
-
- close_path = _outline_close_path(outline);
- break;
-
- case EFL_GFX_PATH_COMMAND_TYPE_LAST:
- case EFL_GFX_PATH_COMMAND_TYPE_END:
- break;
- }
- }
- _outline_end(outline);
- return close_path;
-}
-
-typedef struct _Line
-{
- double x1;
- double y1;
- double x2;
- double y2;
-}Line;
-
-static void
-_line_value_set(Line *l, double x1, double y1, double x2, double y2)
-{
- l->x1 = x1;
- l->y1 = y1;
- l->x2 = x2;
- l->y2 = y2;
-}
-
-// approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm.
-// With alpha = 1, beta = 3/8, giving results with the largest error less
-// than 7% compared to the exact value.
-static double
-_line_length(Line *l)
-{
- double x = l->x2 - l->x1;
- double y = l->y2 - l->y1;
- x = x < 0 ? -x : x;
- y = y < 0 ? -y : y;
- return (x > y ? x + 0.375 * y : y + 0.375 * x);
-}
-
-static void
-_line_split_at_length(Line *l, double length, Line *left, Line *right)
-{
- double len = _line_length(l);
- double dx = ((l->x2 - l->x1)/len) *length;
- double dy = ((l->y2 - l->y1)/len) *length;
-
- left->x1 = l->x1;
- left->y1 = l->y1;
- left->x2 = left->x1 + dx;
- left->y2 = left->y1 + dy;
-
- right->x1 = left->x2;
- right->y1 = left->y2;
- right->x2 = l->x2;
- right->y2 = l->y2;
-}
-
-typedef struct _Dash_Stroker
-{
- Efl_Gfx_Dash *dash;
- int dash_len;
- Outline *outline;
- int cur_dash_index;
- double cur_dash_length;
- Eina_Bool cur_op_gap;
- double start_x, start_y;
- double cur_x, cur_y;
-}Dash_Stroker;
-
-static void
-_dasher_line_to(Dash_Stroker *dasher, double x, double y)
-{
- Line l, left, right;
- double line_len = 0.0;
- _line_value_set(&l, dasher->cur_x, dasher->cur_y, x, y);
- line_len = _line_length(&l);
- if (line_len < dasher->cur_dash_length)
- {
- dasher->cur_dash_length -= line_len;
- if (!dasher->cur_op_gap)
- {
- _outline_move_to(dasher->outline, dasher->cur_x, dasher->cur_y);
- _outline_line_to(dasher->outline, x, y);
- }
- }
- else
- {
- while (line_len > dasher->cur_dash_length)
- {
- line_len -= dasher->cur_dash_length;
- _line_split_at_length(&l, dasher->cur_dash_length, &left, &right);
- if (!dasher->cur_op_gap)
- {
- _outline_move_to(dasher->outline, left.x1, left.y1);
- _outline_line_to(dasher->outline, left.x2, left.y2);
- dasher->cur_dash_length = dasher->dash[dasher->cur_dash_index].gap;
- }
- else
- {
- dasher->cur_dash_index = (dasher->cur_dash_index +1) % dasher->dash_len ;
- dasher->cur_dash_length = dasher->dash[dasher->cur_dash_index].length;
- }
- dasher->cur_op_gap = !dasher->cur_op_gap;
- l = right;
- dasher->cur_x = l.x1;
- dasher->cur_y = l.y1;
- }
- // remainder
- dasher->cur_dash_length -= line_len;
- if (!dasher->cur_op_gap)
- {
- _outline_move_to(dasher->outline, l.x1, l.y1);
- _outline_line_to(dasher->outline, l.x2, l.y2);
- }
- if (dasher->cur_dash_length < 1.0)
- {
- // move to next dash
- if (!dasher->cur_op_gap)
- {
- dasher->cur_op_gap = EINA_TRUE;
- dasher->cur_dash_length = dasher->dash[dasher->cur_dash_index].gap;
- }
- else
- {
- dasher->cur_op_gap = EINA_FALSE;
- dasher->cur_dash_index = (dasher->cur_dash_index +1) % dasher->dash_len ;
- dasher->cur_dash_length = dasher->dash[dasher->cur_dash_index].length;
- }
- }
- }
- dasher->cur_x = x;
- dasher->cur_y = y;
-}
-
-static void
-_dasher_cubic_to(Dash_Stroker *dasher, double cx1 , double cy1, double cx2, double cy2, double x, double y)
-{
- Eina_Bezier b, left, right;
- double bez_len = 0.0;
- eina_bezier_values_set(&b, dasher->cur_x, dasher->cur_y, cx1, cy1, cx2, cy2, x, y);
- bez_len = eina_bezier_length_get(&b);
- if (bez_len < dasher->cur_dash_length)
- {
- dasher->cur_dash_length -= bez_len;
- if (!dasher->cur_op_gap)
- {
- _outline_move_to(dasher->outline, dasher->cur_x, dasher->cur_y);
- _outline_cubic_to(dasher->outline, cx1, cy1, cx2, cy2, x, y);
- }
- }
- else
- {
- while (bez_len > dasher->cur_dash_length)
- {
- bez_len -= dasher->cur_dash_length;
- eina_bezier_split_at_length(&b, dasher->cur_dash_length, &left, &right);
- if (!dasher->cur_op_gap)
- {
- _outline_move_to(dasher->outline, left.start.x, left.start.y);
- _outline_cubic_to(dasher->outline, left.ctrl_start.x, left.ctrl_start.y, left.ctrl_end.x, left.ctrl_end.y, left.end.x, left.end.y);
- dasher->cur_dash_length = dasher->dash[dasher->cur_dash_index].gap;
- }
- else
- {
- dasher->cur_dash_index = (dasher->cur_dash_index +1) % dasher->dash_len ;
- dasher->cur_dash_length = dasher->dash[dasher->cur_dash_index].length;
- }
- dasher->cur_op_gap = !dasher->cur_op_gap;
- b = right;
- dasher->cur_x = b.start.x;
- dasher->cur_y = b.start.y;
- }
- // remainder
- dasher->cur_dash_length -= bez_len;
- if (!dasher->cur_op_gap)
- {
- _outline_move_to(dasher->outline, b.start.x, b.start.y);
- _outline_cubic_to(dasher->outline, b.ctrl_start.x, b.ctrl_start.y, b.ctrl_end.x, b.ctrl_end.y, b.end.x, b.end.y);
- }
- if (dasher->cur_dash_length < 1.0)
- {
- // move to next dash
- if (!dasher->cur_op_gap)
- {
- dasher->cur_op_gap = EINA_TRUE;
- dasher->cur_dash_length = dasher->dash[dasher->cur_dash_index].gap;
- }
- else
- {
- dasher->cur_op_gap = EINA_FALSE;
- dasher->cur_dash_index = (dasher->cur_dash_index +1) % dasher->dash_len ;
- dasher->cur_dash_length = dasher->dash[dasher->cur_dash_index].length;
- }
- }
- }
- dasher->cur_x = x;
- dasher->cur_y = y;
-}
-
-static Eina_Bool
-_generate_dashed_outline(const Efl_Gfx_Path_Command *cmds, const double *pts, Outline * outline, Efl_Gfx_Dash *dash, int dash_len)
-{
- Dash_Stroker dasher;
- dasher.dash = dash;
- dasher.dash_len = dash_len;
- dasher.outline = outline;
- dasher.cur_dash_length = 0.0;
- dasher.cur_dash_index = 0;
- dasher.cur_op_gap = EINA_FALSE;
- dasher.start_x = 0.0;
- dasher.start_y = 0.0;
- dasher.cur_x = 0.0;
- dasher.cur_y = 0.0;
-
- for (; *cmds != EFL_GFX_PATH_COMMAND_TYPE_END; cmds++)
- {
- switch (*cmds)
- {
- case EFL_GFX_PATH_COMMAND_TYPE_MOVE_TO:
- {
- // reset the dash
- dasher.cur_dash_index = 0;
- dasher.cur_dash_length = dasher.dash[0].length;
- dasher.cur_op_gap = EINA_FALSE;
- dasher.start_x = pts[0];
- dasher.start_y = pts[1];
- dasher.cur_x = pts[0];
- dasher.cur_y = pts[1];
- pts += 2;
- }
- break;
- case EFL_GFX_PATH_COMMAND_TYPE_LINE_TO:
- _dasher_line_to(&dasher, pts[0], pts[1]);
- pts += 2;
- break;
- case EFL_GFX_PATH_COMMAND_TYPE_CUBIC_TO:
- _dasher_cubic_to(&dasher, pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
- pts += 6;
- break;
-
- case EFL_GFX_PATH_COMMAND_TYPE_CLOSE:
- _dasher_line_to(&dasher, dasher.start_x, dasher.start_y);
- break;
-
- case EFL_GFX_PATH_COMMAND_TYPE_LAST:
- case EFL_GFX_PATH_COMMAND_TYPE_END:
- break;
- }
- }
- _outline_end(outline);
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_generate_stroke_data(Ector_Renderer_Software_Shape_Data *pd)
-{
- if (pd->outline_data) return EINA_FALSE;
-
- if (!pd->shape->stroke.fill &&
- ((pd->public_shape->stroke.color.a == 0) ||
- (pd->public_shape->stroke.width < 0.01)))
- return EINA_FALSE;
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_generate_shape_data(Ector_Renderer_Software_Shape_Data *pd)
-{
- if (pd->shape_data) return EINA_FALSE;
-
- if (!pd->shape->fill && (pd->base->color.a == 0)) return EINA_FALSE;
-
- return EINA_TRUE;
-}
-
-static Ector_Software_Shape_Task *
-_need_update_rle(Eo *obj, Ector_Renderer_Software_Shape_Data *pd)
-{
- if (pd->task) return pd->task;
-
- if (!pd->base->visibility || (!_generate_stroke_data(pd) &&
- !_generate_shape_data(pd)))
- return NULL;
-
- const Efl_Gfx_Path_Command *cmds;
- const double *pts;
- efl_gfx_path_get(obj, &cmds, &pts);
- if (!cmds) return NULL;
-
- Ector_Software_Shape_Task *task = malloc(sizeof(Ector_Software_Shape_Task));
- if (!task) return NULL;
-
- task->pd = pd;
- task->cmds = cmds;
- task->pts = pts;
- task->fill_rule = efl_gfx_shape_fill_rule_get(obj);
-
- pd->task = task;
-
- return task;
-}
-
-static void
-_done_rle(void *data)
-{
- Ector_Software_Shape_Task *task = data;
- if (!task) return;
- if (task->pd) task->pd->task = NULL;
- free(task);
-}
-
-static void
-_update_rle(void *data, Ector_Software_Thread *thread)
-{
- Ector_Software_Shape_Task *task = data;
- Eina_Bool close_path;
- Outline *outline, *dash_outline;
-
- outline = _outline_create();
- close_path = _generate_outline(task->cmds, task->pts, outline);
- if (task->fill_rule == EFL_GFX_FILL_RULE_ODD_EVEN)
- outline->ft_outline.flags = SW_FT_OUTLINE_EVEN_ODD_FILL;
- else
- outline->ft_outline.flags = SW_FT_OUTLINE_NONE; // default is winding fill
-
- _outline_transform(outline, task->pd->base->m);
-
- //shape data generation
- if (_generate_shape_data(task->pd))
- task->pd->shape_data = ector_software_rasterizer_generate_rle_data(thread,
- task->pd->surface->rasterizer,
- &outline->ft_outline);
-
- //stroke data generation
- if (_generate_stroke_data(task->pd))
- {
- ector_software_rasterizer_stroke_set(thread, task->pd->surface->rasterizer,
- (task->pd->public_shape->stroke.width *
- task->pd->public_shape->stroke.scale),
- task->pd->public_shape->stroke.cap,
- task->pd->public_shape->stroke.join,
- task->pd->base->m,
- task->pd->public_shape->stroke.miterlimit);
-
- if (task->pd->public_shape->stroke.dash)
- {
- dash_outline = _outline_create();
- close_path = _generate_dashed_outline(task->cmds, task->pts, dash_outline,
- task->pd->public_shape->stroke.dash,
- task->pd->public_shape->stroke.dash_length);
- _outline_transform(dash_outline, task->pd->base->m);
- task->pd->outline_data = ector_software_rasterizer_generate_stroke_rle_data(thread,
- task->pd->surface->rasterizer,
- &dash_outline->ft_outline,
- close_path);
- _outline_destroy(dash_outline);
- }
- else
- {
- task->pd->outline_data = ector_software_rasterizer_generate_stroke_rle_data(thread,
- task->pd->surface->rasterizer,
- &outline->ft_outline,
- close_path);
- }
- }
- _outline_destroy(outline);
-}
-
-static Eina_Bool
-_ector_renderer_software_shape_ector_renderer_prepare(Eo *obj,
- Ector_Renderer_Software_Shape_Data *pd)
-{
- // FIXME: shouldn't this be moved to the software base object?
- if (!pd->surface)
- pd->surface = efl_data_xref(pd->base->surface, ECTOR_SOFTWARE_SURFACE_CLASS, obj);
-
- // Asynchronously lazy build of the RLE data for this shape
- if (!pd->task)
- {
- Ector_Software_Shape_Task *task = _need_update_rle(obj, pd);
- if (task) ector_software_schedule(_update_rle, _done_rle, task);
- }
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_ector_renderer_software_shape_ector_renderer_draw(Eo *obj EINA_UNUSED,
- Ector_Renderer_Software_Shape_Data *pd,
- Efl_Gfx_Render_Op op, Eina_Array *clips,
- unsigned int mul_col)
-{
- int x, y;
-
- // check if RLE data are ready
- Ector_Software_Shape_Task *task = pd->task;
- if (task) ector_software_wait(_update_rle, _done_rle, task);
-
- // adjust the offset
- x = (int)pd->base->origin.x - pd->surface->x;
- y = (int)pd->base->origin.y - pd->surface->y;
-
- ector_software_rasterizer_clip_rect_set(pd->surface->rasterizer, clips);
- ector_software_rasterizer_transform_set(pd->surface->rasterizer, pd->base->m);
-
- // fill the span_data structure
- if (pd->shape->fill)
- {
- ector_renderer_software_op_fill(pd->shape->fill);
- ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
- x, y, mul_col, op,
- pd->shape_data,
- pd->comp,
- pd->comp_method);
- }
- else
- {
- if (pd->base->color.a > 0)
- {
- ector_software_rasterizer_color_set(pd->surface->rasterizer,
- pd->base->color.r,
- pd->base->color.g,
- pd->base->color.b,
- pd->base->color.a);
- ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
- x, y, mul_col, op,
- pd->shape_data,
- pd->comp,
- pd->comp_method);
- }
- }
-
- if (!pd->outline_data) return EINA_TRUE;
-
- if (pd->shape->stroke.fill)
- {
- ector_renderer_software_op_fill(pd->shape->stroke.fill);
- ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
- x, y, mul_col, op,
- pd->outline_data,
- pd->comp,
- pd->comp_method);
- }
- else
- {
- if (pd->public_shape->stroke.color.a > 0)
- {
- ector_software_rasterizer_color_set(pd->surface->rasterizer,
- pd->public_shape->stroke.color.r,
- pd->public_shape->stroke.color.g,
- pd->public_shape->stroke.color.b,
- pd->public_shape->stroke.color.a);
- ector_software_rasterizer_draw_rle_data(pd->surface->rasterizer,
- x, y, mul_col, op,
- pd->outline_data,
- pd->comp,
- pd->comp_method);
- }
- }
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_ector_renderer_software_shape_ector_renderer_software_op_fill(Eo *obj EINA_UNUSED,
- Ector_Renderer_Software_Shape_Data *pd EINA_UNUSED)
-{
- // FIXME: let's find out how to fill a shape with a shape later.
- // I need to read SVG specification and see how to map that with software.
- return EINA_FALSE;
-}
-
-EOLIAN static void
-_ector_renderer_software_shape_efl_gfx_path_commit(Eo *obj EINA_UNUSED,
- Ector_Renderer_Software_Shape_Data *pd)
-{
- if (pd->shape_data)
- {
- ector_software_rasterizer_destroy_rle_data(pd->shape_data);
- pd->shape_data = NULL;
- }
- if (pd->outline_data)
- {
- ector_software_rasterizer_destroy_rle_data(pd->outline_data);
- pd->outline_data = NULL;
- }
-}
-
-static Eo *
-_ector_renderer_software_shape_efl_object_constructor(Eo *obj, Ector_Renderer_Software_Shape_Data *pd)
-{
- obj = efl_constructor(efl_super(obj, MY_CLASS));
- if (!obj) return NULL;
-
- pd->public_shape = efl_data_xref(obj, EFL_GFX_SHAPE_MIXIN, obj);
- pd->shape = efl_data_xref(obj, ECTOR_RENDERER_SHAPE_MIXIN, obj);
- pd->base = efl_data_xref(obj, ECTOR_RENDERER_CLASS, obj);
-
- return obj;
-}
-
-static void
-_ector_renderer_software_shape_efl_object_destructor(Eo *obj, Ector_Renderer_Software_Shape_Data *pd)
-{
- // FIXME: As base class, destructor can't call destructor of mixin class.
- // Call explicit API to free shape data.
- if (pd->task)
- ector_software_wait(_update_rle, _done_rle, pd->task);
-
- efl_gfx_path_reset(obj);
-
- if (pd->shape_data) ector_software_rasterizer_destroy_rle_data(pd->shape_data);
- if (pd->outline_data) ector_software_rasterizer_destroy_rle_data(pd->outline_data);
-
- efl_data_xunref(pd->base->surface, pd->surface, obj);
- efl_data_xunref(obj, pd->base, obj);
- efl_data_xunref(obj, pd->shape, obj);
- efl_data_xunref(obj, pd->public_shape, obj);
-
- efl_destructor(efl_super(obj, MY_CLASS));
-}
-
-unsigned int
-_ector_renderer_software_shape_ector_renderer_crc_get(const Eo *obj,
- Ector_Renderer_Software_Shape_Data *pd)
-{
- unsigned int crc;
-
- crc = ector_renderer_crc_get(efl_super(obj, MY_CLASS));
-
- crc = eina_crc((void*) &pd->shape->stroke.marker,
- sizeof (pd->shape->stroke.marker),
- crc, EINA_FALSE);
- crc = eina_crc((void*) &pd->public_shape->stroke.scale,
- sizeof (pd->public_shape->stroke.scale) * 3,
- crc, EINA_FALSE); // scale, width, centered
- crc = eina_crc((void*) &pd->public_shape->stroke.color,
- sizeof (pd->public_shape->stroke.color),
- crc, EINA_FALSE);
- crc = eina_crc((void*) &pd->public_shape->stroke.cap,
- sizeof (pd->public_shape->stroke.cap),
- crc, EINA_FALSE);
- crc = eina_crc((void*) &pd->public_shape->stroke.join,
- sizeof (pd->public_shape->stroke.join),
- crc, EINA_FALSE);
-
- if (pd->shape->fill)
- crc = _renderer_crc_get(pd->shape->fill, crc);
- if (pd->shape->stroke.fill)
- crc = _renderer_crc_get(pd->shape->stroke.fill, crc);
- if (pd->shape->stroke.marker)
- crc = _renderer_crc_get(pd->shape->stroke.marker, crc);
- if (pd->public_shape->stroke.dash_length)
- {
- crc = eina_crc((void*) pd->public_shape->stroke.dash,
- sizeof (Efl_Gfx_Dash) * pd->public_shape->stroke.dash_length,
- crc, EINA_FALSE);
- }
-
- return crc;
-}
-
-static void
-_ector_renderer_software_shape_ector_renderer_comp_method_set(Eo *obj EINA_UNUSED,
- Ector_Renderer_Software_Shape_Data *pd,
- Ector_Buffer *comp,
- Efl_Gfx_Vg_Composite_Method method)
-{
- //Use ref/unref.
- pd->comp = comp;
- pd->comp_method = method;
-}
-
-#include "ector_renderer_software_shape.eo.c"
+++ /dev/null
-class @beta Ector.Renderer.Software.Shape extends Ector.Renderer.Software implements Ector.Renderer.Shape
-{
- [[Ector software renderer shape class]]
- c_prefix: ector_renderer_software_shape;
- implements {
- Ector.Renderer.prepare;
- Ector.Renderer.draw;
- Ector.Renderer.Software.op_fill;
- Ector.Renderer.comp_method { set; }
- Ector.Renderer.crc { get; }
- Efl.Gfx.Path.commit;
- Efl.Object.constructor;
- Efl.Object.destructor;
- }
-}
+++ /dev/null
-#include "ector_software_gradient.h"
-
-#ifdef BUILD_SSE3
-void _radial_helper_sse3(uint32_t *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data, float det, float delta_det, float delta_delta_det, float b, float delta_b);
-void _linear_helper_sse3(uint32_t *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data, int t, int inc);
-#endif
-
-#define GRADIENT_STOPTABLE_SIZE 1024
-#define FIXPT_BITS 8
-#define FIXPT_SIZE (1<<FIXPT_BITS)
-
-typedef void (*Ector_Radial_Helper_Func)(uint32_t *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data,
- float det, float delta_det, float delta_delta_det, float b, float delta_b);
-typedef void (*Ector_Linear_Helper_Func)(uint32_t *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data,
- int t_fixed, int inc_fixed);
-
-static Ector_Radial_Helper_Func _ector_radial_helper;
-static Ector_Linear_Helper_Func _ector_linear_helper;
-
-static void
-_update_color_table(void *data, Ector_Software_Thread *t EINA_UNUSED)
-{
- Ector_Renderer_Software_Gradient_Data *gdata = data;
- gdata->alpha = efl_draw_generate_gradient_color_table(gdata->gd->colors, gdata->gd->colors_count,
- gdata->color_table, GRADIENT_STOPTABLE_SIZE);
-}
-
-static void
-_done_color_table(void *data)
-{
- Ector_Renderer_Software_Gradient_Data *gdata = data;
- gdata->ctable_status = CTABLE_READY_DONE;
-}
-
-void
-ector_software_gradient_color_update(Ector_Renderer_Software_Gradient_Data *gdata)
-{
- if (gdata->ctable_status == CTABLE_READY_DONE) return;
-
- //OPTIMIZE: This color can be updated only when gradient properties are changed.
-
- //Alloc only one time.
- if (!gdata->color_table)
- gdata->color_table = malloc(GRADIENT_STOPTABLE_SIZE * 4);
-
- if (gdata->ctable_status == CTABLE_NOT_READY)
- {
- gdata->ctable_status = CTABLE_PROCESSING;
- ector_software_schedule(_update_color_table, _done_color_table, gdata);
- }
- else if (gdata->ctable_status == CTABLE_PROCESSING)
- ector_software_wait(_update_color_table, _done_color_table, gdata);
-}
-
-void
-destroy_color_table(Ector_Renderer_Software_Gradient_Data *gdata)
-{
- if (gdata->color_table)
- {
- free(gdata->color_table);
- gdata->color_table = NULL;
- }
-}
-
-static void
-_linear_helper_generic(uint32_t *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data,
- int t_fixed, int inc_fixed)
-{
- int i;
-
- for (i = 0 ; i < length ; i++)
- {
- *buffer++ = _gradient_pixel_fixed(g_data, t_fixed);
- t_fixed += inc_fixed;
- }
-}
-
-void
-fetch_linear_gradient(uint32_t *buffer, Span_Data *data, int y, int x, int length)
-{
- Ector_Renderer_Software_Gradient_Data *g_data = data->gradient;
- float t, inc, rx=0, ry=0;
- uint32_t *end;
- int t_fixed, inc_fixed;
-
- if (EINA_DBL_EQ(g_data->linear.l, 0.0))
- {
- t = inc = 0;
- }
- else
- {
- rx = data->inv.xy * (y + (float)0.5) + data->inv.xz + data->inv.xx * (x + (float)0.5);
- ry = data->inv.yy * (y + (float)0.5) + data->inv.yz + data->inv.yx * (x + (float)0.5);
- t = g_data->linear.dx*rx + g_data->linear.dy*ry + g_data->linear.off;
- inc = g_data->linear.dx * data->inv.xx + g_data->linear.dx * data->inv.yx;
-
- t *= (GRADIENT_STOPTABLE_SIZE - 1);
- inc *= (GRADIENT_STOPTABLE_SIZE - 1);
- }
-
- end = buffer + length;
- if (inc > (float)(-1e-5) && inc < (float)(1e-5))
- {
- draw_memset32(buffer, _gradient_pixel_fixed(g_data, (int)(t * FIXPT_SIZE)), length);
- }
- else
- {
- const int vmax = INT_MAX >> (FIXPT_BITS + 1);
- const int vmin = -vmax;
- float v = t + (inc *length);
-
- if ((v < (float)vmax) && (v > (float)(vmin)))
- {
- // we can use fixed point math
- t_fixed = (int)(t * FIXPT_SIZE);
- inc_fixed = (int)(inc * FIXPT_SIZE);
- _ector_linear_helper(buffer, length, g_data, t_fixed, inc_fixed);
- }
- else
- {
- // we have to fall back to float math
- while (buffer < end)
- {
- *buffer++ = _gradient_pixel(g_data, t/GRADIENT_STOPTABLE_SIZE);
- t += inc;
- }
- }
- }
-}
-
-static void
-_radial_helper_generic(uint32_t *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data, float det,
- float delta_det, float delta_delta_det, float b, float delta_b)
-{
- int i;
-
- for (i = 0 ; i < length ; i++)
- {
- *buffer++ = _gradient_pixel(g_data, sqrt(det) - b);
- det += delta_det;
- delta_det += delta_delta_det;
- b += delta_b;
- }
-}
-
-
-void
-fetch_radial_gradient(uint32_t *buffer, Span_Data *data, int y, int x, int length)
-{
- Ector_Renderer_Software_Gradient_Data *g_data = data->gradient;
- float rx, ry, inv_a, delta_rx, delta_ry, b, delta_b, b_delta_b, delta_b_delta_b,
- bb, delta_bb, rxrxryry, delta_rxrxryry, rx_plus_ry, delta_rx_plus_ry, det,
- delta_det, delta_delta_det;
-
- // avoid division by zero
- if (fabsf(g_data->radial.a) <= 0.00001f)
- {
- draw_memset32(buffer, 0, length);
- return;
- }
-
- rx = data->inv.xy * (y + (float)0.5) + data->inv.xz + data->inv.xx * (x + (float)0.5);
- ry = data->inv.yy * (y + (float)0.5) + data->inv.yz + data->inv.yx * (x + (float)0.5);
-
- rx -= g_data->radial.fx;
- ry -= g_data->radial.fy;
-
- inv_a = 1 / (float)(2 * g_data->radial.a);
-
- delta_rx = data->inv.xx;
- delta_ry = data->inv.yx;
-
- b = 2*(g_data->radial.dr*g_data->radial.fradius + rx * g_data->radial.dx + ry * g_data->radial.dy);
- delta_b = 2*(delta_rx * g_data->radial.dx + delta_ry * g_data->radial.dy);
- b_delta_b = 2 * b * delta_b;
- delta_b_delta_b = 2 * delta_b * delta_b;
-
- bb = b * b;
- delta_bb = delta_b * delta_b;
- b *= inv_a;
- delta_b *= inv_a;
-
- rxrxryry = rx * rx + ry * ry;
- delta_rxrxryry = delta_rx * delta_rx + delta_ry * delta_ry;
- rx_plus_ry = 2*(rx * delta_rx + ry * delta_ry);
- delta_rx_plus_ry = 2 * delta_rxrxryry;
-
- inv_a *= inv_a;
-
- det = (bb - 4 * g_data->radial.a * (g_data->radial.sqrfr - rxrxryry)) * inv_a;
- delta_det = (b_delta_b + delta_bb + 4 * g_data->radial.a * (rx_plus_ry + delta_rxrxryry)) * inv_a;
- delta_delta_det = (delta_b_delta_b + 4 * g_data->radial.a * delta_rx_plus_ry) * inv_a;
-
- _ector_radial_helper(buffer, length, g_data, det, delta_det, delta_delta_det, b, delta_b);
-}
-
-int
-ector_software_gradient_init(void)
-{
- static int i = 0;
- if (!(i++))
- {
- _ector_radial_helper = _radial_helper_generic;
- _ector_linear_helper = _linear_helper_generic;
-#ifdef BUILD_SSE3
- if (eina_cpu_features_get() & EINA_CPU_SSE3)
- {
- _ector_radial_helper = _radial_helper_sse3;
- _ector_linear_helper = _linear_helper_sse3;
- }
-#endif
- }
- return i;
-}
+++ /dev/null
-#ifndef ECTOR_SOFTWARE_GRADIENT_H
-# define ECTOR_SOFTWARE_GRADIENT_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <assert.h>
-#include <math.h>
-
-#include <software/Ector_Software.h>
-
-#include "ector_private.h"
-#include "ector_software_private.h"
-#include "draw.h"
-
-#define GRADIENT_STOPTABLE_SIZE 1024
-#define FIXPT_BITS 8
-#define FIXPT_SIZE (1<<FIXPT_BITS)
-
-#define CTABLE_NOT_READY 0
-#define CTABLE_PROCESSING 1
-#define CTABLE_READY_DONE 2
-
-static inline int
-_gradient_clamp(const Ector_Renderer_Software_Gradient_Data *data, int ipos)
-{
- int limit;
-
- if (data->gd->s == EFL_GFX_GRADIENT_SPREAD_REPEAT)
- {
- ipos = ipos % GRADIENT_STOPTABLE_SIZE;
- ipos = ipos < 0 ? GRADIENT_STOPTABLE_SIZE + ipos : ipos;
- }
- else if (data->gd->s == EFL_GFX_GRADIENT_SPREAD_REFLECT)
- {
- limit = GRADIENT_STOPTABLE_SIZE * 2;
- ipos = ipos % limit;
- ipos = ipos < 0 ? limit + ipos : ipos;
- ipos = ipos >= GRADIENT_STOPTABLE_SIZE ? limit - 1 - ipos : ipos;
- }
- else
- {
- if (ipos < 0) ipos = 0;
- else if (ipos >= GRADIENT_STOPTABLE_SIZE)
- ipos = GRADIENT_STOPTABLE_SIZE-1;
- }
- return ipos;
-}
-
-static inline uint32_t
-_gradient_pixel_fixed(const Ector_Renderer_Software_Gradient_Data *data, int fixed_pos)
-{
- int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS;
-
- return data->color_table[_gradient_clamp(data, ipos)];
-}
-
-static inline uint32_t
-_gradient_pixel(const Ector_Renderer_Software_Gradient_Data *data, float pos)
-{
- int ipos = (int)(pos * (GRADIENT_STOPTABLE_SIZE - 1) + (float)(0.5));
-
- return data->color_table[_gradient_clamp(data, ipos)];
-}
-
-#endif
+++ /dev/null
-#include "ector_software_gradient.h"
-
-#ifdef BUILD_SSE3
-#include <immintrin.h>
-
-#define GRADIENT_STOPTABLE_SIZE_SHIFT 10
-typedef union { __m128i v; int i[4];} vec4_i;
-typedef union { __m128 v; float f[4];} vec4_f;
-
-#define FETCH_CLAMP_INIT_F \
- __m128 v_min = _mm_set1_ps(0.0f); \
- __m128 v_max = _mm_set1_ps((float)(GRADIENT_STOPTABLE_SIZE-1)); \
- __m128 v_halff = _mm_set1_ps(0.5f); \
- __m128i v_repeat_mask = _mm_set1_epi32(~((uint32_t)(0xffffff) << GRADIENT_STOPTABLE_SIZE_SHIFT)); \
- __m128i v_reflect_mask = _mm_set1_epi32(~((uint32_t)(0xffffff) << (GRADIENT_STOPTABLE_SIZE_SHIFT+1))); \
- __m128i v_reflect_limit = _mm_set1_epi32(2 * GRADIENT_STOPTABLE_SIZE - 1);
-
-#define FETCH_CLAMP_REPEAT_F \
- vec4_i index_vec; \
- index_vec.v = _mm_and_si128(v_repeat_mask, _mm_cvttps_epi32(v_index));
-
-#define FETCH_CLAMP_REFLECT_F \
- vec4_i index_vec; \
- __m128i v_index_i = _mm_and_si128(v_reflect_mask, _mm_cvttps_epi32(v_index)); \
- __m128i v_index_i_inv = _mm_sub_epi32(v_reflect_limit, v_index_i); \
- index_vec.v = _mm_min_epi16(v_index_i, v_index_i_inv);
-
-#define FETCH_CLAMP_PAD_F \
- vec4_i index_vec; \
- index_vec.v = _mm_cvttps_epi32(_mm_min_ps(v_max, _mm_max_ps(v_min, v_index)));
-
-#define FETCH_EPILOGUE_CPY \
- *buffer++ = g_data->color_table[index_vec.i[0]]; \
- *buffer++ = g_data->color_table[index_vec.i[1]]; \
- *buffer++ = g_data->color_table[index_vec.i[2]]; \
- *buffer++ = g_data->color_table[index_vec.i[3]]; \
-}
-
-static void
-loop_break(unsigned int *buffer, int length, int *lprealign, int *lby4 , int *lremaining)
-{
- int l1=0, l2=0, l3=0;
-
- while ((uintptr_t)buffer & 0xF)
- buffer++ , l1++;
-
- if(length <= l1)
- {
- l1 = length;
- }
- else
- {
- l3 = (length - l1) % 4;
- l2 = length - l1 - l3 ;
- }
-
- *lprealign = l1;
- *lby4 = l2;
- *lremaining = l3;
-}
-
-void
-_radial_helper_sse3(uint32_t *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data,
- float det, float delta_det, float delta_delta_det, float b, float delta_b)
-{
- int lprealign, lby4, lremaining, i;
- vec4_f det_vec;
- vec4_f delta_det4_vec;
- vec4_f b_vec;
- __m128 v_delta_delta_det16;
- __m128 v_delta_delta_det6;
- __m128 v_delta_b4;
-
- loop_break(buffer, length, &lprealign, &lby4, &lremaining);
-
- // prealign loop
- for (i = 0 ; i < lprealign ; i++)
- {
- *buffer++ = _gradient_pixel(g_data, sqrt(det) - b);
- det += delta_det;
- delta_det += delta_delta_det;
- b += delta_b;
- }
-
- // lby4 16byte align loop
- for (i = 0; i < 4; ++i)
- {
- det_vec.f[i] = det;
- delta_det4_vec.f[i] = 4 * delta_det;
- b_vec.f[i] = b;
-
- det += delta_det;
- delta_det += delta_delta_det;
- b += delta_b;
- }
-
- v_delta_delta_det16 = _mm_set1_ps(16 * delta_delta_det);
- v_delta_delta_det6 = _mm_set1_ps(6 * delta_delta_det);
- v_delta_b4 = _mm_set1_ps(4 * delta_b);
-
-#define FETCH_RADIAL_PROLOGUE \
- for (i = 0 ; i < lby4 ; i+=4) { \
- __m128 v_index_local = _mm_sub_ps(_mm_sqrt_ps(det_vec.v), b_vec.v); \
- __m128 v_index = _mm_add_ps(_mm_mul_ps(v_index_local, v_max), v_halff); \
- det_vec.v = _mm_add_ps(_mm_add_ps(det_vec.v, delta_det4_vec.v), v_delta_delta_det6); \
- delta_det4_vec.v = _mm_add_ps(delta_det4_vec.v, v_delta_delta_det16); \
- b_vec.v = _mm_add_ps(b_vec.v, v_delta_b4);
-
-#define FETCH_RADIAL_LOOP(FETCH_CLAMP) \
- FETCH_RADIAL_PROLOGUE; \
- FETCH_CLAMP; \
- FETCH_EPILOGUE_CPY;
-
- FETCH_CLAMP_INIT_F;
- switch (g_data->gd->s)
- {
- case EFL_GFX_GRADIENT_SPREAD_REPEAT:
- FETCH_RADIAL_LOOP(FETCH_CLAMP_REPEAT_F);
- break;
- case EFL_GFX_GRADIENT_SPREAD_REFLECT:
- FETCH_RADIAL_LOOP( FETCH_CLAMP_REFLECT_F);
- break;
- default:
- FETCH_RADIAL_LOOP(FETCH_CLAMP_PAD_F);
- break;
- }
-
- // remaining loop
- for (i = 0 ; i < lremaining ; i++)
- *buffer++ = _gradient_pixel(g_data, sqrt(det_vec.f[i]) - b_vec.f[i]);
-}
-
-void
-_linear_helper_sse3(uint32_t *buffer, int length, Ector_Renderer_Software_Gradient_Data *g_data, int t, int inc)
-{
- int lprealign, lby4, lremaining, i;
- vec4_i t_vec;
- __m128i v_inc;
- __m128i v_fxtpt_size;
- __m128i v_min;
- __m128i v_max;
- __m128i v_repeat_mask;
- __m128i v_reflect_mask;
- __m128i v_reflect_limit;
-
- loop_break(buffer, length, &lprealign, &lby4, &lremaining);
-
- // prealign loop
- for (i = 0 ; i < lprealign ; i++)
- {
- *buffer++ = _gradient_pixel_fixed(g_data, t);
- t += inc;
- }
-
- // lby4 16byte align loop
- for (i = 0; i < 4; ++i)
- {
- t_vec.i[i] = t;
- t += inc;
- }
-
- v_inc = _mm_set1_epi32(4 * inc);
- v_fxtpt_size = _mm_set1_epi32(FIXPT_SIZE * 0.5);
-
- v_min = _mm_set1_epi32(0);
- v_max = _mm_set1_epi32((GRADIENT_STOPTABLE_SIZE - 1));
-
- v_repeat_mask = _mm_set1_epi32(~((uint32_t)(0xffffff) << GRADIENT_STOPTABLE_SIZE_SHIFT));
- v_reflect_mask = _mm_set1_epi32(~((uint32_t)(0xffffff) << (GRADIENT_STOPTABLE_SIZE_SHIFT + 1)));
-
- v_reflect_limit = _mm_set1_epi32(2 * GRADIENT_STOPTABLE_SIZE - 1);
-
-#define FETCH_LINEAR_LOOP_PROLOGUE \
- for (i = 0 ; i < lby4 ; i+=4) { \
- vec4_i index_vec; \
- __m128i v_index; \
- v_index = _mm_srai_epi32(_mm_add_epi32(t_vec.v, v_fxtpt_size), FIXPT_BITS); \
- t_vec.v = _mm_add_epi32(t_vec.v, v_inc);
-
-#define FETCH_LINEAR_LOOP_CLAMP_REPEAT \
- index_vec.v = _mm_and_si128(v_repeat_mask, v_index);
-
-#define FETCH_LINEAR_LOOP_CLAMP_REFLECT \
- __m128i v_index_i = _mm_and_si128(v_reflect_mask, v_index); \
- __m128i v_index_i_inv = _mm_sub_epi32(v_reflect_limit, v_index_i); \
- index_vec.v = _mm_min_epi16(v_index_i, v_index_i_inv);
-
-#define FETCH_LINEAR_LOOP_CLAMP_PAD \
- index_vec.v = _mm_min_epi16(v_max, _mm_max_epi16(v_min, v_index));
-
-#define FETCH_LINEAR_LOOP(FETCH_LINEAR_LOOP_CLAMP) \
- FETCH_LINEAR_LOOP_PROLOGUE; \
- FETCH_LINEAR_LOOP_CLAMP; \
- FETCH_EPILOGUE_CPY;
-
- switch (g_data->gd->s)
- {
- case EFL_GFX_GRADIENT_SPREAD_REPEAT:
- FETCH_LINEAR_LOOP(FETCH_LINEAR_LOOP_CLAMP_REPEAT);
- break;
- case EFL_GFX_GRADIENT_SPREAD_REFLECT:
- FETCH_LINEAR_LOOP(FETCH_LINEAR_LOOP_CLAMP_REFLECT);
- break;
- default:
- FETCH_LINEAR_LOOP(FETCH_LINEAR_LOOP_CLAMP_PAD);
- break;
- }
-
- // remaining loop
- for (i = 0 ; i < lremaining ; i++)
- *buffer++ = _gradient_pixel_fixed(g_data, t_vec.i[i]);
-}
-
-#endif
+++ /dev/null
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <Eina.h>
-#include <Ector.h>
-#include <software/Ector_Software.h>
-
-#include "ector_private.h"
-#include "ector_software_private.h"
-
-#include "draw.h"
-
-static void
-_blend_argb(int count, const SW_FT_Span *spans, void *user_data)
-{
- Span_Data *sd = user_data;
- uint32_t color, *buffer, *target;
- const int pix_stride = sd->raster_buffer->stride / 4;
-
- // multiply the color with mul_col if any
- color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
- RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
-
- // move to the offset location
- buffer = sd->raster_buffer->pixels.u32 + ((pix_stride * sd->offy) + sd->offx);
-
- while (count--)
- {
- target = buffer + ((pix_stride * spans->y) + spans->x);
- comp_func(target, spans->len, color, spans->coverage);
- ++spans;
- }
-}
-
-static void
-_comp_matte_alpha(int count, const SW_FT_Span *spans, void *user_data)
-{
- Span_Data *sd = user_data;
- const int pix_stride = sd->raster_buffer->stride / 4;
- Ector_Software_Buffer_Base_Data *comp = sd->comp;
- if (!comp || !comp->pixels.u32) return;
- const int comp_stride = comp->stride / 4;
-
- // multiply the color with mul_col if any
- uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
- RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
-
- // move to the offset location
- uint32_t *buffer =
- sd->raster_buffer->pixels.u32 + ((pix_stride * sd->offy) + sd->offx);
- uint32_t *mbuffer = comp->pixels.u32;
-
- //Temp buffer for intermediate processing
- int tsize = sd->raster_buffer->generic->w;
- uint32_t *tbuffer = alloca(sizeof(uint32_t) * tsize);
-
- while (count--)
- {
- uint32_t *target = buffer + ((pix_stride * spans->y) + spans->x);
- uint32_t *mtarget =
- mbuffer + ((comp_stride * spans->y) + spans->x);
- uint32_t *temp = tbuffer;
- memset(temp, 0x00, sizeof(uint32_t) * spans->len);
- comp_func(temp, spans->len, color, spans->coverage);
-
- //composite
- for (int i = 0; i < spans->len; i++)
- {
- *temp = draw_mul_256(((*mtarget)>>24), *temp);
- int alpha = 255 - ((*temp) >> 24);
- *target = *temp + draw_mul_256(alpha, *target);
- ++temp;
- ++mtarget;
- ++target;
- }
- ++spans;
- }
-}
-
-static void
-_comp_matte_alpha_inv(int count, const SW_FT_Span *spans, void *user_data)
-{
- Span_Data *sd = user_data;
- const int pix_stride = sd->raster_buffer->stride / 4;
- Ector_Software_Buffer_Base_Data *comp = sd->comp;
- if (!comp || !comp->pixels.u32) return;
- const int comp_stride = comp->stride / 4;
-
- // multiply the color with mul_col if any
- uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
- RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
-
- // move to the offset location
- uint32_t *buffer =
- sd->raster_buffer->pixels.u32 + ((pix_stride * sd->offy) + sd->offx);
- uint32_t *mbuffer = comp->pixels.u32;
-
- //Temp buffer for intermediate processing
- int tsize = sd->raster_buffer->generic->w;
- uint32_t *tbuffer = alloca(sizeof(uint32_t) * tsize);
-
- while (count--)
- {
- uint32_t *target = buffer + ((pix_stride * spans->y) + spans->x);
- uint32_t *mtarget =
- mbuffer + ((comp_stride * spans->y) + spans->x);
- uint32_t *temp = tbuffer;
- memset(temp, 0x00, sizeof(uint32_t) * spans->len);
- comp_func(temp, spans->len, color, spans->coverage);
-
- //composite
- for (int i = 0; i < spans->len; i++)
- {
- if (*mtarget)
- *temp = draw_mul_256((255 - ((*mtarget)>>24)), *temp);
- int alpha = 255 - ((*temp) >> 24);
- *target = *temp + draw_mul_256(alpha, *target);
- ++temp;
- ++mtarget;
- ++target;
- }
- ++spans;
- }
-}
-
-static void
-_comp_mask_add(int count, const SW_FT_Span *spans, void *user_data)
-{
- Span_Data *sd = user_data;
- Ector_Software_Buffer_Base_Data *comp = sd->comp;
- if (!comp || !comp->pixels.u32) return;
- const int comp_stride = comp->stride / 4;
-
- uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
- RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
- uint32_t *mbuffer = comp->pixels.u32;
-
- int tsize = sd->raster_buffer->generic->w;
- uint32_t *ttarget = alloca(sizeof(uint32_t) * tsize);
-
- while (count--)
- {
- uint32_t *mtarget = mbuffer + ((comp_stride * spans->y) + spans->x);
- memset(ttarget, 0x00, sizeof(uint32_t) * spans->len);
- comp_func(ttarget, spans->len, color, spans->coverage);
- for (int i = 0; i < spans->len; i++)
- mtarget[i] = draw_mul_256(0xFF - (ttarget[i]>>24), mtarget[i]) + ttarget[i];
- ++spans;
- }
-}
-
-static void
-_comp_mask_sub(int count, const SW_FT_Span *spans, void *user_data)
-{
- Span_Data *sd = user_data;
- Ector_Software_Buffer_Base_Data *comp = sd->comp;
- if (!comp || !comp->pixels.u32) return;
- const int comp_stride = comp->stride / 4;
-
- uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
- RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
- uint32_t *mbuffer = comp->pixels.u32;
-
- int tsize = sd->raster_buffer->generic->w;
- uint32_t *ttarget = alloca(sizeof(uint32_t) * tsize);
-
- while (count--)
- {
- uint32_t *mtarget = mbuffer + ((comp_stride * spans->y) + spans->x);
- memset(ttarget, 0x00, sizeof(uint32_t) * spans->len);
- comp_func(ttarget, spans->len, color, spans->coverage);
- for (int i = 0; i < spans->len; i++)
- mtarget[i] = draw_mul_256(0xFF - (ttarget[i]>>24), mtarget[i]);
- ++spans;
- }
-}
-
-
-static void
-_comp_mask_ins(int count, const SW_FT_Span *spans, void *user_data)
-{
- Span_Data *sd = user_data;
- Ector_Software_Buffer_Base_Data *comp = sd->comp;
- if (!comp || !comp->pixels.u32) return;
- const int comp_stride = comp->stride / 4;
-
- uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
- RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
- uint32_t *mbuffer = comp->pixels.u32;
-
- int tsize = sd->raster_buffer->generic->w;
- uint32_t *ttarget = alloca(sizeof(uint32_t) * tsize);
-
- for(unsigned int y = 0; y < comp->generic->h; y++)
- {
- for(unsigned int x = 0; x < comp->generic->w; x++)
- {
- if (x == (unsigned int)spans->x && x + spans->len <= comp->generic->w &&
- y == (unsigned int)spans->y && count > 0)
- {
- memset(ttarget, 0x00, sizeof(uint32_t) * spans->len);
- uint32_t *mtarget = mbuffer + ((comp_stride * spans->y) + spans->x);
- comp_func(ttarget, spans->len, color, spans->coverage);
- for (int c = 0; c < spans->len; c++)
- mtarget[c] = draw_mul_256(ttarget[c]>>24, mtarget[c]);
- x += spans->len - 1;
- ++spans;
- --count;
- }
- else
- {
- mbuffer[x + (comp_stride * y)] = (0x00FFFFFF & mbuffer[x + (comp_stride * y)]);
- }
- }
- }
-}
-
-
-static void
-_comp_mask_diff(int count, const SW_FT_Span *spans, void *user_data)
-{
- Span_Data *sd = user_data;
- Ector_Software_Buffer_Base_Data *comp = sd->comp;
- if (!comp || !comp->pixels.u32) return;
- const int comp_stride = comp->stride / 4;
-
- uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col);
- RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color);
- uint32_t *mbuffer = comp->pixels.u32;
-
- int tsize = sd->raster_buffer->generic->w;
- uint32_t *ttarget = alloca(sizeof(uint32_t) * tsize);
-
- while (count--)
- {
- memset(ttarget, 0x00, sizeof(uint32_t) * spans->len);
- uint32_t *mtarget = mbuffer + ((comp_stride * spans->y) + spans->x);
- comp_func(ttarget, spans->len, color, spans->coverage);
- for (int i = 0; i < spans->len; i++)
- mtarget[i] = draw_mul_256(0xFF - (mtarget[i]>>24), ttarget[i]) + draw_mul_256(0xFF - (ttarget[i]>>24), mtarget[i]);
- ++spans;
- }
-}
-
-#define BLEND_GRADIENT_BUFFER_SIZE 2048
-
-typedef void (*src_fetch) (unsigned int *buffer, Span_Data *data, int y, int x, int length);
-
-static void
-_blend_gradient(int count, const SW_FT_Span *spans, void *user_data)
-{
- RGBA_Comp_Func comp_func;
- Span_Data *sd = (Span_Data *)(user_data);
- src_fetch fetchfunc = NULL;
- unsigned int buffer[BLEND_GRADIENT_BUFFER_SIZE], *target, *destbuffer;
- int length, l;
- const int pix_stride = sd->raster_buffer->stride / 4;
-
- // FIXME: Get the proper composition function using ,color, ECTOR_OP etc.
- if (sd->type == LinearGradient) fetchfunc = &fetch_linear_gradient;
- if (sd->type == RadialGradient) fetchfunc = &fetch_radial_gradient;
-
- if (!fetchfunc || !sd->raster_buffer->pixels.u32) return;
-
- comp_func = efl_draw_func_span_get(sd->op, sd->mul_col, sd->gradient->alpha);
-
- // move to the offset location
- destbuffer = sd->raster_buffer->pixels.u32 + ((pix_stride * sd->offy) + sd->offx);
-
- while (count--)
- {
- target = destbuffer + ((pix_stride * spans->y) + spans->x);
- length = spans->len;
- while (length)
- {
- l = MIN(length, BLEND_GRADIENT_BUFFER_SIZE);
- //FIXME: span->x must have adding an offset as much as subtracted length...
- fetchfunc(buffer, sd, spans->y, spans->x, l);
- comp_func(target, buffer, l, sd->mul_col, spans->coverage);
- target += l;
- length -= l;
- }
- ++spans;
- }
-}
-
-static void
-_blend_gradient_alpha(int count, const SW_FT_Span *spans, void *user_data)
-{
- Span_Data *sd = (Span_Data *)(user_data);
- src_fetch fetchfunc = NULL;
- uint32_t *buffer;
- const int pix_stride = sd->raster_buffer->stride / 4;
- uint32_t gbuffer[BLEND_GRADIENT_BUFFER_SIZE]; //gradient buffer
-
- // FIXME: Get the proper composition function using ,color, ECTOR_OP etc.
- if (sd->type == LinearGradient) fetchfunc = &fetch_linear_gradient;
- if (sd->type == RadialGradient) fetchfunc = &fetch_radial_gradient;
-
- if (!fetchfunc) return;
-
- Ector_Software_Buffer_Base_Data *comp = sd->comp;
- uint32_t *mbuffer = comp->pixels.u32;
- const int comp_stride = comp->stride / 4;
-
- // move to the offset location
- buffer = sd->raster_buffer->pixels.u32 + ((pix_stride * sd->offy) + sd->offx);
-
- while (count--)
- {
- uint32_t *target = buffer + ((pix_stride * spans->y) + spans->x);
- uint32_t *mtarget = mbuffer + ((comp_stride * spans->y) + spans->x);
- int length = spans->len;
-
- while (length)
- {
- int l = MIN(length, BLEND_GRADIENT_BUFFER_SIZE);
- //FIXME: span->x must have adding an offset as much as subtracted length...
- fetchfunc(gbuffer, sd, spans->y, spans->x, l);
- uint32_t *temp = gbuffer;
-
- for (int i = 0; i < l; i++)
- {
- *temp = draw_mul_256(((*mtarget)>>24), *temp);
- int alpha = 255 - ((*temp) >> 24);
- *target = *temp + draw_mul_256(alpha, *target);
- ++temp;
- ++mtarget;
- ++target;
- }
- length -= l;
- }
- ++spans;
- }
-}
-
-static void
-_blend_gradient_alpha_inv(int count, const SW_FT_Span *spans, void *user_data)
-{
- Span_Data *sd = (Span_Data *)(user_data);
- src_fetch fetchfunc = NULL;
- uint32_t *buffer;
- const int pix_stride = sd->raster_buffer->stride / 4;
- uint32_t gbuffer[BLEND_GRADIENT_BUFFER_SIZE]; //gradient buffer
-
- // FIXME: Get the proper composition function using ,color, ECTOR_OP etc.
- if (sd->type == LinearGradient) fetchfunc = &fetch_linear_gradient;
- if (sd->type == RadialGradient) fetchfunc = &fetch_radial_gradient;
-
- if (!fetchfunc) return;
-
- Ector_Software_Buffer_Base_Data *comp = sd->comp;
- uint32_t *mbuffer = comp->pixels.u32;
- const int comp_stride = comp->stride / 4;
-
- // move to the offset location
- buffer = sd->raster_buffer->pixels.u32 + ((pix_stride * sd->offy) + sd->offx);
-
- while (count--)
- {
- uint32_t *target = buffer + ((pix_stride * spans->y) + spans->x);
- uint32_t *mtarget = mbuffer + ((comp_stride * spans->y) + spans->x);
- int length = spans->len;
-
- while (length)
- {
- int l = MIN(length, BLEND_GRADIENT_BUFFER_SIZE);
- //FIXME: span->x must have adding an offset as much as subtracted length...
- fetchfunc(gbuffer, sd, spans->y, spans->x, l);
- uint32_t *temp = gbuffer;
-
- for (int i = 0; i < l; i++)
- {
- if (*mtarget)
- *temp = draw_mul_256((255 - ((*mtarget)>>24)), *temp);
- int alpha = 255 - ((*temp) >> 24);
- *target = *temp + draw_mul_256(alpha, *target);
- ++temp;
- ++mtarget;
- ++target;
- }
- length -= l;
- }
- ++spans;
- }
-}
-/*!
- \internal
- spans must be sorted on y
-*/
-static const
-SW_FT_Span *_intersect_spans_rect(const Eina_Rectangle *clip,
- const SW_FT_Span *spans,
- const SW_FT_Span *end,
- SW_FT_Span **out_spans,
- int available)
-{
- SW_FT_Span *out = *out_spans;
- short minx, miny, maxx, maxy;
- minx = clip->x;
- miny = clip->y;
- maxx = minx + clip->w - 1;
- maxy = miny + clip->h - 1;
-
- while (available && spans < end )
- {
- if (spans->y > maxy)
- {
- spans = end;// update spans so that we can breakout
- break;
- }
- if (spans->y < miny
- || spans->x > maxx
- || spans->x + spans->len <= minx)
- {
- ++spans;
- continue;
- }
- if (spans->x < minx)
- {
- out->len = MIN(spans->len - (minx - spans->x), maxx - minx + 1);
- out->x = minx;
- }
- else
- {
- out->x = spans->x;
- out->len = MIN(spans->len, (maxx - spans->x + 1));
- }
- if (out->len != 0)
- {
- out->y = spans->y;
- out->coverage = spans->coverage;
- ++out;
- }
- ++spans;
- --available;
- }
-
- *out_spans = out;
- return spans;
-}
-
-static inline int
-_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
-
-static const
-SW_FT_Span *_intersect_spans_region(const Shape_Rle_Data *clip,
- int *currentClip,
- const SW_FT_Span *spans,
- const SW_FT_Span *end,
- SW_FT_Span **out_spans,
- int available)
-{
- SW_FT_Span *out = *out_spans;
- int sx1, sx2, cx1, cx2, x, len;
-
- const SW_FT_Span *clipSpans = clip->spans + *currentClip;
- const SW_FT_Span *clipEnd = clip->spans + clip->size;
-
- while (available && spans < end )
- {
- if (clipSpans >= clipEnd)
- {
- spans = end;
- break;
- }
- if (clipSpans->y > spans->y)
- {
- ++spans;
- continue;
- }
- if (spans->y != clipSpans->y)
- {
- ++clipSpans;
- continue;
- }
- //assert(spans->y == clipSpans->y);
- sx1 = spans->x;
- sx2 = sx1 + spans->len;
- cx1 = clipSpans->x;
- cx2 = cx1 + clipSpans->len;
-
- if (cx1 < sx1 && cx2 < sx1)
- {
- ++clipSpans;
- continue;
- }
- else if (sx1 < cx1 && sx2 < cx1)
- {
- ++spans;
- continue;
- }
- x = MAX(sx1, cx1);
- len = MIN(sx2, cx2) - x;
- if (len)
- {
- out->x = MAX(sx1, cx1);
- out->len = MIN(sx2, cx2) - out->x;
- out->y = spans->y;
- out->coverage = _div_255(spans->coverage * clipSpans->coverage);
- ++out;
- --available;
- }
- if (sx2 < cx2)
- {
- ++spans;
- }
- else
- {
- ++clipSpans;
- }
- }
-
- *out_spans = out;
- *currentClip = clipSpans - clip->spans;
- return spans;
-}
-
-static void
-_span_fill_clipRect(int span_count, const SW_FT_Span *spans, void *user_data)
-{
- const int NSPANS = 256;
- int clip_count, i;
- Span_Data *fill_data = (Span_Data *) user_data;
- Clip_Data clip = fill_data->clip;
- SW_FT_Span *clipped;
- Eina_Rectangle *rect;
- Eina_Rectangle tmp_rect;
- SW_FT_Span *cspans = NULL;
- Eina_Bool intersect = EINA_FALSE;
-
- //Note: Uses same span_count sized heap memory in intersect mask case.
- if (fill_data->comp_method == EFL_GFX_VG_COMPOSITE_METHOD_MASK_INTERSECT)
- {
- intersect = EINA_TRUE;
- cspans = malloc(sizeof(SW_FT_Span) * (span_count));
- if (!cspans)
- {
- ERR("OOM: Failed malloc()");
- return ;
- }
- }
- else
- {
- cspans = alloca(sizeof(SW_FT_Span) * (NSPANS));
- }
-
- clip_count = eina_array_count(clip.clips);
-
- for (i = 0; i < clip_count; i++)
- {
- rect = (Eina_Rectangle *)eina_array_data_get(clip.clips, i);
-
- // invert transform the offset
- tmp_rect.x = rect->x - fill_data->offx;
- tmp_rect.y = rect->y - fill_data->offy;
- tmp_rect.w = rect->w;
- tmp_rect.h = rect->h;
- const SW_FT_Span *end = spans + span_count;
-
- while (spans < end)
- {
- clipped = cspans;
- spans = _intersect_spans_rect(&tmp_rect, spans, end, &clipped, intersect ? span_count : NSPANS);
- if (clipped - cspans)
- fill_data->unclipped_blend(clipped - cspans, cspans, fill_data);
- }
- }
- if (intersect && cspans) free(cspans);
-}
-
-static void
-_span_fill_clipPath(int span_count, const SW_FT_Span *spans, void *user_data)
-{
- const int NSPANS = 256;
- int current_clip = 0;
- Span_Data *fill_data = (Span_Data *) user_data;
- Clip_Data clip = fill_data->clip;
- SW_FT_Span *clipped;
- SW_FT_Span *cspans = NULL;
- Eina_Bool intersect = EINA_FALSE;
-
- //Note: Uses same span_count sized heap memory in intersect mask case.
- if (fill_data->comp_method == EFL_GFX_VG_COMPOSITE_METHOD_MASK_INTERSECT)
- {
- intersect = EINA_TRUE;
- cspans = malloc(sizeof(SW_FT_Span) * (span_count));
- if (!cspans)
- {
- ERR("OOM: Failed malloc()");
- return ;
- }
- }
- else
- {
- cspans = alloca(sizeof(SW_FT_Span) * (NSPANS));
- }
-
- // FIXME: Take clip path offset into account.
- const SW_FT_Span *end = spans + span_count;
- while (spans < end)
- {
- clipped = cspans;
- spans = _intersect_spans_region(clip.path, ¤t_clip, spans, end, &clipped, intersect ? span_count : NSPANS);
- if (clipped - cspans)
- fill_data->unclipped_blend(clipped - cspans, cspans, fill_data);
- }
- if (intersect && cspans) free(cspans);
-}
-
-static void
-_adjust_span_fill_methods(Span_Data *spdata)
-{
- //Blending Function
- if (spdata->comp)
- {
- switch (spdata->comp_method)
- {
- default:
- case EFL_GFX_VG_COMPOSITE_METHOD_MATTE_ALPHA:
- if (spdata->type == Solid)
- spdata->unclipped_blend = &_comp_matte_alpha;
- else if (spdata->type == LinearGradient || spdata->type == RadialGradient)
- spdata->unclipped_blend = &_blend_gradient_alpha;
- else //None
- spdata->unclipped_blend = NULL;
- break;
- case EFL_GFX_VG_COMPOSITE_METHOD_MATTE_ALPHA_INVERSE:
- if (spdata->type == Solid)
- spdata->unclipped_blend = &_comp_matte_alpha_inv;
- else if (spdata->type == LinearGradient || spdata->type == RadialGradient)
- spdata->unclipped_blend = &_blend_gradient_alpha_inv;
- else //None
- spdata->unclipped_blend = NULL;
- break;
- case EFL_GFX_VG_COMPOSITE_METHOD_MASK_ADD:
- spdata->unclipped_blend = &_comp_mask_add;
- break;
- case EFL_GFX_VG_COMPOSITE_METHOD_MASK_SUBSTRACT:
- spdata->unclipped_blend = &_comp_mask_sub;
- break;
- case EFL_GFX_VG_COMPOSITE_METHOD_MASK_INTERSECT:
- spdata->unclipped_blend = &_comp_mask_ins;
- break;
- case EFL_GFX_VG_COMPOSITE_METHOD_MASK_DIFFERENCE:
- spdata->unclipped_blend = &_comp_mask_diff;
- break;
- }
- }
- else
- {
- if (spdata->type == Solid)
- spdata->unclipped_blend = &_blend_argb;
- else if (spdata->type == LinearGradient || spdata->type == RadialGradient)
- spdata->unclipped_blend = &_blend_gradient;
- else //None
- spdata->unclipped_blend = NULL;
- }
-
- // Clipping Function
- if (spdata->clip.enabled)
- {
- if (spdata->clip.type == 0)
- spdata->blend = &_span_fill_clipRect;
- else
- spdata->blend = &_span_fill_clipPath;
- }
- else
- spdata->blend = spdata->unclipped_blend;
-}
-
-void ector_software_thread_init(Ector_Software_Thread *thread)
-{
- // initialize the rasterizer and stroker
- sw_ft_grays_raster.raster_new(&thread->raster);
-
- SW_FT_Stroker_New(&thread->stroker);
- SW_FT_Stroker_Set(thread->stroker, 1 << 6,
- SW_FT_STROKER_LINECAP_BUTT, SW_FT_STROKER_LINEJOIN_MITER_FIXED, 0x4<<16);
-}
-
-void ector_software_rasterizer_init(Software_Rasterizer *rasterizer)
-{
- //initialize the span data.
- rasterizer->fill_data.clip.enabled = EINA_FALSE;
- rasterizer->fill_data.unclipped_blend = 0;
- rasterizer->fill_data.blend = 0;
- efl_draw_init();
- ector_software_gradient_init();
-}
-
-void ector_software_thread_shutdown(Ector_Software_Thread *thread)
-{
- sw_ft_grays_raster.raster_done(thread->raster);
- SW_FT_Stroker_Done(thread->stroker);
-}
-
-void ector_software_rasterizer_stroke_set(Ector_Software_Thread *thread,
- Software_Rasterizer *rasterizer EINA_UNUSED, double width,
- Efl_Gfx_Cap cap_style, Efl_Gfx_Join join_style,
- Eina_Matrix3 *m, double miterlimit)
-{
- SW_FT_Stroker_LineCap cap;
- SW_FT_Stroker_LineJoin join;
- int stroke_width;
- double scale_factor = 1.0;
-
- // convert to freetype co-ordinate
- SW_FT_Fixed miter_limit = miterlimit * (1<<16);
-
- if (m)
- {
- // get the minimum scale factor from matrix
- scale_factor = m->xx < m->yy ? m->xx : m->yy;
- }
- width = width * scale_factor;
- width = width/2.0; // as free type uses it as the radius of the
- // pen not the diameter.
- // convert to freetype co-ordinate
- stroke_width = (int)(width * 64);
-
- switch (cap_style)
- {
- case EFL_GFX_CAP_SQUARE:
- cap = SW_FT_STROKER_LINECAP_SQUARE;
- break;
- case EFL_GFX_CAP_ROUND:
- cap = SW_FT_STROKER_LINECAP_ROUND;
- break;
- default:
- cap = SW_FT_STROKER_LINECAP_BUTT;
- break;
- }
-
- switch (join_style)
- {
- case EFL_GFX_JOIN_BEVEL:
- join = SW_FT_STROKER_LINEJOIN_BEVEL;
- break;
- case EFL_GFX_JOIN_ROUND:
- join = SW_FT_STROKER_LINEJOIN_ROUND;
- break;
- default:
- join = SW_FT_STROKER_LINEJOIN_MITER_FIXED;
- break;
- }
- SW_FT_Stroker_Set(thread->stroker, stroke_width, cap, join, miter_limit);
-}
-
-static void
-_rle_generation_cb( int count, const SW_FT_Span* spans,void *user)
-{
- Shape_Rle_Data *rle = (Shape_Rle_Data *) user;
- int newsize = rle->size + count;
-
- // allocate enough memory for new spans
- // alloc is required to prevent free and reallocation
- // when the rle needs to be regenerated because of attribute change.
- if (rle->alloc < newsize)
- {
- rle->spans = (SW_FT_Span *) realloc(rle->spans, newsize * sizeof(SW_FT_Span));
- rle->alloc = newsize;
- }
-
- // copy the new spans to the allocated memory
- SW_FT_Span *lastspan = (rle->spans + rle->size);
- memcpy(lastspan,spans, count * sizeof(SW_FT_Span));
-
- // update the size
- rle->size = newsize;
-}
-
-Shape_Rle_Data *
-ector_software_rasterizer_generate_rle_data(Ector_Software_Thread *thread,
- Software_Rasterizer *rasterizer EINA_UNUSED,
- SW_FT_Outline *outline)
-{
- int i, rle_size;
- int l = 0, t = 0, r = 0, b = 0;
- Shape_Rle_Data *rle_data = (Shape_Rle_Data *) calloc(1, sizeof(Shape_Rle_Data));
- SW_FT_Raster_Params params;
- SW_FT_Span* span;
-
- params.flags = SW_FT_RASTER_FLAG_DIRECT | SW_FT_RASTER_FLAG_AA ;
- params.gray_spans = &_rle_generation_cb;
- params.user = rle_data;
- params.source = outline;
-
- sw_ft_grays_raster.raster_render(thread->raster, ¶ms);
-
- // update RLE bounding box.
- span = rle_data->spans;
- rle_size = rle_data->size;
- if (rle_size)
- {
- t = span[0].y;
- b = span[rle_size-1].y;
- for (i = 0; i < rle_size; i++)
- {
- if (span[i].x < l) l = span[i].x;
- if (span[i].x + span[i].len > r) r = span[i].x + span[i].len;
- }
- rle_data->bbox.x = l;
- rle_data->bbox.y = t;
- rle_data->bbox.w = r - l;
- rle_data->bbox.h = b - t + 1;
- }
- return rle_data;
-}
-
-Shape_Rle_Data *
-ector_software_rasterizer_generate_stroke_rle_data(Ector_Software_Thread *thread,
- Software_Rasterizer *rasterizer,
- SW_FT_Outline *outline,
- Eina_Bool closePath)
-{
- uint32_t points,contors;
- Shape_Rle_Data *rle_data;
- SW_FT_Outline strokeOutline = { 0, 0, NULL, NULL, NULL, 0 };
-
- SW_FT_Stroker_ParseOutline(thread->stroker, outline, !closePath);
- SW_FT_Stroker_GetCounts(thread->stroker,&points, &contors);
-
- strokeOutline.points = (SW_FT_Vector *) calloc(points, sizeof(SW_FT_Vector));
- strokeOutline.tags = (char *) calloc(points, sizeof(char));
- strokeOutline.contours = (short *) calloc(contors, sizeof(short));
-
- SW_FT_Stroker_Export(thread->stroker, &strokeOutline);
-
- rle_data = ector_software_rasterizer_generate_rle_data(thread, rasterizer, &strokeOutline);
-
- // cleanup the outline data.
- free(strokeOutline.points);
- free(strokeOutline.tags);
- free(strokeOutline.contours);
-
- return rle_data;
-}
-
-void
-ector_software_rasterizer_destroy_rle_data(Shape_Rle_Data *rle)
-{
- if (rle)
- {
- if (rle->spans)
- free(rle->spans);
- free(rle);
- }
-}
-
-static
-void _setup_span_fill_matrix(Software_Rasterizer *rasterizer)
-{
- if (rasterizer->transform)
- eina_matrix3_inverse(rasterizer->transform, &rasterizer->fill_data.inv);
- else
- eina_matrix3_identity(&rasterizer->fill_data.inv);
-}
-
-void
-ector_software_rasterizer_transform_set(Software_Rasterizer *rasterizer, Eina_Matrix3 *t)
-{
- rasterizer->transform = t;
-}
-
-void
-ector_software_rasterizer_clip_rect_set(Software_Rasterizer *rasterizer, Eina_Array *clips)
-{
- if (clips)
- {
- rasterizer->fill_data.clip.clips = clips;
- rasterizer->fill_data.clip.type = 0;
- rasterizer->fill_data.clip.enabled = EINA_TRUE;
- }
- else
- {
- rasterizer->fill_data.clip.clips = NULL;
- rasterizer->fill_data.clip.type = 0;
- rasterizer->fill_data.clip.enabled = EINA_FALSE;
- }
-}
-
-void
-ector_software_rasterizer_clip_shape_set(Software_Rasterizer *rasterizer, Shape_Rle_Data *clip)
-{
- if (clip)
- {
- rasterizer->fill_data.clip.path = clip;
- rasterizer->fill_data.clip.type = 1;
- rasterizer->fill_data.clip.enabled = EINA_TRUE;
- }
- else
- {
- rasterizer->fill_data.clip.path = NULL;
- rasterizer->fill_data.clip.type = 0;
- rasterizer->fill_data.clip.enabled = EINA_FALSE;
- }
-}
-
-void
-ector_software_rasterizer_color_set(Software_Rasterizer *rasterizer, int r, int g, int b, int a)
-{
- rasterizer->fill_data.color = DRAW_ARGB_JOIN(a, r, g, b);
- rasterizer->fill_data.type = Solid;
-}
-
-void ector_software_rasterizer_linear_gradient_set(Software_Rasterizer *rasterizer,
- Ector_Renderer_Software_Gradient_Data *linear)
-{
- rasterizer->fill_data.gradient = linear;
- rasterizer->fill_data.type = LinearGradient;
-}
-
-void
-ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasterizer,
- Ector_Renderer_Software_Gradient_Data *radial)
-{
- rasterizer->fill_data.gradient = radial;
- rasterizer->fill_data.type = RadialGradient;
-}
-
-void
-ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer,
- int x, int y, uint32_t mul_col,
- Efl_Gfx_Render_Op op, Shape_Rle_Data* rle,
- Ector_Buffer *comp,
- Efl_Gfx_Vg_Composite_Method comp_method)
-{
- if (!rle) return;
- if (!rasterizer->fill_data.raster_buffer->pixels.u32) return;
-
- rasterizer->fill_data.offx = x;
- rasterizer->fill_data.offy = y;
- rasterizer->fill_data.mul_col = mul_col;
- rasterizer->fill_data.op = op;
- rasterizer->fill_data.comp =
- comp ? efl_data_scope_get(comp, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN) : NULL;
- rasterizer->fill_data.comp_method = comp_method;
-
- _setup_span_fill_matrix(rasterizer);
- _adjust_span_fill_methods(&rasterizer->fill_data);
-
- if (rasterizer->fill_data.blend)
- rasterizer->fill_data.blend(rle->size, rle->spans, &rasterizer->fill_data);
-}
+++ /dev/null
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <Ector.h>
-#include <software/Ector_Software.h>
-
-#include "ector_private.h"
-#include "ector_software_private.h"
-
-#define MY_CLASS ECTOR_SOFTWARE_SURFACE_CLASS
-
-typedef struct _Ector_Software_Task Ector_Software_Task;
-
-struct _Ector_Software_Task
-{
- Eina_Thread_Queue_Msg member;
-
- Ector_Thread_Worker_Cb cb;
- Eina_Free_Cb done;
- void *data;
-};
-
-static int _count_init = 0;
-static unsigned int current = 0;
-static unsigned int cpu_core = 0;
-static Ector_Software_Thread *ths = NULL;
-static Eina_Thread_Queue *render_queue = NULL;
-static Ector_Software_Thread render_thread;
-
-static void *
-_prepare_process(void *data, Eina_Thread t)
-{
- Ector_Software_Thread *th = data;
-
- eina_thread_name_set(t, "Ector Preparing Thread");
- do
- {
- Ector_Software_Task *task, todo;
- void *ref;
-
- task = eina_thread_queue_wait(th->queue, &ref);
-
- if (!task) break ;
- todo.cb = task->cb;
- todo.data = task->data;
- todo.done = task->done;
-
- eina_thread_queue_wait_done(th->queue, ref);
-
- if (!todo.cb) break ;
-
- todo.cb(todo.data, th);
-
- task = eina_thread_queue_send(render_queue, sizeof (Ector_Software_Task), &ref);
- task->cb = todo.cb;
- task->data = todo.data;
- task->done = todo.done;
- eina_thread_queue_send_done(render_queue, ref);
- }
- while (1);
-
- return th;
-}
-
-
-static void
-_ector_software_init(void)
-{
- int cpu, i;
-
- ++_count_init;
- if (_count_init != 1) return;
-
- cpu = eina_cpu_count() - 1;
- if (cpu < 1)
- {
- render_thread.queue = NULL;
- ector_software_thread_init(&render_thread);
- return ;
- }
- cpu = cpu > 8 ? 8 : cpu;
- cpu_core = cpu;
-
- render_queue = eina_thread_queue_new();
-
- ths = malloc(sizeof(Ector_Software_Thread) * cpu);
- for (i = 0; i < cpu; i++)
- {
- Ector_Software_Thread *t;
-
- t = &ths[i];
- t->queue = eina_thread_queue_new();
- ector_software_thread_init(t);
- if (!eina_thread_create(&t->thread, EINA_THREAD_NORMAL, -1,
- _prepare_process, t))
- {
- eina_thread_queue_free(t->queue);
- t->queue = NULL;
- }
- }
-}
-
-static void
-_ector_software_shutdown(void)
-{
- Ector_Software_Thread *t;
- unsigned int i;
-
- --_count_init;
- if (_count_init != 0) return;
-
- if (!ths)
- {
- ector_software_thread_shutdown(&render_thread);
- return ;
- }
-
- for (i = 0; i < cpu_core; i++)
- {
- Ector_Software_Task *task;
- void *ref;
-
- t = &ths[i];
-
- task = eina_thread_queue_send(t->queue, sizeof (Ector_Software_Task), &ref);
- task->cb = NULL;
- task->data = NULL;
- eina_thread_queue_send_done(t->queue, ref);
-
- eina_thread_join(t->thread);
- eina_thread_queue_free(t->queue);
- ector_software_thread_shutdown(t);
- }
-
- eina_thread_queue_free(render_queue);
- render_queue = NULL;
-
- free(ths);
- ths = NULL;
-}
-
-void
-ector_software_schedule(Ector_Thread_Worker_Cb cb, Eina_Free_Cb done, void *data)
-{
- Ector_Software_Thread *t;
- Ector_Software_Task *task;
- void *ref;
-
- // Not enough CPU, doing it inline in the rendering thread
- if (!ths) return ;
-
- t = &ths[current];
- current = (current + 1) % cpu_core;
-
- task = eina_thread_queue_send(t->queue, sizeof (Ector_Software_Task), &ref);
- task->cb = cb;
- task->done = done;
- task->data = data;
- eina_thread_queue_send_done(t->queue, ref);
-}
-
-// Do not call this function if the done function has already called
-void
-ector_software_wait(Ector_Thread_Worker_Cb cb, Eina_Free_Cb done, void *data)
-{
- Ector_Software_Task *task, covering;
-
- // First handle case with just inlined prepare code call inside the rendering thread
- if (!ths)
- {
- render_thread.thread = eina_thread_self();
- cb(data, &render_thread);
- done(data);
-
- return ;
- }
-
- // We don't know which task is going to be done first, so
- // we iterate until we find ourself back and trigger all
- // the done call along the way.
- do
- {
- void *ref;
-
- task = eina_thread_queue_wait(render_queue, &ref);
- if (!task) break;
- covering.cb = task->cb;
- covering.done = task->done;
- covering.data = task->data;
- eina_thread_queue_wait_done(render_queue, ref);
-
- covering.done(covering.data);
- }
- while (covering.cb != cb ||
- covering.done != done ||
- covering.data != data);
-}
-
-static Ector_Renderer *
-_ector_software_surface_ector_surface_renderer_factory_new(Eo *obj,
- Ector_Software_Surface_Data *pd EINA_UNUSED,
- const Efl_Class *type)
-{
- if (type == ECTOR_RENDERER_SHAPE_MIXIN)
- return efl_add_ref(ECTOR_RENDERER_SOFTWARE_SHAPE_CLASS, NULL, ector_renderer_surface_set(efl_added, obj));
- else if (type == ECTOR_RENDERER_IMAGE_MIXIN)
- return efl_add_ref(ECTOR_RENDERER_SOFTWARE_IMAGE_CLASS, NULL, ector_renderer_surface_set(efl_added, obj));
- else if (type == ECTOR_RENDERER_GRADIENT_LINEAR_MIXIN)
- return efl_add_ref(ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS, NULL, ector_renderer_surface_set(efl_added, obj));
- else if (type == ECTOR_RENDERER_GRADIENT_RADIAL_MIXIN)
- return efl_add_ref(ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS, NULL, ector_renderer_surface_set(efl_added, obj));
-
- ERR("Couldn't find class for type: %s", efl_class_name_get(type));
- return NULL;
-}
-
-static Eo *
-_ector_software_surface_efl_object_constructor(Eo *obj, Ector_Software_Surface_Data *pd)
-{
- _ector_software_init();
-
- obj = efl_constructor(efl_super(obj, MY_CLASS));
- pd->rasterizer = (Software_Rasterizer *) calloc(1, sizeof(Software_Rasterizer));
- ector_software_rasterizer_init(pd->rasterizer);
- pd->rasterizer->fill_data.raster_buffer = efl_data_ref(obj, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
- return obj;
-}
-
-static void
-_ector_software_surface_efl_object_destructor(Eo *obj, Ector_Software_Surface_Data *pd)
-{
- efl_data_unref(obj, pd->rasterizer->fill_data.raster_buffer);
- free(pd->rasterizer);
- pd->rasterizer = NULL;
- efl_destructor(efl_super(obj, ECTOR_SOFTWARE_SURFACE_CLASS));
-
- _ector_software_shutdown();
-}
-
-static void
-_ector_software_surface_ector_surface_reference_point_get(const Eo *obj EINA_UNUSED,
- Ector_Software_Surface_Data *pd,
- int* x, int* y)
-{
- if (x) *x = pd->x;
- if (y) *y = pd->y;
-}
-
-static void
-_ector_software_surface_ector_surface_reference_point_set(Eo *obj EINA_UNUSED,
- Ector_Software_Surface_Data *pd,
- int x, int y)
-{
- pd->x = x;
- pd->y = y;
-}
-
-static Eina_Bool
-_ector_software_surface_ector_surface_draw_image(Eo *obj EINA_UNUSED,
- Ector_Software_Surface_Data *pd,
- Ector_Buffer *buffer, int x, int y, int alpha)
-{
- if (!buffer || !pd->rasterizer || !pd->rasterizer->fill_data.raster_buffer->pixels.u32)
- return EINA_FALSE;
-
- Ector_Software_Buffer_Base_Data *bd = efl_data_scope_get(buffer, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
- const int pix_stride = pd->rasterizer->fill_data.raster_buffer->stride / 4;
-
- uint32_t *src = bd->pixels.u32;
- if (!src) return EINA_FALSE;
-
- for (unsigned int local_y = 0; local_y < bd->generic->h; local_y++)
- {
- uint32_t *dst = pd->rasterizer->fill_data.raster_buffer->pixels.u32 + (x + ((local_y + y) * pix_stride));
- for (unsigned int local_x = 0; local_x < bd->generic->w; local_x++)
- {
- *src = draw_mul_256(alpha, *src);
- int inv_alpha = 255 - ((*src) >> 24);
- *dst = *src + draw_mul_256(inv_alpha, *dst);
- dst++;
- src++;
- }
- }
- return EINA_TRUE;
-}
-#include "ector_software_surface.eo.c"
-#include "ector_renderer_software.eo.c"
+++ /dev/null
-class @beta Ector.Software.Surface extends Ector.Software.Buffer implements Ector.Surface
-{
- [[Ector surface software class]]
- c_prefix: ector_software_surface;
- methods {}
- implements {
- Ector.Surface.renderer_factory_new;
- Ector.Surface.reference_point { set; get; }
- Ector.Surface.draw_image;
- Efl.Object.destructor;
- Efl.Object.constructor;
- }
-}
ector_src += files([
- 'ector_renderer_software_gradient_linear.c',
- 'ector_renderer_software_gradient_radial.c',
- 'ector_renderer_software_shape.c',
- 'ector_renderer_software_image.c',
- 'ector_software_gradient.c',
- 'ector_software_rasterizer.c',
- 'ector_software_surface.c',
'ector_software_buffer.c',
])
pub_eo_files = [
- 'ector_software_surface.eo',
'ector_software_buffer.eo',
'ector_software_buffer_base.eo',
- 'ector_renderer_software.eo',
- 'ector_renderer_software_shape.eo',
- 'ector_renderer_software_image.eo',
- 'ector_renderer_software_gradient_radial.eo',
- 'ector_renderer_software_gradient_linear.eo',
]
foreach eo_file : pub_eo_files
endforeach
-if cpu_sse3 == true
- ector_opt = static_library('ector_opt',
- sources: pub_eo_file_target + [ 'ector_software_gradient_sse3.c' ],
- dependencies: ector_pub_deps + [triangulator, freetype, draw, m] + ector_deps,
- include_directories: config_dir + [ include_directories('..') ],
- c_args: native_arch_opt_c_args,
- )
- ector_opt_lib += [ ector_opt ]
-endif
-
-
#
# Only enable that again when the namespace problems are fixed. ref T8648
#
#include "evas_common_private.h"
#include "evas_gl_core_private.h"
-#include "software/Ector_Software.h"
#include "gl/Ector_GL.h"
#include "evas_ector_gl.h"
#include "filters/gl_engine_filter.h"
ector = efl_add_ref(ECTOR_GL_SURFACE_CLASS, NULL);
use_gl = EINA_TRUE;
}
- else
- ector = efl_add_ref(ECTOR_SOFTWARE_SURFACE_CLASS, NULL);
efl_domain_current_pop();
return ector;
#include "region.h"
-#include <software/Ector_Software.h>
#include "evas_ector_software.h"
#include "draw.h"
#include "evas_filter_private.h"
Eina_Bool free_it;
};
-struct _Evas_Thread_Command_Ector_Surface
-{
- Ector_Surface *ector;
- void *pixels;
- int x, y;
-};
// declare here as it is re-used
static void *eng_image_map_surface_new(void *data, int w, int h, int alpha);
Eina_Mempool *_mp_command_font = NULL;
Eina_Mempool *_mp_command_map = NULL;
Eina_Mempool *_mp_command_multi_font = NULL;
-Eina_Mempool *_mp_command_ector = NULL;
-Eina_Mempool *_mp_command_ector_surface = NULL;
/*
*****
**
return eng_image_map_surface_new(engdata, w, h, alpha);
}
-EAPI void
-_evas_image_flip_horizontal(DATA32 *pixels_out, const DATA32 *pixels_in,
+static void
+_image_flip_horizontal(DATA32 *pixels_out, const DATA32 *pixels_in,
int iw, int ih)
{
const unsigned int *pi1, *pi2;
}
}
-EAPI void
-_evas_image_flip_vertical(DATA32 *pixels_out, const DATA32 *pixels_in,
+static void
+_image_flip_vertical(DATA32 *pixels_out, const DATA32 *pixels_in,
int iw, int ih)
{
const unsigned int *pi1, *pi2;
}
}
-EAPI void
-_evas_image_rotate_180(DATA32 *pixels_out, const DATA32 *pixels_in,
+static void
+_image_rotate_180(DATA32 *pixels_out, const DATA32 *pixels_in,
int iw, int ih)
{
const unsigned int *pi1, *pi2;
}
}
-EAPI void
-_evas_image_rotate_90(DATA32 *pixels_out, const DATA32 *pixels_in, int iw, int ih)
+static void
+_image_rotate_90(DATA32 *pixels_out, const DATA32 *pixels_in, int iw, int ih)
{
int x, y, xx, yy, xx2, yy2;
}
}
-EAPI void
-_evas_image_rotate_270(DATA32 *pixels_out, const DATA32 *pixels_in, int iw, int ih)
+static void
+_image_rotate_270(DATA32 *pixels_out, const DATA32 *pixels_in, int iw, int ih)
{
int x, y, xx, yy, xx2, yy2;
}
}
-EAPI void
-_evas_image_flip_transpose(DATA32 *pixels_out, const DATA32 *pixels_in,
+static void
+_image_flip_transpose(DATA32 *pixels_out, const DATA32 *pixels_in,
int iw, int ih)
{
int x, y;
}
}
-EAPI void
-_evas_image_flip_transverse(DATA32 *pixels_out, const DATA32 *pixels_in,
+static void
+_image_flip_transverse(DATA32 *pixels_out, const DATA32 *pixels_in,
int iw, int ih)
{
int x, y;
ERR("You shouldn't get this message, wrong orient value");
goto on_error;
case EVAS_IMAGE_ORIENT_90:
- _evas_image_rotate_90(pixels_out, pixels_in, im->w, im->h);
+ _image_rotate_90(pixels_out, pixels_in, im->w, im->h);
break;
case EVAS_IMAGE_ORIENT_180:
- _evas_image_rotate_180(pixels_out, pixels_in, im->w, im->h);
+ _image_rotate_180(pixels_out, pixels_in, im->w, im->h);
break;
case EVAS_IMAGE_ORIENT_270:
- _evas_image_rotate_270(pixels_out, pixels_in, im->w, im->h);
+ _image_rotate_270(pixels_out, pixels_in, im->w, im->h);
break;
default:
ERR("Wrong orient value");
(orient == EVAS_IMAGE_ORIENT_NONE)))
{
// flip horizontally to get the new orientation
- _evas_image_flip_horizontal(pixels_out, pixels_in, im->w, im->h);
+ _image_flip_horizontal(pixels_out, pixels_in, im->w, im->h);
}
else if (((im->orient == EVAS_IMAGE_ORIENT_NONE) &&
(orient == EVAS_IMAGE_FLIP_VERTICAL)) ||
(orient == EVAS_IMAGE_ORIENT_NONE)))
{
// flip vertically to get the new orientation
- _evas_image_flip_vertical(pixels_out, pixels_in, im->w, im->h);
+ _image_flip_vertical(pixels_out, pixels_in, im->w, im->h);
}
else
{
memcpy(pixels_tmp, pixels_in, sizeof (unsigned int) * w * h);
break;
case EVAS_IMAGE_ORIENT_90:
- _evas_image_rotate_270(pixels_tmp, pixels_in, im->w, im->h);
+ _image_rotate_270(pixels_tmp, pixels_in, im->w, im->h);
break;
case EVAS_IMAGE_ORIENT_180:
- _evas_image_rotate_180(pixels_tmp, pixels_in, im->w, im->h);
+ _image_rotate_180(pixels_tmp, pixels_in, im->w, im->h);
break;
case EVAS_IMAGE_ORIENT_270:
- _evas_image_rotate_90(pixels_tmp, pixels_in, im->w, im->h);
+ _image_rotate_90(pixels_tmp, pixels_in, im->w, im->h);
break;
case EVAS_IMAGE_FLIP_HORIZONTAL:
- _evas_image_flip_horizontal(pixels_tmp, pixels_in, im->w, im->h);
+ _image_flip_horizontal(pixels_tmp, pixels_in, im->w, im->h);
break;
case EVAS_IMAGE_FLIP_VERTICAL:
- _evas_image_flip_vertical(pixels_tmp, pixels_in, im->w, im->h);
+ _image_flip_vertical(pixels_tmp, pixels_in, im->w, im->h);
break;
case EVAS_IMAGE_FLIP_TRANSPOSE:
- _evas_image_flip_transpose(pixels_tmp, pixels_in, im->w, im->h);
+ _image_flip_transpose(pixels_tmp, pixels_in, im->w, im->h);
break;
case EVAS_IMAGE_FLIP_TRANSVERSE:
- _evas_image_flip_transverse(pixels_tmp, pixels_in, im->w, im->h);
+ _image_flip_transverse(pixels_tmp, pixels_in, im->w, im->h);
break;
default:
ERR("Wrong orient value");
memcpy(pixels_out, pixels_tmp, sizeof (unsigned int) * w * h);
break;
case EVAS_IMAGE_ORIENT_90:
- _evas_image_rotate_90(pixels_out, pixels_tmp, tw, th);
+ _image_rotate_90(pixels_out, pixels_tmp, tw, th);
break;
case EVAS_IMAGE_ORIENT_180:
- _evas_image_rotate_180(pixels_out, pixels_tmp, tw, th);
+ _image_rotate_180(pixels_out, pixels_tmp, tw, th);
break;
case EVAS_IMAGE_ORIENT_270:
- _evas_image_rotate_270(pixels_out, pixels_tmp, tw, th);
+ _image_rotate_270(pixels_out, pixels_tmp, tw, th);
break;
case EVAS_IMAGE_FLIP_HORIZONTAL:
- _evas_image_flip_horizontal(pixels_out, pixels_tmp, tw, th);
+ _image_flip_horizontal(pixels_out, pixels_tmp, tw, th);
break;
case EVAS_IMAGE_FLIP_VERTICAL:
- _evas_image_flip_vertical(pixels_out, pixels_tmp, tw, th);
+ _image_flip_vertical(pixels_out, pixels_tmp, tw, th);
break;
case EVAS_IMAGE_FLIP_TRANSPOSE:
- _evas_image_flip_transpose(pixels_out, pixels_tmp, tw, th);
+ _image_flip_transpose(pixels_out, pixels_tmp, tw, th);
break;
case EVAS_IMAGE_FLIP_TRANSVERSE:
- _evas_image_flip_transverse(pixels_out, pixels_tmp, tw, th);
+ _image_flip_transverse(pixels_out, pixels_tmp, tw, th);
break;
}
static Ector_Surface *
eng_ector_create(void *engine EINA_UNUSED)
{
- Ector_Surface *ector;
-
- efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
- ector = efl_add_ref(ECTOR_SOFTWARE_SURFACE_CLASS, NULL);
- efl_domain_current_pop();
- return ector;
+ return NULL;
}
static void*
-eng_ector_surface_create(void *engine, int width, int height, int *error)
+eng_ector_surface_create(void *engine EINA_UNUSED, int width EINA_UNUSED, int height EINA_UNUSED, int *error EINA_UNUSED)
{
- void *surface;
-
- *error = EINA_FALSE;
-
- surface = eng_image_new_from_copied_data(engine, width, height, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
- if (!surface) *error = EINA_TRUE;
-
- return surface;
+ return NULL;
}
static void
-eng_ector_surface_destroy(void *engine, void *surface)
+eng_ector_surface_destroy(void *engine EINA_UNUSED, void *surface EINA_UNUSED)
{
- if (!surface) return;
- eng_image_free(engine, surface);
}
static void
-eng_ector_surface_cache_set(void *engine, void *key , void *surface)
+eng_ector_surface_cache_set(void *engine EINA_UNUSED, void *key EINA_UNUSED, void *surface EINA_UNUSED)
{
- Render_Engine_Software_Generic *e = engine;
-
- generic_cache_data_set(e->surface_cache, key, surface);
-
}
static void *
-eng_ector_surface_cache_get(void *engine, void *key)
+eng_ector_surface_cache_get(void *engine EINA_UNUSED, void *key EINA_UNUSED)
{
- Render_Engine_Software_Generic *e = engine;
-
- return generic_cache_data_get(e->surface_cache, key);
+ return NULL;
}
static void
-eng_ector_surface_cache_drop(void *engine, void *key)
+eng_ector_surface_cache_drop(void *engine EINA_UNUSED, void *key EINA_UNUSED)
{
- Render_Engine_Software_Generic *e = engine;
-
- generic_cache_data_drop(e->surface_cache, key);
}
static void
-eng_ector_destroy(void *data EINA_UNUSED, Ector_Surface *ector)
+eng_ector_destroy(void *data EINA_UNUSED, Ector_Surface *ector EINA_UNUSED)
{
- if (ector) efl_unref(ector);
}
static Ector_Buffer *
}
static void
-_draw_thread_ector_cleanup(Evas_Thread_Command_Ector *ector)
-{
- Eina_Rectangle *r;
-
- while ((r = eina_array_pop(ector->clips)))
- eina_rectangle_free(r);
- eina_array_free(ector->clips);
-
- if (ector->free_it)
- eina_mempool_free(_mp_command_ector, ector);
-}
-
-static void
-_draw_thread_ector_draw(void *data)
-{
- Evas_Thread_Command_Ector *ector = data;
-
- ector_renderer_draw(ector->r, ector->render_op, ector->clips, ector->mul_col);
-
- _draw_thread_ector_cleanup(ector);
-}
-
-static void
-eng_ector_renderer_draw(void *engine EINA_UNUSED, void *surface,
- void *context, Ector_Renderer *renderer,
- Eina_Array *clips, Eina_Bool do_async)
-{
- RGBA_Image *dst = surface;
- RGBA_Draw_Context *dc = context;
- Evas_Thread_Command_Ector ector;
- Eina_Array *c;
- Eina_Rectangle *r;
- Eina_Rectangle clip;
- Eina_Array_Iterator it;
- unsigned int i;
-
- if (dc->clip.use)
- {
- clip.x = dc->clip.x;
- clip.y = dc->clip.y;
- clip.w = dc->clip.w;
- clip.h = dc->clip.h;
- // clip the clip rect to surface boundary.
- RECTS_CLIP_TO_RECT(clip.x, clip.y, clip.w, clip.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
- if ((clip.w < 1) || (clip.h < 1)) return;
- }
- else
- {
- clip.x = 0;
- clip.y = 0;
- clip.w = dst->cache_entry.w;
- clip.h = dst->cache_entry.h;
- }
-
- c = eina_array_new(8);
- if (clips)
- {
- EINA_ARRAY_ITER_NEXT(clips, i, r, it)
- {
- Eina_Rectangle *rc;
-
- rc = eina_rectangle_new(r->x, r->y, r->w, r->h);
- if (!rc) continue;
-
- if (eina_rectangle_intersection(rc, &clip))
- eina_array_push(c, rc);
- else
- eina_rectangle_free(rc);
- }
-
- if (eina_array_count(c) == 0 &&
- eina_array_count(clips) > 0)
- {
- eina_array_free(c);
- return;
- }
- }
-
- if (eina_array_count(c) == 0)
- eina_array_push(c, eina_rectangle_new(clip.x, clip.y, clip.w, clip.h));
-
- ector.r = renderer; // This has already been refcounted by Evas_Object_VG
- ector.clips = c;
- ector.render_op = EFL_GFX_RENDER_OP_BLEND;
- ector.mul_col = 0xffffffff;
- ector.free_it = EINA_FALSE;
-
- if (do_async)
- {
- Evas_Thread_Command_Ector *ne;
-
- ne = eina_mempool_malloc(_mp_command_ector, sizeof (Evas_Thread_Command_Ector));
- if (!ne)
- {
- _draw_thread_ector_cleanup(&ector);
- return;
- }
-
- memcpy(ne, &ector, sizeof (Evas_Thread_Command_Ector));
- ne->free_it = EINA_TRUE;
-
- QCMD(_draw_thread_ector_draw, ne);
- }
- else
- {
- _draw_thread_ector_draw(&ector);
- }
-}
-
-static void
-_draw_thread_ector_surface_set(void *data)
+eng_ector_renderer_draw(void *engine EINA_UNUSED, void *surface EINA_UNUSED,
+ void *context EINA_UNUSED, Ector_Renderer *renderer EINA_UNUSED,
+ Eina_Array *clips EINA_UNUSED, Eina_Bool do_async EINA_UNUSED)
{
- Evas_Thread_Command_Ector_Surface *ector_surface = data;
- RGBA_Image *surface = ector_surface->pixels;
- void *pixels = NULL;
- unsigned int w = 0;
- unsigned int h = 0;
- unsigned int x = 0;
- unsigned int y = 0;
-
- // flush the cpu pipeline before ector drawing.
- evas_common_cpu_end_opt();
-
- if (surface)
- {
- pixels = evas_cache_image_pixels(&surface->cache_entry);
- if (pixels)
- {
- w = surface->cache_entry.w;
- h = surface->cache_entry.h;
- x = ector_surface->x;
- y = ector_surface->y;
- // clear the surface before giving to ector
- memset(pixels, 0, (w * h * 4));
- }
- }
-
- ector_buffer_pixels_set(ector_surface->ector, pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
- ector_surface_reference_point_set(ector_surface->ector, x, y);
-
- eina_mempool_free(_mp_command_ector_surface, ector_surface);
}
static Eina_Bool
-eng_ector_begin(void *engine EINA_UNUSED, void *surface,
- void *context EINA_UNUSED, Ector_Surface *ector,
- int x, int y, Eina_Bool do_async)
+eng_ector_begin(void *engine EINA_UNUSED, void *surface EINA_UNUSED,
+ void *context EINA_UNUSED, Ector_Surface *ector EINA_UNUSED,
+ int x EINA_UNUSED, int y EINA_UNUSED, Eina_Bool do_async EINA_UNUSED)
{
- if (do_async)
- {
- Evas_Thread_Command_Ector_Surface *nes;
-
- nes = eina_mempool_malloc(_mp_command_ector_surface, sizeof (Evas_Thread_Command_Ector_Surface));
- if (!nes) return EINA_FALSE;
-
- nes->ector = ector;
- nes->pixels = surface;
- nes->x = x;
- nes->y = y;
-
- QCMD(_draw_thread_ector_surface_set, nes);
- }
- else
- {
- RGBA_Image *sf = surface;
- void *pixels = NULL;
- unsigned int w = 0;
- unsigned int h = 0;
-
- pixels = evas_cache_image_pixels(&sf->cache_entry);
- if (!pixels) return EINA_FALSE;
-
- w = sf->cache_entry.w;
- h = sf->cache_entry.h;
- // clear the surface before giving to ector
- memset(pixels, 0, (w * h * 4));
-
- ector_buffer_pixels_set(ector, pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
- ector_surface_reference_point_set(ector, x, y);
- }
return EINA_TRUE;
}
eng_ector_end(void *engine EINA_UNUSED,
void *surface EINA_UNUSED,
void *context EINA_UNUSED,
- Ector_Surface *ector,
- Eina_Bool do_async)
+ Ector_Surface *ector EINA_UNUSED,
+ Eina_Bool do_async EINA_UNUSED)
{
- if (do_async)
- {
- Evas_Thread_Command_Ector_Surface *nes;
-
- nes = eina_mempool_malloc(_mp_command_ector_surface, sizeof (Evas_Thread_Command_Ector_Surface));
- if (!nes) return ;
-
- nes->ector = ector;
- nes->pixels = NULL;
-
- QCMD(_draw_thread_ector_surface_set, nes);
- }
- else
- {
- ector_buffer_pixels_set(ector, NULL, 0, 0, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
- evas_common_cpu_end_opt();
- }
}
//------------------------------------------------//
_mp_command_multi_font =
eina_mempool_add("chained_mempool", "Evas_Thread_Command_Multi_Font",
NULL, sizeof(Evas_Thread_Command_Multi_Font), 128);
- _mp_command_ector =
- eina_mempool_add("chained_mempool", "Evas_Thread_Command_Ector",
- NULL, sizeof(Evas_Thread_Command_Ector), 128);
- _mp_command_ector_surface =
- eina_mempool_add("chained_mempool", "Evas_Thread_Command_Ector_Surface",
- NULL, sizeof(Evas_Thread_Command_Ector_Surface), 128);
ector_init();
// do on demand when first evas_gl_api_get is called...
// init_gl();
- ector_glsym_set(dlsym, RTLD_DEFAULT);
evas_common_pipe_init();
em->functions = (void *)(&func);
eina_mempool_del(_mp_command_image);
eina_mempool_del(_mp_command_font);
eina_mempool_del(_mp_command_map);
- eina_mempool_del(_mp_command_ector);
if (_evas_soft_gen_log_dom >= 0)
{
eina_log_domain_unregister(_evas_soft_gen_log_dom);