void soft8_rectangle_draw(Soft8_Image * dst, RGBA_Draw_Context * dc, int x, int y, int w, int h) { Eina_Rectangle dr; Cutout_Rects *rects; Cutout_Rect *r; struct RGBA_Draw_Context_clip c_bkp; int i; /* handle cutouts here! */ EINA_RECTANGLE_SET(&dr, x, y, w, h); if (_is_empty_rectangle(&dr)) return; if (! (RECTS_INTERSECT (dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h))) return; /* no cutouts - cut right to the chase */ if (!dc->cutout.rects) { _soft8_rectangle_draw_int(dst, dc, dr); return; } c_bkp = dc->clip; evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h); evas_common_draw_context_clip_clip(dc, x, y, w, h); /* our clip is 0 size.. abort */ if ((dc->clip.w <= 0) || (dc->clip.h <= 0)) { dc->clip = c_bkp; return; } rects = evas_common_draw_context_apply_cutouts(dc); for (i = 0; i < rects->active; ++i) { r = rects->rects + i; evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); _soft8_rectangle_draw_int(dst, dc, dr); } evas_common_draw_context_apply_clear_cutouts(rects); dc->clip = c_bkp; }
void feh_menu_draw_to_buf(feh_menu * m, Imlib_Image im, int ox, int oy) { feh_menu_item *i; int w, h; w = gib_imlib_image_get_width(im); h = gib_imlib_image_get_height(im); feh_menu_draw_menu_bg(m, im, ox, oy); for (i = m->items; i; i = i->next) { if (RECTS_INTERSECT(i->x, i->y, i->w, i->h, ox, oy, w, h)) feh_menu_draw_item(i, im, ox, oy); } return; }
EAPI Eina_Bool evas_common_rectangle_draw_prepare(Cutout_Rects *reuse, const RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h) { if ((w <= 0) || (h <= 0)) return EINA_FALSE; if (!(RECTS_INTERSECT(x, y, w, h, 0, 0, dst->cache_entry.w, dst->cache_entry.h))) return EINA_FALSE; /* save out clip info */ evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h); /* no cutouts - cut right to the chase */ if (dc->cutout.rects) { evas_common_draw_context_clip_clip(dc, x, y, w, h); /* our clip is 0 size.. abort */ if ((dc->clip.w > 0) && (dc->clip.h > 0)) reuse = evas_common_draw_context_apply_cutouts(dc, reuse); } return EINA_TRUE; }
EAPI void evas_common_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h) { Cutout_Rects *rects; Cutout_Rect *r; int c, cx, cy, cw, ch; int i; /* handle cutouts here! */ if ((w <= 0) || (h <= 0)) return; if (!(RECTS_INTERSECT(x, y, w, h, 0, 0, dst->cache_entry.w, dst->cache_entry.h))) return; /* save out clip info */ c = dc->clip.use; cx = dc->clip.x; cy = dc->clip.y; cw = dc->clip.w; ch = dc->clip.h; evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h); /* no cutouts - cut right to the chase */ if (!dc->cutout.rects) { rectangle_draw_internal(dst, dc, x, y, w, h); } else { evas_common_draw_context_clip_clip(dc, x, y, w, h); /* our clip is 0 size.. abort */ if ((dc->clip.w > 0) && (dc->clip.h > 0)) { rects = evas_common_draw_context_apply_cutouts(dc); for (i = 0; i < rects->active; ++i) { r = rects->rects + i; evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); rectangle_draw_internal(dst, dc, x, y, w, h); } evas_common_draw_context_apply_clear_cutouts(rects); } } /* restore clip info */ dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; }
int evas_common_draw_context_cutout_split(Cutout_Rects* res, int idx, Cutout_Rect *split) { /* 1 input rect, multiple out */ Cutout_Rect in = res->rects[idx]; /* this is to save me a LOT of typing */ #define INX1 (in.x) #define INX2 (in.x + in.w) #define SPX1 (split->x) #define SPX2 (split->x + split->w) #define INY1 (in.y) #define INY2 (in.y + in.h) #define SPY1 (split->y) #define SPY2 (split->y + split->h) #define X1_IN (in.x < split->x) #define X2_IN ((in.x + in.w) > (split->x + split->w)) #define Y1_IN (in.y < split->y) #define Y2_IN ((in.y + in.h) > (split->y + split->h)) #define R_NEW(_r, _x, _y, _w, _h) { evas_common_draw_context_cutouts_add(_r, _x, _y, _w, _h); } if (!RECTS_INTERSECT(in.x, in.y, in.w, in.h, split->x, split->y, split->w, split->h)) { /* No colision => no clipping, don't touch it. */ return 1; } /* S = split (ie cut out rect) */ /* +--+ = in (rect to be cut) */ /* * +---+ * | | * | S | * | | * +---+ * */ if (X1_IN && X2_IN && Y1_IN && Y2_IN) { R_NEW(res, in.x, in.y, in.w, SPY1 - in.y); R_NEW(res, in.x, SPY1, SPX1 - in.x, SPY2 - SPY1); R_NEW(res, SPX2, SPY1, INX2 - SPX2, SPY2 - SPY1); /* out => (in.x, SPY2, in.w, INY2 - SPY2) */ res->rects[idx].h = INY2 - SPY2; res->rects[idx].y = SPY2; return 1; } /* SSSSSSS * S+---+S * S|SSS|S * S|SSS|S * S|SSS|S * S+---+S * SSSSSSS */ if (!X1_IN && !X2_IN && !Y1_IN && !Y2_IN) { evas_common_draw_context_cutouts_del(res, idx); return 0; } /* SSS * S+---+ * S|S | * S|S | * S|S | * S+---+ * SSS */ if (!X1_IN && X2_IN && !Y1_IN && !Y2_IN) { /* in => (SPX2, in.y, INX2 - SPX2, in.h) */ res->rects[idx].w = INX2 - SPX2; res->rects[idx].x = SPX2; return 1; } /* S * +---+ * | S | * | S | * | S | * +---+ * S */ if (X1_IN && X2_IN && !Y1_IN && !Y2_IN) { R_NEW(res, in.x, in.y, SPX1 - in.x, in.h); /* in => (SPX2, in.y, INX2 - SPX2, in.h) */ res->rects[idx].w = INX2 - SPX2; res->rects[idx].x = SPX2; return 1; } /* SSS * +---+S * | S|S * | S|S * | S|S * +---+S * SSS */ if (X1_IN && !X2_IN && !Y1_IN && !Y2_IN) { /* in => (in.x, in.y, SPX1 - in.x, in.h) */ res->rects[idx].w = SPX1 - in.x; return 1; } /* SSSSSSS * S+---+S * S|SSS|S * | | * | | * +---+ * */ if (!X1_IN && !X2_IN && !Y1_IN && Y2_IN) { /* in => (in.x, SPY2, in.w, INY2 - SPY2) */ res->rects[idx].h = INY2 - SPY2; res->rects[idx].y = SPY2; return 1; } /* * +---+ * | | * S|SSS|S * | | * +---+ * */ if (!X1_IN && !X2_IN && Y1_IN && Y2_IN) { R_NEW(res, in.x, SPY2, in.w, INY2 - SPY2); /* in => (in.x, in.y, in.w, SPY1 - in.y) */ res->rects[idx].h = SPY1 - in.y; return 1; } /* * +---+ * | | * | | * S|SSS|S * S+---+S * SSSSSSS */ if (!X1_IN && !X2_IN && Y1_IN && !Y2_IN) { /* in => (in.x, in.y, in.w, SPY1 - in.y) */ res->rects[idx].h = SPY1 - in.y; return 1; } /* SSS * S+---+ * S|S | * | | * | | * +---+ * */ if (!X1_IN && X2_IN && !Y1_IN && Y2_IN) { R_NEW(res, SPX2, in.y, INX2 - SPX2, SPY2 - in.y); /* in => (in.x, SPY2, in.w, INY2 - SPY2) */ res->rects[idx].h = INY2 - SPY2; res->rects[idx].y = SPY2; return 1; } /* S * +---+ * | S | * | | * | | * +---+ * */ if (X1_IN && X2_IN && !Y1_IN && Y2_IN) { R_NEW(res, in.x, in.y, SPX1 - in.x, SPY2 - in.y); R_NEW(res, SPX2, in.y, INX2 - SPX2, SPY2 - in.y); /* in => (in.x, SPY2, in.w, INY2 - SPY2) */ res->rects[idx].h = INY2 - SPY2; res->rects[idx].y = SPY2; return 1; } /* SSS * +---+S * | S|S * | | * | | * +---+ * */ if (X1_IN && !X2_IN && !Y1_IN && Y2_IN) { R_NEW(res, in.x, in.y, SPX1 - in.x, SPY2 - in.y); /* in => (in.x, SPY2, in.w, INY2 - SPY2) */ res->rects[idx].h = INY2 - SPY2; res->rects[idx].y = SPY2; return 1; } /* * +---+ * | | * S|S | * | | * +---+ * */ if (!X1_IN && X2_IN && Y1_IN && Y2_IN) { R_NEW(res, in.x, SPY2, in.w, INY2 - SPY2); R_NEW(res, SPX2, SPY1, INX2 - SPX2, SPY2 - SPY1); /* in => (in.x, SPY2, in.w, INY2 - SPY2) */ res->rects[idx].h = SPY1 - in.y; return 1; } /* * +---+ * | | * | S|S * | | * +---+ * */ if (X1_IN && !X2_IN && Y1_IN && Y2_IN) { R_NEW(res, in.x, SPY2, in.w, INY2 - SPY2); R_NEW(res, in.x, SPY1, SPX1 - in.x, SPY2 - SPY1); /* in => (in.x, in.y, in.w, SPY1 - in.y) */ res->rects[idx].h = SPY1 - in.y; return 1; } /* * +---+ * | | * | | * S|S | * S+---+ * SSS */ if (!X1_IN && X2_IN && Y1_IN && !Y2_IN) { R_NEW(res, SPX2, SPY1, INX2 - SPX2, INY2 - SPY1); /* in => (in.x, in.y, in.w, SPY1 - in.y) */ res->rects[idx].h = SPY1 - in.y; return 1; } /* * +---+ * | | * | | * | S | * +---+ * S */ if (X1_IN && X2_IN && Y1_IN && !Y2_IN) { R_NEW(res, in.x, SPY1, SPX1 - in.x, INY2 - SPY1); R_NEW(res, SPX2, SPY1, INX2 - SPX2, INY2 - SPY1); /* in => (in.x, in.y, in.w, SPY1 - in.y) */ res->rects[idx].h = SPY1 - in.y; return 1; } /* * +---+ * | | * | | * | S|S * +---+S * SSS */ if (X1_IN && !X2_IN && Y1_IN && !Y2_IN) { R_NEW(res, in.x, SPY1, SPX1 - in.x, INY2 - SPY1); /* in => (in.x, in.y, in.w, SPY1 - in.y) */ res->rects[idx].h = SPY1 - in.y; return 1; } evas_common_draw_context_cutouts_del(res, idx); return 0; #undef INX1 #undef INX2 #undef SPX1 #undef SPX2 #undef INY1 #undef INY2 #undef SPY1 #undef SPY2 #undef X1_IN #undef X2_IN #undef Y1_IN #undef Y2_IN #undef R_NEW }
static void 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, *dptr; DATA32 **row_ptr; DATA32 *ptr, *dst_ptr, *src_data, *dst_data; int dst_clip_x, dst_clip_y, dst_clip_w, dst_clip_h; int m_clip_x = 0, m_clip_y = 0, m_clip_w = 0, m_clip_h = 0, mdx = 0, mdy = 0; int src_w, src_h, dst_w, dst_h; RGBA_Gfx_Func func; RGBA_Image *maskobj = NULL; DATA8 *mask = NULL; 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; 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; 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 (dc->mask.mask) { m_clip_x = dc->mask.x; m_clip_y = dc->mask.y; m_clip_w = dc->mask.mask->cache_entry.w; m_clip_h = dc->mask.mask->cache_entry.h; RECTS_CLIP_TO_RECT(m_clip_x, m_clip_y, m_clip_w, m_clip_h, dst_clip_x, dst_clip_y, dst_clip_w, dst_clip_h); if ((m_clip_w <= 0) || (m_clip_h <= 0)) return; dst_clip_x = m_clip_x; dst_clip_y = m_clip_y; dst_clip_w = m_clip_w; dst_clip_h = m_clip_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; /* 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; 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; if (src_region_w <= 0) return; if (dst_clip_x < 0) { dst_clip_w += dst_clip_x; dst_clip_x = 0; } if (dst_clip_w <= 0) return; if (dst_clip_x >= dst_w) return; 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; /* 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; 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; if (src_region_h <= 0) return; if (dst_clip_y < 0) { dst_clip_h += dst_clip_y; dst_clip_y = 0; } if (dst_clip_h <= 0) return; if (dst_clip_y >= dst_h) return; 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; /* allocate scale lookup tables */ lin_ptr = alloca(dst_clip_w * sizeof(int)); row_ptr = alloca(dst_clip_h * sizeof(DATA32 *)); /* 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 (dc->mask.mask) { func = evas_common_gfx_func_composite_pixel_mask_span_get(src, dst, dst_clip_w, dc->render_op); maskobj = dc->mask.mask; mask = maskobj->mask.mask; /* if (1 || dst_region_w > src_region_w || dst_region_h > src_region_h){ printf("Mask w/h: %d/%d\n",maskobj->cache_entry.w, maskobj->cache_entry.h); printf("Warning: Unscaled mask (%d/%d) // (%d/%d)\n", dst_region_w,src_region_w, dst_region_h,src_region_h); } */ } else if (dc->mul.use) func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op); else func = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, dc->render_op); 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->mask.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 if ((src->pixman.im) && (dst->pixman.im) && (dc->mask.mask) && (dc->mask.mask->pixman.im) && ((dc->render_op == _EVAS_RENDER_COPY) || (dc->render_op == _EVAS_RENDER_BLEND))) { // In case of pixel and color operation. 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, dc->mask.mask->pixman.im, 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; if (mask) { mdx = (m_clip_x - dc->mask.x) + (m_clip_x - dst_clip_x); mdy = (m_clip_y - dc->mask.y) + (m_clip_y - dst_clip_y); mask += mdx + (mdy * maskobj->cache_entry.w); } for (y = 0; y < dst_clip_h; y++) { /* * blend here [clip_w *] ptr -> dst_ptr * */ func(ptr, mask, dc->mul.col, dst_ptr, dst_clip_w); ptr += src_w; dst_ptr += dst_w; if (mask) mask += maskobj->cache_entry.w; } } } else { /* 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)) { 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 { /* a scanline buffer */ buf = alloca(dst_clip_w * sizeof(DATA32)); 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, dc->mul.col, dptr, dst_clip_w); dptr += dst_w; } } } }
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) { int x, y; int *lin_ptr; DATA32 *buf, *dptr; DATA32 **row_ptr; DATA32 *ptr, *dst_ptr, *src_data, *dst_data; int src_w, src_h, dst_w, dst_h; RGBA_Gfx_Func func; 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; 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; 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; 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; /* 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; 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; if (src_region_w <= 0) return; if (dst_clip_x < 0) { dst_clip_w += dst_clip_x; dst_clip_x = 0; } if (dst_clip_w <= 0) return; if (dst_clip_x >= dst_w) return; 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; /* 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; 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; if (src_region_h <= 0) return; if (dst_clip_y < 0) { dst_clip_h += dst_clip_y; dst_clip_y = 0; } if (dst_clip_h <= 0) return; if (dst_clip_y >= dst_h) return; 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; /* allocate scale lookup tables */ lin_ptr = alloca(dst_clip_w * sizeof(int)); row_ptr = alloca(dst_clip_h * sizeof(DATA32 *)); /* 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 (mul_col != 0xffffffff) func = evas_common_gfx_func_composite_pixel_color_span_get(src, mul_col, dst, dst_clip_w, render_op); else func = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, render_op); 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; 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 { /* 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)); 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; } } }
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); }
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; } } } }