#include "evas_common.h" 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); #ifndef BUILD_SCALE_SMOOTH #ifdef BUILD_SCALE_SAMPLE void evas_common_scale_rgba_in_to_out_clip_smooth(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) { evas_common_scale_rgba_in_to_out_clip_sample(src, dst, dc, src_region_x, src_region_y, src_region_w, src_region_h, dst_region_x, dst_region_y, dst_region_w, dst_region_h); } #endif #endif #ifdef BUILD_SCALE_SAMPLE void evas_common_scale_rgba_in_to_out_clip_sample(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 c, cx, cy, cw, ch; Cutout_Rect *rects, *r; Evas_Object_List *l; /* handle cutouts here! */ if ((dst_region_w <= 0) || (dst_region_h <= 0)) return; if (!(RECTS_INTERSECT(dst_region_x, dst_region_y, dst_region_w, dst_region_h, 0, 0, dst->image->w, dst->image->h))) return; /* no cutouts - cut right to the chase */ if (!dc->cutout.rects) { scale_rgba_in_to_out_clip_sample_internal(src, dst, dc, src_region_x, src_region_y, src_region_w, src_region_h, dst_region_x, dst_region_y, dst_region_w, dst_region_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->image->w, dst->image->h); evas_common_draw_context_clip_clip(dc, dst_region_x, dst_region_y, dst_region_w, dst_region_h); /* our clip is 0 size.. abort */ if ((dc->clip.w <= 0) || (dc->clip.h <= 0)) { dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; return; } rects = evas_common_draw_context_apply_cutouts(dc); for (l = (Evas_Object_List *)rects; l; l = l->next) { r = (Cutout_Rect *)l; evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); scale_rgba_in_to_out_clip_sample_internal(src, dst, dc, src_region_x, src_region_y, src_region_w, src_region_h, dst_region_x, dst_region_y, dst_region_w, dst_region_h); } evas_common_draw_context_apply_free_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; } 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_jump; int dst_clip_x, dst_clip_y, dst_clip_w, dst_clip_h; int src_w, src_h, dst_w, dst_h; if (!(RECTS_INTERSECT(dst_region_x, dst_region_y, dst_region_w, dst_region_h, 0, 0, dst->image->w, dst->image->h))) return; if (!(RECTS_INTERSECT(src_region_x, src_region_y, src_region_w, src_region_h, 0, 0, src->image->w, src->image->h))) return; src_w = src->image->w; src_h = src->image->h; dst_w = dst->image->w; dst_h = dst->image->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 (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 = malloc(dst_clip_w * sizeof(int)); if (!lin_ptr) goto no_lin_ptr; row_ptr = malloc(dst_clip_h * sizeof(DATA32 *)); if (!row_ptr) goto no_row_ptr; /* 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->mod.use) { Gfx_Func_Blend_Src_Cmod_Dst func; func = evas_common_draw_func_blend_cmod_get(src, dst, dst_clip_w); /* if 1:1 scale */ 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, dst_ptr, dst_clip_w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); ptr += src_w; dst_ptr += dst_w; } } else { /* a scanline buffer */ buf = malloc(dst_clip_w * sizeof(DATA32)); if (!buf) goto no_buf; /* 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; 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, dptr, dst_clip_w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); dptr += dst_w; } free(buf); } } else if (dc->mul.use) { Gfx_Func_Blend_Src_Mul_Dst func; func = evas_common_draw_func_blend_mul_get(src, dc->mul.col, dst, dst_clip_w); /* if 1:1 scale */ 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, dst_ptr, dst_clip_w, dc->mul.col); ptr += src_w; dst_ptr += dst_w; } } else { /* a scanline buffer */ buf = malloc(dst_clip_w * sizeof(DATA32)); if (!buf) goto no_buf; /* 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; 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, dptr, dst_clip_w, dc->mul.col); dptr += dst_w; } free(buf); } } else { Gfx_Func_Blend_Src_Dst func; func = evas_common_draw_func_blend_get(src, dst, dst_clip_w); /* if 1:1 scale */ 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, dst_ptr, dst_clip_w); ptr += src_w; dst_ptr += dst_w; } } else { /* a scanline buffer */ buf = malloc(dst_clip_w * sizeof(DATA32)); if (!buf) goto no_buf; /* 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; 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, dptr, dst_clip_w); dptr += dst_w; } free(buf); } } no_buf: /* free scale tables */ free(row_ptr); no_row_ptr: free(lin_ptr); //_WIN32_WCE no_lin_ptr: ; } #else #ifdef BUILD_SCALE_SMOOTH void evas_common_scale_rgba_in_to_out_clip_sample(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) { evas_common_scale_rgba_in_to_out_clip_smooth(src, dst, dc, src_region_x, src_region_y, src_region_w, src_region_h, dst_region_x, dst_region_y, dst_region_w, dst_region_h); } #endif #endif