Example #1
0
EAPI int
eina_strbuf_replace_all(Eina_Strbuf *buf, const char *str, const char *with)
{
   size_t len1, len2, len;
   char *tmp_buf = NULL;
   char *spos;
   size_t pos, start;
   size_t pos_tmp, start_tmp;
   int n = 0;

   EINA_SAFETY_ON_NULL_RETURN_VAL( str, 0);
   EINA_SAFETY_ON_NULL_RETURN_VAL(with, 0);
   EINA_MAGIC_CHECK_STRBUF(buf, 0);

   spos = strstr(buf->buf, str);
   if (!spos || *spos == '\0') return 0;

   /* This is a read only buffer which need change to be made */
   if (buf->ro)
     {
        char *dest;

        dest = malloc(buf->size);
        if (!dest) return 0;
        memcpy(dest, buf->buf, buf->len);
        buf->buf = dest;
     }

   len1 = strlen(str);
   len2 = strlen(with);
   /* if the size of the two string is equal, it is fairly easy to replace them
    * we don't need to resize the buffer or doing other calculations */
   if (len1 == len2)
     {
        while (spos)
          {
             memcpy(spos, with, len2);
             spos = strstr(spos + len2, str);
             n++;
          }
        return n;
     }
   pos = pos_tmp = spos - (const char *)buf->buf;
   tmp_buf = buf->buf;
   buf->buf = malloc(buf->size);
   if (EINA_UNLIKELY(!buf->buf))
     {
        buf->buf = tmp_buf;
        return 0;
     }
   start = start_tmp = 0;
   len = buf->len;
   while (spos)
     {
        n++;
        len = (len + len2) - len1;
        /* resize the buffer if necessary */
        if (EINA_UNLIKELY(!_eina_strbuf_common_grow(_STRBUF_CSIZE, buf, len)))
          {
             /* we have to stop replacing here, because we haven't enough
              * memory to go on */
             len = (len + len1) - len2;
             break;
          }
        /* copy the untouched text */
        memcpy(((unsigned char *)(buf->buf)) + start,  tmp_buf + start_tmp,
               pos - start);
        /* copy the new string */
        memcpy(((unsigned char *)(buf->buf)) + pos, with, len2);
        /* calculate the next positions */
        start_tmp = pos_tmp + len1;
        start = pos + len2;
        spos = strstr(tmp_buf + start_tmp, str);
        /* this calculations don't make sense if spos == NULL, but the
         * calculated values won't be used, because the loop will stop
         * then */
        pos_tmp = spos - tmp_buf;
        pos = start + pos_tmp - start_tmp;
     }
   /* and now copy the rest of the text */
   memcpy(((unsigned char *)(buf->buf)) + start, tmp_buf + start_tmp,
          len - start);
   buf->len = len;
   memset(((unsigned char *)(buf->buf)) + buf->len, 0, 1);
   free(tmp_buf);
   return n;
}
Example #2
0
EAPI_MAIN int
elm_main(int    argc,
         char **argv)
{
   int ret = EXIT_FAILURE;
   int args;
   int i;
   Editor *ed;
   unsigned int ed_count = 0;
   Eina_Bool quit_opt = EINA_FALSE;
   Eina_Bool debug = EINA_FALSE;
   Ecore_Getopt_Value values[] = {
      ECORE_GETOPT_VALUE_BOOL(debug),
      ECORE_GETOPT_VALUE_BOOL(quit_opt),
      ECORE_GETOPT_VALUE_BOOL(quit_opt)
   };
   const Module *mod_ptr;
   const Module *mod_end = &(_modules[EINA_C_ARRAY_LENGTH(_modules)]);
   const char *env;
   unsigned int debug_flags = 0;

   args = ecore_getopt_parse(&_options, values, argc, argv);
   if (args < 0)
     {
        EINA_LOG_CRIT("Getopt failed");
        goto end;
     }

   /* Quit option requested? End now, with success */
   if (quit_opt)
     {
        ret = EXIT_SUCCESS;
        goto end;
     }

   if (debug)
     debug_flags = ~0U;

   /* Are we running in tree? */
   env = getenv("WAR2EDIT_IN_TREE");
   _in_tree = (env) ? !!atoi(env) : EINA_FALSE;

   elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
   elm_language_set("");
   elm_app_compile_bin_dir_set(PACKAGE_BIN_DIR);
   elm_app_compile_lib_dir_set(PACKAGE_LIB_DIR);
   elm_app_compile_data_dir_set(PACKAGE_DATA_DIR);
   elm_app_info_set(elm_main, "war2edit", "sprites/units/units.eet");

   if (EINA_UNLIKELY(!_edje_get(NULL)))
     {
        EINA_LOG_CRIT("Failed to get edje theme");
        goto end;
     }

   for (mod_ptr = _modules; mod_ptr != mod_end; ++mod_ptr)
     {
       if (EINA_UNLIKELY(EINA_FALSE == mod_ptr->init()))
         {
            EINA_LOG_CRIT("Failed to initialize module \"%s\"", mod_ptr->name);
            goto modules_shutdown;
         }
     }


   /* Open editors for each specified files */
   for (i = args; i < argc; ++i)
     {
        /* If an editor fails to open, don't close now */
        ed = editor_new(argv[i], debug_flags);
        if (!ed)
          ERR("Failed to create editor with file \"%s\"", argv[i]);
        else
          ++ed_count;
     }

   if (ed_count == 0)
     {
        ed = editor_new(NULL, debug_flags);
        if (EINA_UNLIKELY(!ed))
          {
             CRI("Failed to create editor");
             goto modules_shutdown;
          }
     }

   /* === Main loop === */
   elm_run();
   ret = EXIT_SUCCESS;

modules_shutdown:
   for (--mod_ptr; mod_ptr >= _modules; --mod_ptr)
     mod_ptr->shutdown();
end:
   if (_edje_file)
     {
        free(_edje_file);
        _edje_file = NULL;
     }
   return ret;
}
Example #3
0
static Eina_Bool
scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst,
                                         RGBA_Draw_Context *dc,
                                         int src_region_x, int src_region_y,
                                         int src_region_w, int src_region_h,
                                         int dst_region_x, int dst_region_y,
                                         int dst_region_w, int dst_region_h)
{
   int      x, y;
   int     *lin_ptr;
   DATA32  *buf = NULL, *dptr;
   DATA32 **row_ptr;
   DATA32  *ptr, *dst_ptr, *src_data, *dst_data;
   DATA8   *mask;
   int      dst_clip_x, dst_clip_y, dst_clip_w, dst_clip_h;
   int      src_w, src_h, dst_w, dst_h, mask_x, mask_y;
   RGBA_Gfx_Func func, func2 = NULL;
   RGBA_Image *mask_ie = dc->clip.mask;

   if (!(RECTS_INTERSECT(dst_region_x, dst_region_y, dst_region_w, dst_region_h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
     return EINA_FALSE;
   if (!(RECTS_INTERSECT(src_region_x, src_region_y, src_region_w, src_region_h, 0, 0, src->cache_entry.w, src->cache_entry.h)))
     return EINA_FALSE;

   src_w = src->cache_entry.w;
   src_h = src->cache_entry.h;
   dst_w = dst->cache_entry.w;
   dst_h = dst->cache_entry.h;

   src_data = src->image.data;
   dst_data = dst->image.data;

   mask_x = dc->clip.mask_x;
   mask_y = dc->clip.mask_y;

   if (dc->clip.use)
     {
        dst_clip_x = dc->clip.x;
        dst_clip_y = dc->clip.y;
        dst_clip_w = dc->clip.w;
        dst_clip_h = dc->clip.h;
        if (dst_clip_x < 0)
          {
             dst_clip_w += dst_clip_x;
             dst_clip_x = 0;
          }
        if (dst_clip_y < 0)
          {
             dst_clip_h += dst_clip_y;
             dst_clip_y = 0;
          }
        if ((dst_clip_x + dst_clip_w) > dst_w)
          dst_clip_w = dst_w - dst_clip_x;
        if ((dst_clip_y + dst_clip_h) > dst_h)
          dst_clip_h = dst_h - dst_clip_y;
     }
   else
     {
        dst_clip_x = 0;
        dst_clip_y = 0;
        dst_clip_w = dst_w;
        dst_clip_h = dst_h;
     }

   if (dst_clip_x < dst_region_x)
     {
        dst_clip_w += dst_clip_x - dst_region_x;
        dst_clip_x = dst_region_x;
     }
   if ((dst_clip_x + dst_clip_w) > (dst_region_x + dst_region_w))
     dst_clip_w = dst_region_x + dst_region_w - dst_clip_x;
   if (dst_clip_y < dst_region_y)
     {
        dst_clip_h += dst_clip_y - dst_region_y;
        dst_clip_y = dst_region_y;
     }
   if ((dst_clip_y + dst_clip_h) > (dst_region_y + dst_region_h))
     dst_clip_h = dst_region_y + dst_region_h - dst_clip_y;

   if ((src_region_w <= 0) || (src_region_h <= 0) ||
       (dst_region_w <= 0) || (dst_region_h <= 0) ||
       (dst_clip_w <= 0) || (dst_clip_h <= 0))
     return EINA_FALSE;

   /* sanitise x */
   if (src_region_x < 0)
     {
        dst_region_x -= (src_region_x * dst_region_w) / src_region_w;
        dst_region_w += (src_region_x * dst_region_w) / src_region_w;
        src_region_w += src_region_x;
        src_region_x = 0;
     }
   if (src_region_x >= src_w) return EINA_FALSE;
   if ((src_region_x + src_region_w) > src_w)
     {
        dst_region_w = (dst_region_w * (src_w - src_region_x)) / (src_region_w);
        src_region_w = src_w - src_region_x;
     }
   if (dst_region_w <= 0) return EINA_FALSE;
   if (src_region_w <= 0) return EINA_FALSE;
   if (dst_clip_w <= 0) return EINA_FALSE;
   if (dst_clip_x >= dst_w) return EINA_FALSE;
   if (dst_clip_x < dst_region_x)
     {
        dst_clip_w += (dst_clip_x - dst_region_x);
        dst_clip_x = dst_region_x;
     }
   if ((dst_clip_x + dst_clip_w) > dst_w)
     {
        dst_clip_w = dst_w - dst_clip_x;
     }
   if (dst_clip_w <= 0) return EINA_FALSE;

   /* sanitise y */
   if (src_region_y < 0)
     {
        dst_region_y -= (src_region_y * dst_region_h) / src_region_h;
        dst_region_h += (src_region_y * dst_region_h) / src_region_h;
        src_region_h += src_region_y;
        src_region_y = 0;
     }
   if (src_region_y >= src_h) return EINA_FALSE;
   if ((src_region_y + src_region_h) > src_h)
     {
        dst_region_h = (dst_region_h * (src_h - src_region_y)) / (src_region_h);
        src_region_h = src_h - src_region_y;
     }
   if (dst_region_h <= 0) return EINA_FALSE;
   if (src_region_h <= 0) return EINA_FALSE;
   if (dst_clip_h <= 0) return EINA_FALSE;
   if (dst_clip_y >= dst_h) return EINA_FALSE;
   if (dst_clip_y < dst_region_y)
     {
        dst_clip_h += (dst_clip_y - dst_region_y);
        dst_clip_y = dst_region_y;
     }
   if ((dst_clip_y + dst_clip_h) > dst_h)
     {
        dst_clip_h = dst_h - dst_clip_y;
     }
   if (dst_clip_h <= 0) return EINA_FALSE;

   /* figure out dst jump */
   //dst_jump = dst_w - dst_clip_w;

   /* figure out dest start ptr */
   dst_ptr = dst_data + dst_clip_x + (dst_clip_y * dst_w);

   if (!mask_ie)
     {
        if (dc->mul.use)
          func = evas_common_gfx_func_composite_pixel_color_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dc->mul.col, dst->cache_entry.flags.alpha, dst_clip_w, dc->render_op);
        else
          func = evas_common_gfx_func_composite_pixel_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dst->cache_entry.flags.alpha, dst_clip_w, dc->render_op);
     }
   else
     {
        func = evas_common_gfx_func_composite_pixel_mask_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dst->cache_entry.flags.alpha, dst_clip_w, dc->render_op);
        if (dc->mul.use)
          func2 = evas_common_gfx_func_composite_pixel_color_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dc->mul.col, dst->cache_entry.flags.alpha, dst_clip_w, EVAS_RENDER_COPY);
        // Adjust clipping info
        if (EINA_UNLIKELY((dst_clip_x - mask_x) < 0))
          dst_clip_x = mask_x;
        if (EINA_UNLIKELY((dst_clip_y - mask_y) < 0))
          dst_clip_y = mask_y;
        if (EINA_UNLIKELY((dst_clip_x - mask_x + dst_clip_w) > (int)mask_ie->cache_entry.w))
          dst_clip_w = mask_ie->cache_entry.w - dst_clip_x + mask_x;
        if (EINA_UNLIKELY((dst_clip_y - mask_y + dst_clip_h) > (int)mask_ie->cache_entry.h))
          dst_clip_h = mask_ie->cache_entry.h - dst_clip_y + mask_y;
     }

   if ((dst_region_w == src_region_w) && (dst_region_h == src_region_h))
     {
#ifdef HAVE_PIXMAN
# ifdef PIXMAN_IMAGE_SCALE_SAMPLE
        if ((src->pixman.im) && (dst->pixman.im) && (!dc->clip.mask) &&
            ((!dc->mul.use) || ((dc->mul.use) && (dc->mul.col == 0xffffffff))) &&
            ((dc->render_op == _EVAS_RENDER_COPY) ||
             (dc->render_op == _EVAS_RENDER_BLEND)))
          {
             pixman_op_t op = PIXMAN_OP_SRC; // _EVAS_RENDER_COPY
             if (dc->render_op == _EVAS_RENDER_BLEND)
               op = PIXMAN_OP_OVER;

             pixman_image_composite(op,
                                    src->pixman.im, NULL,
                                    dst->pixman.im,
                                    (dst_clip_x - dst_region_x) + src_region_x,
                                    (dst_clip_y - dst_region_y) + src_region_y,
                                    0, 0,
                                    dst_clip_x, dst_clip_y,
                                    dst_clip_w, dst_clip_h);
          }
        else
# endif
#endif
          {
             ptr = src_data + ((dst_clip_y - dst_region_y + src_region_y) * src_w) + (dst_clip_x - dst_region_x) + src_region_x;

             /* image masking */
             if (mask_ie)
               {
                  if (dc->mul.use)
                    buf = alloca(dst_clip_w * sizeof(DATA32));

                  for (y = 0; y < dst_clip_h; y++)
                    {
                       mask = mask_ie->image.data8
                          + ((dst_clip_y - mask_y + y) * mask_ie->cache_entry.w)
                          + (dst_clip_x - mask_x);

                       /* * blend here [clip_w *] ptr -> dst_ptr * */
                       if (dc->mul.use)
                         {
                            func2(ptr, NULL, dc->mul.col, buf, dst_clip_w);
                            func(buf, mask, 0, dst_ptr, dst_clip_w);
                         }
                       else
                         func(ptr, mask, 0, dst_ptr, dst_clip_w);

                       ptr += src_w;
                       dst_ptr += dst_w;
                    }
               }
             else
               {
                  for (y = 0; y < dst_clip_h; y++)
                    {
                       /* * blend here [clip_w *] ptr -> dst_ptr * */
                       func(ptr, NULL, dc->mul.col, dst_ptr, dst_clip_w);

                       ptr += src_w;
                       dst_ptr += dst_w;
                    }
               }
          }
     }
   else
     {
        /* allocate scale lookup tables */
        lin_ptr = alloca(dst_clip_w * sizeof(int));
        row_ptr = alloca(dst_clip_h * sizeof(DATA32 *));

        /* fill scale tables */
        for (x = 0; x < dst_clip_w; x++)
          lin_ptr[x] = (((x + dst_clip_x - dst_region_x) * src_region_w) / dst_region_w) + src_region_x;
        for (y = 0; y < dst_clip_h; y++)
          row_ptr[y] = src_data + (((((y + dst_clip_y - dst_region_y) * src_region_h) / dst_region_h)
                                    + src_region_y) * src_w);
        /* scale to dst */
        dptr = dst_ptr;
#ifdef DIRECT_SCALE
        if ((!src->cache_entry.flags.alpha) &&
            (!dst->cache_entry.flags.alpha) &&
            (!dc->mul.use) &&
            (!dc->clip.mask))
          {
             for (y = 0; y < dst_clip_h; y++)
               {

                  dst_ptr = dptr;
                  for (x = 0; x < dst_clip_w; x++)
                    {
                       ptr = row_ptr[y] + lin_ptr[x];
                       *dst_ptr = *ptr;
                       dst_ptr++;
                    }

                  dptr += dst_w;
               }
          }
        else
#endif
          {
             unsigned int mul_col;

             /* a scanline buffer */
             buf = alloca(dst_clip_w * sizeof(DATA32));

             mul_col = dc->mul.use ? dc->mul.col : 0xFFFFFFFF;

             /* do we have enough data to start some additional thread ? */
             if (use_thread && dst_clip_h > 32 && dst_clip_w * dst_clip_h > 4096)
               {
                  /* Yes, we do ! */
                  Evas_Scale_Msg *msg;
                  void *ref;
                  Evas_Scale_Thread local;

                  local.mask8 = dc->clip.mask;
                  local.row_ptr = row_ptr;
                  local.dptr = dptr;
                  local.lin_ptr = lin_ptr;
                  local.func = func;
                  local.func2 = func2;
                  local.dst_clip_x = dst_clip_x;
                  local.dst_clip_y = dst_clip_y;
                  local.dst_clip_h = dst_clip_h;
                  local.dst_clip_w = dst_clip_w;
                  local.dst_w = dst_w;
                  local.mask_x = mask_x;
                  local.mask_y = mask_y;
                  local.mul_col = mul_col;

                  msg = eina_thread_queue_send(thread_queue, sizeof (Evas_Scale_Msg), &ref);
                  msg->task = &local;
                  eina_thread_queue_send_done(thread_queue, ref);

                  /* image masking */
                  if (dc->clip.mask)
                    {
                       _evas_common_scale_rgba_sample_scale_mask(0,
                                                                 dst_clip_x, dst_clip_y,
                                                                 dst_clip_w, dst_clip_h >> 1, dst_w,
                                                                 dc->clip.mask_x, dc->clip.mask_y,
                                                                 row_ptr, lin_ptr, dc->clip.mask,
                                                                 dptr, func, func2, mul_col);

                    }
                  else
                    {
                       _evas_common_scale_rgba_sample_scale_nomask(0,
                                                                   dst_clip_w, dst_clip_h >> 1, dst_w,
                                                                   row_ptr, lin_ptr,
                                                                   dptr, func, mul_col);
                    }

                  msg = eina_thread_queue_wait(main_queue, &ref);
                  if (msg) eina_thread_queue_wait_done(main_queue, ref);
               }
Example #4
0
void
termpty_text_append(Termpty *ty, const Eina_Unicode *codepoints, int len)
{
   Termcell *cells;
   int i, j;

   termio_content_change(ty->obj, ty->cursor_state.cx, ty->cursor_state.cy, len);

   cells = &(TERMPTY_SCREEN(ty, 0, ty->cursor_state.cy));
   for (i = 0; i < len; i++)
     {
        Eina_Unicode g;

        if (ty->termstate.wrapnext)
          {
             cells[ty->w - 1].att.autowrapped = 1;
             ty->termstate.wrapnext = 0;
             ty->cursor_state.cx = 0;
             ty->cursor_state.cy++;
             termpty_text_scroll_test(ty, EINA_TRUE);
             cells = &(TERMPTY_SCREEN(ty, 0, ty->cursor_state.cy));
          }
        if (ty->termstate.insert)
          {
             for (j = ty->w - 1; j > ty->cursor_state.cx; j--)
               termpty_cell_copy(ty, &(cells[j - 1]), &(cells[j]), 1);
          }

        g = _termpty_charset_trans(codepoints[i], ty);
        /* Skip 0-width space */
        if (EINA_UNLIKELY(g == 0x200b))
          {
             continue;
          }
        if (EINA_UNLIKELY(g >= 0x300 && g <=0x36f))
          {
             /* combining chars */
             if (EINA_UNLIKELY(g == 0x336))
               {
                  ty->termstate.combining_strike = 1;
               }
             continue;
          }

        termpty_cell_codepoint_att_fill(ty, g, ty->termstate.att,
                                        &(cells[ty->cursor_state.cx]), 1);
        if (EINA_UNLIKELY(ty->termstate.combining_strike))
          {
             ty->termstate.combining_strike = 0;
             cells[ty->cursor_state.cx].att.strike = 1;
          }
        cells[ty->cursor_state.cx].att.dblwidth = _termpty_is_dblwidth_get(ty, g);
        if (EINA_UNLIKELY((cells[ty->cursor_state.cx].att.dblwidth) && (ty->cursor_state.cx < (ty->w - 1))))
          {
             TERMPTY_FMTCLR(cells[ty->cursor_state.cx].att);
             termpty_cell_codepoint_att_fill(ty, 0, cells[ty->cursor_state.cx].att,
                                             &(cells[ty->cursor_state.cx + 1]), 1);
          }
        if (ty->termstate.wrap)
          {
             unsigned char offset = 1;

             ty->termstate.wrapnext = 0;
             if (EINA_UNLIKELY(cells[ty->cursor_state.cx].att.dblwidth))
               offset = 2;
             if (EINA_UNLIKELY(ty->cursor_state.cx >= (ty->w - offset)))
               ty->termstate.wrapnext = 1;
             else
               {
                  ty->cursor_state.cx += offset;
                  TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
               }
          }
        else
          {
             unsigned char offset = 1;

             ty->termstate.wrapnext = 0;
             if (EINA_UNLIKELY(cells[ty->cursor_state.cx].att.dblwidth))
               offset = 2;
             ty->cursor_state.cx += offset;
             if (ty->cursor_state.cx > (ty->w - offset))
               {
                  ty->cursor_state.cx = ty->w - offset;
                  TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
                  return;
               }
             TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
          }
     }
}
Example #5
0
EAPI void
evas_common_scale_rgba_sample_draw(RGBA_Image *src, RGBA_Image *dst, int dst_clip_x, int dst_clip_y, int dst_clip_w, int dst_clip_h, DATA32 mul_col, int render_op, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h, RGBA_Image *mask_ie, int mask_x, int mask_y)
{
   int      x, y;
   int     *lin_ptr;
   DATA32  *buf, *dptr;
   DATA32 **row_ptr;
   DATA32  *ptr, *dst_ptr, *src_data, *dst_data;
   DATA8   *mask;
   int      src_w, src_h, dst_w, dst_h;
   RGBA_Gfx_Func func, func2 = NULL;

   if ((!src->image.data) || (!dst->image.data)) return;
   if (!(RECTS_INTERSECT(dst_region_x, dst_region_y, dst_region_w, dst_region_h,
                         0, 0, dst->cache_entry.w, dst->cache_entry.h))) return;
   if (!(RECTS_INTERSECT(src_region_x, src_region_y, src_region_w, src_region_h,
                         0, 0, src->cache_entry.w, src->cache_entry.h))) return;

   if ((src_region_w <= 0) || (src_region_h <= 0) ||
       (dst_region_w <= 0) || (dst_region_h <= 0)) return;

   src_w = src->cache_entry.w;
   if (src_region_x >= src_w) return;

   src_h = src->cache_entry.h;
   if (src_region_y >= src_h) return;

   dst_w = dst->cache_entry.w;
   dst_h = dst->cache_entry.h;

   src_data = src->image.data;
   dst_data = dst->image.data;

   /* sanitise clip x */
   if (dst_clip_x < 0)
     {
        dst_clip_w += dst_clip_x;
        dst_clip_x = 0;
     }

   if ((dst_clip_x + dst_clip_w) > dst_w)
     dst_clip_w = dst_w - dst_clip_x;

   if (dst_clip_x < dst_region_x)
     {
        dst_clip_w += dst_clip_x - dst_region_x;
        dst_clip_x = dst_region_x;
     }

   if (dst_clip_x >= dst_w) return;

   if ((dst_clip_x + dst_clip_w) > (dst_region_x + dst_region_w))
     dst_clip_w = dst_region_x + dst_region_w - dst_clip_x;

   if (dst_clip_w <= 0) return;

   /* sanitise clip y */
   if (dst_clip_y < 0)
     {
        dst_clip_h += dst_clip_y;
        dst_clip_y = 0;
     }

   if ((dst_clip_y + dst_clip_h) > dst_h)
     dst_clip_h = dst_h - dst_clip_y;

   if (dst_clip_y < dst_region_y)
     {
        dst_clip_h += dst_clip_y - dst_region_y;
        dst_clip_y = dst_region_y;
     }

   if (dst_clip_y >= dst_h) return;

   if ((dst_clip_y + dst_clip_h) > (dst_region_y + dst_region_h))
     dst_clip_h = dst_region_y + dst_region_h - dst_clip_y;

   if (dst_clip_h <= 0) return;

   /* sanitise region x */
   if (src_region_x < 0)
     {
        dst_region_x -= (src_region_x * dst_region_w) / src_region_w;
        dst_region_w += (src_region_x * dst_region_w) / src_region_w;
        src_region_w += src_region_x;
        src_region_x = 0;

        if (dst_clip_x < dst_region_x)
          {
             dst_clip_w += (dst_clip_x - dst_region_x);
             dst_clip_x = dst_region_x;
          }
     }

   if ((dst_clip_x + dst_clip_w) > dst_w)
     dst_clip_w = dst_w - dst_clip_x;

   if (dst_clip_w <= 0) return;

   if ((src_region_x + src_region_w) > src_w)
     {
        dst_region_w = (dst_region_w * (src_w - src_region_x)) / (src_region_w);
        src_region_w = src_w - src_region_x;
     }

   if ((dst_region_w <= 0) || (src_region_w <= 0)) return;

   /* sanitise region y */
   if (src_region_y < 0)
     {
        dst_region_y -= (src_region_y * dst_region_h) / src_region_h;
        dst_region_h += (src_region_y * dst_region_h) / src_region_h;
        src_region_h += src_region_y;
        src_region_y = 0;

        if (dst_clip_y < dst_region_y)
          {
             dst_clip_h += (dst_clip_y - dst_region_y);
             dst_clip_y = dst_region_y;
          }
     }

   if ((dst_clip_y + dst_clip_h) > dst_h)
     dst_clip_h = dst_h - dst_clip_y;

   if (dst_clip_h <= 0) return;

   if ((src_region_y + src_region_h) > src_h)
     {
        dst_region_h = (dst_region_h * (src_h - src_region_y)) / (src_region_h);
        src_region_h = src_h - src_region_y;
     }

   if ((dst_region_h <= 0) || (src_region_h <= 0)) return;

   /* figure out dst jump */
   //dst_jump = dst_w - dst_clip_w;

   /* figure out dest start ptr */
   dst_ptr = dst_data + dst_clip_x + (dst_clip_y * dst_w);

   if (!mask_ie)
     {
         if (mul_col != 0xffffffff)
           func = evas_common_gfx_func_composite_pixel_color_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, mul_col, dst->cache_entry.flags.alpha, dst_clip_w, render_op);
         else
           func = evas_common_gfx_func_composite_pixel_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dst->cache_entry.flags.alpha, dst_clip_w, render_op);
     }
   else
     {
        if (mul_col != 0xffffffff)
          {
             func = evas_common_gfx_func_composite_pixel_mask_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dst->cache_entry.flags.alpha, dst_clip_w, render_op);
             func2 = evas_common_gfx_func_composite_pixel_color_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, mul_col, dst->cache_entry.flags.alpha, dst_clip_w, EVAS_RENDER_COPY);
          }
        else
          func = evas_common_gfx_func_composite_pixel_mask_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dst->cache_entry.flags.alpha, dst_clip_w, render_op);
        // Adjust clipping info
        if (EINA_UNLIKELY((dst_clip_x - mask_x) < 0))
          dst_clip_x = mask_x;
        if (EINA_UNLIKELY((dst_clip_y - mask_y) < 0))
          dst_clip_y = mask_y;
        if (EINA_UNLIKELY((dst_clip_x - mask_x + dst_clip_w) > (int)mask_ie->cache_entry.w))
          dst_clip_w = mask_ie->cache_entry.w - dst_clip_x + mask_x;
        if (EINA_UNLIKELY((dst_clip_y - mask_y + dst_clip_h) > (int)mask_ie->cache_entry.h))
          dst_clip_h = mask_ie->cache_entry.h - dst_clip_y + mask_y;
     }

   if ((dst_region_w == src_region_w) && (dst_region_h == src_region_h))
     {
        ptr = src_data + (((dst_clip_y - dst_region_y) + src_region_y) * src_w) + ((dst_clip_x - dst_region_x) + src_region_x);

        /* image masking */
        if (mask_ie)
          {
             if (mul_col != 0xffffffff)
               buf = alloca(dst_clip_w * sizeof(DATA32));

             for (y = 0; y < dst_clip_h; y++)
               {
                  mask = mask_ie->image.data8
                     + ((dst_clip_y - mask_y + y) * mask_ie->cache_entry.w)
                     + (dst_clip_x - mask_x);

                  /* * blend here [clip_w *] ptr -> dst_ptr * */
                  if (mul_col != 0xffffffff)
                    {
                       func2(ptr, NULL, mul_col, buf, dst_clip_w);
                       func(buf, mask, 0, dst_ptr, dst_clip_w);
                    }
                  else
                    func(ptr, mask, 0, dst_ptr, dst_clip_w);

                  ptr += src_w;
                  dst_ptr += dst_w;
               }
          }
        else
          {
             for (y = 0; y < dst_clip_h; y++)
               {
                  /* * blend here [clip_w *] ptr -> dst_ptr * */
                  func(ptr, NULL, mul_col, dst_ptr, dst_clip_w);

                  ptr += src_w;
                  dst_ptr += dst_w;
               }
          }
     }
   else
     {
        /* allocate scale lookup tables */
        lin_ptr = alloca(dst_clip_w * sizeof(int));
        row_ptr = alloca(dst_clip_h * sizeof(DATA32 *));

        /* fill scale tables */
        for (x = 0; x < dst_clip_w; x++)
          lin_ptr[x] = (((x + dst_clip_x - dst_region_x) * src_region_w) / dst_region_w) + src_region_x;
        for (y = 0; y < dst_clip_h; y++)
          row_ptr[y] = src_data + (((((y + dst_clip_y - dst_region_y) * src_region_h) / dst_region_h)
                                    + src_region_y) * src_w);

        /* scale to dst */
        dptr = dst_ptr;

        /* a scanline buffer */
        buf = alloca(dst_clip_w * sizeof(DATA32));

        /* image masking */
        if (mask_ie)
          {
             for (y = 0; y < dst_clip_h; y++)
               {
                  dst_ptr = buf;
                  mask = mask_ie->image.data8
                     + ((dst_clip_y - mask_y + y) * mask_ie->cache_entry.w)
                     + (dst_clip_x - mask_x);

                  for (x = 0; x < dst_clip_w; x++)
                    {
                       ptr = row_ptr[y] + lin_ptr[x];
                       *dst_ptr = *ptr;
                       dst_ptr++;
                    }

                  /* * blend here [clip_w *] buf -> dptr * */
                  if (mul_col != 0xffffffff)
                    func2(buf, NULL, mul_col, buf, dst_clip_w);
                  func(buf, mask, 0, dptr, dst_clip_w);

                  dptr += dst_w;
               }
          }
        else
          {
             for (y = 0; y < dst_clip_h; y++)
               {
                  dst_ptr = buf;

                  for (x = 0; x < dst_clip_w; x++)
                    {
                       ptr = row_ptr[y] + lin_ptr[x];
                       *dst_ptr = *ptr;
                       dst_ptr++;
                    }

                  /* * blend here [clip_w *] buf -> dptr * */
                  func(buf, NULL, mul_col, dptr, dst_clip_w);

                  dptr += dst_w;
               }
          }
     }
}