From a8ccf132b8ee9eeb323f64b5841e4b1ff94c2caf Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Thu, 28 Dec 2000 03:54:58 +0000 Subject: [PATCH] err commit? SVN revision: 4048 --- src/Imlib2.h | 1 + src/api.c | 87 ++++++++++++++------- src/blend.c | 31 ++++++-- src/blend.h | 47 +++++++++++- src/font.c | 211 +++++++++++++++------------------------------------ src/font.h | 6 +- src/grad.c | 82 ++++++++++++++------ src/grad.h | 2 +- src/rend.c | 117 +++++++++++++++++++++++++++- src/rend.h | 4 + src/rotate.c | 3 +- src/rotate.h | 4 +- 12 files changed, 378 insertions(+), 217 deletions(-) diff --git a/src/Imlib2.h b/src/Imlib2.h index 59e45f2..b3e81c5 100644 --- a/src/Imlib2.h +++ b/src/Imlib2.h @@ -190,6 +190,7 @@ extern "C" int source_height, int x, int y, int width, int height); + DATA32 imlib_render_get_pixel_color(void); #endif void imlib_blend_image_onto_image(Imlib_Image source_image, char merge_alpha, int source_x, diff --git a/src/api.c b/src/api.c index 32ef381..fe2174a 100644 --- a/src/api.c +++ b/src/api.c @@ -900,6 +900,16 @@ imlib_render_image_part_on_drawable_at_size(int source_x, int source_y, ctxt_anti_alias, ctxt_dither, ctxt_blend, 0, ctxt_color_modifier, ctxt_operation); } + +DATA32 +imlib_render_get_pixel_color(void) +{ + return __imlib_RenderGetPixel(ctxt_display, ctxt_drawable, ctxt_visual, ctxt_colormap, ctxt_depth, + (DATA8)ctxt_color.red, + (DATA8)ctxt_color.green, + (DATA8)ctxt_color.blue); +} + #endif void @@ -910,7 +920,8 @@ imlib_blend_image_onto_image(Imlib_Image source_image, char merge_alpha, int destination_height) { ImlibImage *im_src, *im_dst; - + int aa; + CHECK_PARAM_POINTER("imlib_blend_image_onto_image", "source_image", source_image); CHECK_PARAM_POINTER("imlib_blend_image_onto_image", "image", ctxt_image); @@ -927,19 +938,16 @@ imlib_blend_image_onto_image(Imlib_Image source_image, char merge_alpha, __imlib_DirtyImage(im_dst); __imlib_DirtyPixmapsForImage(im_dst); /* FIXME: hack to get around infinite loops for scaling down too far */ + aa = ctxt_anti_alias; if ((abs(destination_width) < (source_width >> 7)) - || (abs(destination_height) < (source_height >> 7))) - __imlib_BlendImageToImage(im_src, im_dst, 0, ctxt_blend, merge_alpha, - source_x, source_y, source_width, - source_height, destination_x, destination_y, - destination_width, destination_height, - ctxt_color_modifier, ctxt_operation); - else - __imlib_BlendImageToImage(im_src, im_dst, ctxt_anti_alias, ctxt_blend, - merge_alpha, source_x, source_y, source_width, - source_height, destination_x, destination_y, - destination_width, destination_height, - ctxt_color_modifier, ctxt_operation); + || (abs(destination_height) < (source_height >> 7))) aa = 0; + __imlib_BlendImageToImage(im_src, im_dst, aa, ctxt_blend, + merge_alpha, source_x, source_y, source_width, + source_height, destination_x, destination_y, + destination_width, destination_height, + ctxt_color_modifier, ctxt_operation, + ctxt_cliprect.x, ctxt_cliprect.y, + ctxt_cliprect.w, ctxt_cliprect.h); } Imlib_Image @@ -1252,7 +1260,9 @@ imlib_create_cropped_image(int x, int y, int width, int height) } __imlib_BlendImageToImage(im_old, im, 0, 0, 0, x, y, abs(width), abs(height), 0, 0, width, height, NULL, - IMLIB_OP_COPY); + IMLIB_OP_COPY, + ctxt_cliprect.x, ctxt_cliprect.y, + ctxt_cliprect.w, ctxt_cliprect.h); return (Imlib_Image) im; } @@ -1287,14 +1297,18 @@ imlib_create_cropped_scaled_image(int source_x, int source_y, __imlib_BlendImageToImage(im_old, im, ctxt_anti_alias, 0, 1, source_x, source_y, source_width, source_height, 0, 0, destination_width, destination_height, NULL, - IMLIB_OP_COPY); + IMLIB_OP_COPY, + ctxt_cliprect.x, ctxt_cliprect.y, + ctxt_cliprect.w, ctxt_cliprect.h); } else { __imlib_BlendImageToImage(im_old, im, ctxt_anti_alias, 0, 0, source_x, source_y, source_width, source_height, 0, 0, destination_width, destination_height, NULL, - IMLIB_OP_COPY); + IMLIB_OP_COPY, + ctxt_cliprect.x, ctxt_cliprect.y, + ctxt_cliprect.w, ctxt_cliprect.h); } return (Imlib_Image) im; } @@ -1808,8 +1822,10 @@ imlib_text_draw_with_return_metrics(int x, int y, const char *text, (DATA8)ctxt_color.alpha, (char)dir, ctxt_angle, width_return, height_return, 0, horizontal_advance_return, vertical_advance_return, - ctxt_operation); - return; + ctxt_operation, + ctxt_cliprect.x, ctxt_cliprect.y, + ctxt_cliprect.w, ctxt_cliprect.h); + return; case IMLIB_FONT_TYPE_X: __imlib_xfd_draw_str(ctxt_display, ctxt_drawable, ctxt_visual, @@ -1820,8 +1836,9 @@ imlib_text_draw_with_return_metrics(int x, int y, const char *text, ctxt_angle, ctxt_blend, ctxt_color_modifier, ctxt_dither, ctxt_dither_mask, ctxt_operation, width_return, height_return, - horizontal_advance_return, vertical_advance_return); - + horizontal_advance_return, vertical_advance_return, + ctxt_cliprect.x, ctxt_cliprect.y, + ctxt_cliprect.w, ctxt_cliprect.h); return; case IMLIB_FONT_TYPE_TTF_X: @@ -1929,8 +1946,10 @@ imlib_text_draw_with_return_metrics(int x, int y, const char *text, (char)dir, ctxt_angle, &retw, &reth, 0, &nextx, &nexty, - ctxt_operation); - + ctxt_operation, + ctxt_cliprect.x, ctxt_cliprect.y, + ctxt_cliprect.w, ctxt_cliprect.h); + else if (oldlen > 1 || oldlen == -1) __imlib_xfd_draw_str(ctxt_display, ctxt_drawable, ctxt_visual, ctxt_depth, ctxt_colormap, @@ -1943,8 +1962,10 @@ imlib_text_draw_with_return_metrics(int x, int y, const char *text, ctxt_blend, ctxt_color_modifier, ctxt_dither, ctxt_dither_mask, ctxt_operation, - &retw, &reth, &nextx, &nexty); - + &retw, &reth, &nextx, &nexty, + ctxt_cliprect.x, ctxt_cliprect.y, + ctxt_cliprect.w, ctxt_cliprect.h); + /* #### DEBUG DEBUG DEBUG #### __imlib_draw_box(im, x1, y1, retw, reth, (DATA8)ctxt_color.red, @@ -2095,8 +2116,10 @@ imlib_get_text_size(const char *text, int *width_return, int *height_return) __imlib_render_str(&im, fn, 1, 1, tmp, (DATA8)0, (DATA8)0, (DATA8)0, (DATA8)0, (char)0, (double)0, NULL, NULL, 0, - &ww, &hh, 0); - } + &ww, &hh, 0, + ctxt_cliprect.x, ctxt_cliprect.y, + ctxt_cliprect.w, ctxt_cliprect.h); + } else if (oldlen > 1 || oldlen == -1) { XRectangle i_ret, l_ret; @@ -3093,7 +3116,9 @@ imlib_image_fill_color_range_rectangle(int x, int y, int width, int height, __imlib_DirtyPixmapsForImage(im); __imlib_DrawGradient(im, x, y, width, height, (ImlibRange *) ctxt_color_range, angle, - ctxt_operation); + ctxt_operation, + ctxt_cliprect.x, ctxt_cliprect.y, + ctxt_cliprect.w, ctxt_cliprect.h); } void @@ -3330,7 +3355,9 @@ imlib_blend_image_onto_image_at_angle(Imlib_Image source_image, source_y, source_width, source_height, destination_x, destination_y, angle_x, angle_y, 0, 0, ctxt_color_modifier, - ctxt_operation); + ctxt_operation, + ctxt_cliprect.x, ctxt_cliprect.y, + ctxt_cliprect.w, ctxt_cliprect.h); } void @@ -3365,7 +3392,9 @@ imlib_blend_image_onto_image_skewed(Imlib_Image source_image, source_y, source_width, source_height, destination_x, destination_y, h_angle_x, h_angle_y, v_angle_x, v_angle_y, - ctxt_color_modifier, ctxt_operation); + ctxt_color_modifier, ctxt_operation, + ctxt_cliprect.x, ctxt_cliprect.y, + ctxt_cliprect.w, ctxt_cliprect.h); } #ifndef X_DISPLAY_MISSING diff --git a/src/blend.c b/src/blend.c index e2cbb07..4aae7ab 100644 --- a/src/blend.c +++ b/src/blend.c @@ -62,10 +62,10 @@ /* COPY OPS */ -static int pow_lut_initialized = 0; -static DATA8 pow_lut[256][256]; +int pow_lut_initialized = 0; +DATA8 pow_lut[256][256]; -static void +void __imlib_build_pow_lut(void) { int i, j; @@ -1022,7 +1022,8 @@ __imlib_BlendImageToImage(ImlibImage *im_src, ImlibImage *im_dst, char aa, char blend, char merge_alpha, int ssx, int ssy, int ssw, int ssh, int ddx, int ddy, int ddw, int ddh, - ImlibColorModifier *cm, ImlibOp op) + ImlibColorModifier *cm, ImlibOp op, + int clx, int cly, int clw, int clh) { char rgb_src = 0; @@ -1046,12 +1047,26 @@ __imlib_BlendImageToImage(ImlibImage *im_src, ImlibImage *im_dst, if (merge_alpha) blend = 1; } + if (clw) + { + int px, py; + + px = ddx; + py = ddy; + CLIP_TO(ddx, ddy, ddw, ddh, clx, cly, clw, clh); + px = ddx - px; + py = ddy - py; + ssx += px; + ssy += py; + if ((ssw < 1) || (ssh < 1)) return; + if ((ddw < 1) || (ddh < 1)) return; + } __imlib_BlendRGBAToData(im_src->data, im_src->w, im_src->h, im_dst->data, im_dst->w, im_dst->h, ssx, ssy, ddx, ddy, - ssw, ssh, blend, merge_alpha, cm, op, rgb_src); + ddw, ddh, blend, merge_alpha, cm, op, rgb_src); } else { @@ -1099,9 +1114,11 @@ __imlib_BlendImageToImage(ImlibImage *im_src, ImlibImage *im_dst, x2 = sx; y2 = sy; CLIP(dx, dy, dw, dh, 0, 0, im_dst->w, im_dst->h); - if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0)) + if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0)) return; + if (clw) { - return; + CLIP_TO(dx, dy, dw, dh, clx, cly, clw, clh); + if ((dw < 1) || (dh < 1)) return; } if (psx != dx) sx += ((dx - psx) * ssw) / abs(ddw); diff --git a/src/blend.h b/src/blend.h index 8fcc14f..eff3581 100644 --- a/src/blend.h +++ b/src/blend.h @@ -46,7 +46,39 @@ B_VAL(p) = (b); \ A_VAL(p) = (a); +#define INTERSECTS(x, y, w, h, xx, yy, ww, hh) \ + ((x < (xx + ww)) && \ + (y < (yy + hh)) && \ + ((x + w) > xx) && \ + ((y + h) > yy)) +#define CLIP_TO(_x, _y, _w, _h, _cx, _cy, _cw, _ch) \ +{ \ +if (INTERSECTS(_x, _y, _w, _h, _cx, _cy, _cw, _ch)) \ + { \ + if (_x < _cx) \ + { \ + _w += _x - _cx; \ + _x = _cx; \ + if (_w < 0) _w = 0; \ + } \ + if ((_x + _w) > (_cx + _cw)) \ + _w = _cx + _cw - _x; \ + if (_y < _cy) \ + { \ + _h += _y - _cy; \ + _y = _cy; \ + if (_h < 0) _h = 0; \ + } \ + if ((_y + _h) > (_cy + _ch)) \ + _h = _cy + _ch - _y; \ + } \ +else \ + { \ + _w = 0; _h = 0; \ + } \ +} + /* * 1) Basic Saturation - 8 bit unsigned * @@ -294,6 +326,18 @@ SATURATE_BOTH(nc, tmp); tmp = (cc) + (((c) - 127) << 1); \ SATURATE_BOTH(nc, tmp); +extern int pow_lut_initialized; +extern DATA8 pow_lut[256][256]; + +#define BLEND_DST_ALPHA(r1, g1, b1, a1, dest) \ +{ int _aa; \ +_aa = pow_lut[a1][A_VAL(dest)]; \ +BLEND_COLOR(_aa, R_VAL(dest), r1, R_VAL(dest)); \ +BLEND_COLOR(_aa, G_VAL(dest), g1, G_VAL(dest)); \ +BLEND_COLOR(_aa, B_VAL(dest), b1, B_VAL(dest)); \ +A_VAL(dest) = A_VAL(dest) + ((a1 * (255 - A_VAL(dest))) / 255); \ +} + #define BLEND(r1, g1, b1, a1, dest) \ BLEND_COLOR(a1, R_VAL(dest), r1, R_VAL(dest)); \ BLEND_COLOR(a1, G_VAL(dest), g1, G_VAL(dest)); \ @@ -338,7 +382,8 @@ __imlib_BlendImageToImage(ImlibImage *im_src, ImlibImage *im_dst, char aa, char blend, char merge_alpha, int ssx, int ssy, int ssw, int ssh, int ddx, int ddy, int ddw, int ddh, - ImlibColorModifier *cm, ImlibOp op); + ImlibColorModifier *cm, ImlibOp op, + int clx, int cly, int clw, int clh); void __imlib_BlendRGBAToData(DATA32 *src, int src_w, int src_h, DATA32 *dst, int dst_w, int dst_h, int sx, int sy, int dx, int dy, diff --git a/src/font.c b/src/font.c index 97f3db1..5373b6a 100644 --- a/src/font.c +++ b/src/font.c @@ -725,7 +725,8 @@ void __imlib_render_str(ImlibImage *im, ImlibFont *f, int drx, int dry, const char *text, DATA8 r, DATA8 g, DATA8 b, DATA8 a, char dir, double angle, int *retw, int *reth, int blur, - int *nextx, int *nexty, ImlibOp op) + int *nextx, int *nexty, ImlibOp op, + int clx, int cly, int clw, int clh) { DATA32 lut[9], *p, *tmp; TT_Glyph_Metrics metrics; @@ -754,22 +755,6 @@ __imlib_render_str(ImlibImage *im, ImlibFont *f, int drx, int dry, const char *t return; } -#if 0 - /* if we draw outside the image from here - give up */ - if ((drx > im->w) || (dry > im->h)) - { - if ((retw) || (reth)) - { - __imlib_calc_size(f, &w, &h, text); - if (retw) - *retw = w; - if (reth) - *reth = h; - } - return; - } -#endif - /* build LUT table */ for (i = 0; i < 9; i++) lut[i] = (DATA32)( @@ -900,33 +885,9 @@ __imlib_render_str(ImlibImage *im, ImlibFont *f, int drx, int dry, const char *t rtmp = fn->glyphs_cached_right[j]; if (!rtmp) { -#if 1 rtmp = __imlib_create_font_raster(((xmax - xmin) / 64) + 1, ((ymax - ymin) / 64) + 1); TT_Get_Glyph_Pixmap(fn->glyphs[j], rtmp, -xmin, -ymin); -#else - TT_Raster_Map *rbuf; - - rbuf = __imlib_create_font_raster(((xmax - xmin) / 64) + 1, - ((ymax - ymin) / 64) + 1); - rtmp = __imlib_create_font_raster(((xmax - xmin) / 64) + 1, - ((ymax - ymin) / 64) + 1); - TT_Get_Glyph_Bitmap(fn->glyphs[j], rbuf, -xmin, -ymin); - for (y = 0; y < rtmp->rows; y++) - { - for (x = 0; x < rtmp->cols; x++) - { - int val; - - val = (((DATA8 *)rbuf->bitmap)[(y * rbuf->cols) + (x >> 3)] >> (7 - (x - ((x >> 3) << 3))) & 0x1); - ((DATA8 *)(rtmp->bitmap))[(y * rtmp->cols) + x] = val * 8; - printf("%i", val); - } - printf("\n"); - } - - __imlib_destroy_font_raster(rbuf); -#endif fn->glyphs_cached_right[j] = rtmp; fn->mem_use += (((xmax - xmin) / 64) + 1) * @@ -1020,6 +981,7 @@ __imlib_render_str(ImlibImage *im, ImlibFont *f, int drx, int dry, const char *t } /* blend buffer onto image */ im2.data = tmp; + SET_FLAG(im2.flags, F_HAS_ALPHA); im2.w = rmap->cols; im2.h = rmap->rows; if (blur > 0) @@ -1046,10 +1008,10 @@ __imlib_render_str(ImlibImage *im, ImlibFont *f, int drx, int dry, const char *t } tmp = im2.data; if (angle == 0.0) { - __imlib_BlendRGBAToData(tmp, im2.w, im2.h, - im->data, im->w, im->h, - 0, 0, drx, dry, im2.w, im2.h, - 1, IMAGE_HAS_ALPHA(im), NULL, op, 0); + __imlib_BlendImageToImage(&im2, im, 0, 1, 0, + 0, 0, im2.w, im2.h, + drx, dry, im2.w, im2.h, + NULL, OP_COPY, clx, cly, clw, clh); } else { int xx, yy; double sa, ca; @@ -1066,10 +1028,11 @@ __imlib_render_str(ImlibImage *im, ImlibFont *f, int drx, int dry, const char *t yy -= ca * im2.h; } __imlib_BlendImageToImageSkewed(&im2, im, 1, 1, - IMAGE_HAS_ALPHA(im), - 0, 0, im2.w, im2.h, - xx, yy, (w * ca), (w * sa), 0, 0, - NULL, op); + IMAGE_HAS_ALPHA(im), + 0, 0, im2.w, im2.h, + xx, yy, (w * ca), (w * sa), 0, 0, + NULL, op, + clx, cly, clw, clh); } free(tmp); } @@ -1083,7 +1046,8 @@ __imlib_xfd_draw_str(Display *display, Drawable drawable, Visual *v, int depth, const char *text, DATA8 r, DATA8 g, DATA8 b, DATA8 a, char dir, double angle, char blend, ImlibColorModifier *cmod, char hiq, char dmask, - ImlibOp op, int *retw, int *reth, int *nextx, int *nexty) + ImlibOp op, int *retw, int *reth, int *nextx, int *nexty, + int clx, int cly, int clw, int clh) { ImlibImage *im2; ImlibImagePixmap *ip; @@ -1189,6 +1153,7 @@ __imlib_xfd_draw_str(Display *display, Drawable drawable, Visual *v, int depth, __imlib_GrabDrawableToRGBA(im2->data, 0, 0, im2->w, im2->h, display, m, NULL, v, NULL, 1, 0, 0, im2->w, im2->h, 0, 0); + SET_FLAG(im2->flags, F_HAS_ALPHA); #endif /* @@ -1197,108 +1162,52 @@ __imlib_xfd_draw_str(Display *display, Drawable drawable, Visual *v, int depth, printf( "l_ret.x=%d, l_ret.y=%d, l_ret.w=%d, l_ret.h=%d, dascent=%d\n", l_ret.x, l_ret.y, l_ret.width, l_ret.height, fn->xf.descent); */ - for (y1=0; y1h; y1++) + switch(dir) { - for (x1=0; x1w; x1++) - { - if (im2->data[im2->w * y1 + x1] & 0x00ffffff) - { - DATA32 *p; - int rr, gg, bb, aa, tmp, nr, ng, nb, na; - - switch(dir) - { - case 0: /* to right */ - if ( y + y1 < 0 || y + y1 >= im->h) - continue; - if (x + x1 < 0 || x + x1 >= im->w) - continue; - - p = im->data + im->w * (y + y1) + x + x1; - break; - - case 1: /* to left */ - if (y + i_ret.height - y1 < 0 || - y + i_ret.height - y1 >= im->h) - continue; - if (x + i_ret.width - x1 < 0 || - x + i_ret.width - x1 >= im->w) - continue; - - p = im->data + im->w * (y + i_ret.height - y1) + - x + i_ret.width - x1; - break; - - case 2: /* to down */ - if (y + x1 < 0 || y + x1 >= im->h) - continue; - if (x + i_ret.height - y1 < 0 || - x + i_ret.height - y1 >= im->w) - continue; - - p = im->data + im->w * (y + x1) + x + i_ret.height - y1; - break; - - case 3: /* to up */ - if (y + i_ret.width - x1 < 0 || - y + i_ret.width - x1 >= im->h) - continue; - if (x + y1 < 0 || x + y1 >= im->w) - continue; - - p = im->data + im->w * (y + i_ret.width - x1) + x + y1; - break; - - case 4: /* angle */ - { /* However, I cann't make sure these are correct or not. */ - int x2, y2; - double sa, ca; - - sa = sin(angle); - ca = cos(angle); - if (sa > 0) - { - x2 = fn->xf.max_ascent * sa + x1 * ca - y1 * sa; - y2 = fn->xf.max_ascent - fn->xf.max_ascent * ca + - x1 * sa + y1 * ca; - } - else - { - sa *= -1; - x2 = i_ret.width - fn->xf.max_ascent * sa - - (i_ret.width - x1) * ca + y1 * sa; - y2 = fn->xf.max_ascent - fn->xf.max_ascent * ca + - (i_ret.width - x1) * sa + y1 * ca; - } - - if ( y + y2 < 0 || y + y2 >= im->h) - continue; - if (x + x2 < 0 || x + x2 >= im->w) - continue; - - p = im->data + im->w * (y + y2) + x + x2; - - } - break; - } - - switch(op) - { - case OP_COPY: - XMB_BLEND(r, g, b, a, *p); - break; - case OP_ADD: - XMB_BLEND_ADD(r, g, b, a, *p); - break; - case OP_SUBTRACT: - XMB_BLEND_SUB(r, g, b, a, *p); - break; - case OP_RESHADE: - XMB_BLEND_RE(r, g, b, a, *p); - break; - } - } - } + case 0: /* to right */ + angle = 0.0; + break; + case 1: /* to left */ + angle = 0.0; + __imlib_FlipImageBoth(im2); + break; + case 2: /* to down */ + angle = 0.0; + __imlib_FlipImageDiagonal(im2, 1); + break; + case 3: /* to up */ + angle = 0.0; + __imlib_FlipImageDiagonal(im2, 2); + break; + default: + break; + } + if (angle == 0.0) { + __imlib_BlendImageToImage(im2, im, 0, blend, 0, + 0, 0, im2->w, im2->h, + x, y, im2->w, im2->h, + NULL, OP_COPY, clx, cly, clw, clh); + } else { + int xx, yy; + double sa, ca; + sa = sin(angle); + ca = cos(angle); + xx = x; + yy = y; + if (sa > 0.0) + xx += sa * im2->h; + else + yy -= sa * im2->w; + if (ca < 0.0) { + xx -= ca * im2->w; + yy -= ca * im2->h; + } + __imlib_BlendImageToImageSkewed(im2, im, 1, 1, + IMAGE_HAS_ALPHA(im), + 0, 0, im2->w, im2->h, + xx, yy, (im2->w * ca), (im2->w * sa), 0, 0, + NULL, op, + clx, cly, clw, clh); } #ifndef XMB_FONT_CACHE diff --git a/src/font.h b/src/font.h index 7efcf11..2ea3124 100644 --- a/src/font.h +++ b/src/font.h @@ -133,7 +133,8 @@ void __imlib_render_str(ImlibImage *im, ImlibFont *fn, int drx, int dry, const char *text, DATA8 r, DATA8 g, DATA8 b, DATA8 a, char dir, double angle, int *retw, int *reth, int blur, - int *nextx, int *nexty, ImlibOp op); + int *nextx, int *nexty, ImlibOp op, + int cx, int cy, int cw, int ch); void __imlib_xfd_draw_str(Display *display, Drawable drawable, Visual *v, int depth, Colormap cm, ImlibImage *im, ImlibFont *fn, int x, @@ -142,7 +143,8 @@ void __imlib_xfd_draw_str(Display *display, Drawable drawable, char blend, ImlibColorModifier *cmod, char hiq, char dmask, ImlibOp op, int *retw, int *reth, - int *nextx, int *nexty); + int *nextx, int *nexty, + int cx, int cy, int cw, int ch); #ifdef XMB_FONT_CACHE void __imlib_xfd_build_str_image(Display *display, Drawable drawable, Visual *v, ImlibFont *fn, ImlibImage *im, diff --git a/src/grad.c b/src/grad.c index ff88d3a..eeca3b6 100644 --- a/src/grad.c +++ b/src/grad.c @@ -143,7 +143,8 @@ __imlib_MapRange(ImlibRange *rg, int len) void __imlib_DrawGradient(ImlibImage *im, int x, int y, int w, int h, - ImlibRange *rg, double angle, ImlibOp op) + ImlibRange *rg, double angle, ImlibOp op, + int clx, int cly, int clw, int clh) { DATA32 *map, *p, v; int *hlut, *vlut, len = 0, xx, yy, xoff = 0, yoff = 0, ww, hh, jump; @@ -176,6 +177,18 @@ __imlib_DrawGradient(ImlibImage *im, int x, int y, int w, int h, h = (im->h - y); if (h <= 0) return; + if (clw) + { + int px, py; + + CLIP_TO(clx, cly, clw, clh, 0, 0, im->w, im->h); + px = x; + py = y; + CLIP_TO(x, y, w, h, clx, cly, clw, clh); + if ((w < 1) || (h < 1)) return; + xoff += (x - px); + yoff += (y - py); + } hlut = malloc(sizeof(int) * ww); vlut = malloc(sizeof(int) * hh); @@ -208,36 +221,59 @@ __imlib_DrawGradient(ImlibImage *im, int x, int y, int w, int h, vlut[i] = (yy * i * len) / ((hh - 1) << 5); } jump = im->w - w; + p = im->data + (y * im->w) + x; switch (op) { - case OP_COPY: - for (yy = 0; yy < h; yy++) + case OP_COPY: + if (IMAGE_HAS_ALPHA(im)) { - for (xx = 0; xx < w; xx++) + __imlib_build_pow_lut(); + for (yy = 0; yy < h; yy++) { - i = vlut[yoff + yy] + hlut[xoff + xx]; - if (i < 0) - i = 0; - else if (i >= len) - i = len - 1; - READ_RGBA(&(map[i]), r, g, b, a); - BLEND(r, g, b, a, p); - p++; + for (xx = 0; xx < w; xx++) + { + i = vlut[yoff + yy] + hlut[xoff + xx]; + if (i < 0) + i = 0; + else if (i >= len) + i = len - 1; + READ_RGBA(&(map[i]), r, g, b, a); + BLEND_DST_ALPHA(r, g, b, a, p); + p++; + } + p += jump; + } + } + else + { + for (yy = 0; yy < h; yy++) + { + for (xx = 0; xx < w; xx++) + { + i = vlut[yoff + yy] + hlut[xoff + xx]; + if (i < 0) + i = 0; + else if (i >= len) + i = len - 1; + READ_RGBA(&(map[i]), r, g, b, a); + BLEND(r, g, b, a, p); + p++; + } + p += jump; } - p += jump; } break; - case OP_ADD: + case OP_ADD: for (yy = 0; yy < h; yy++) { for (xx = 0; xx < w; xx++) { i = vlut[yoff + yy] + hlut[xoff + xx]; if (i < 0) - i = 0; + i = 0; else if (i >= len) - i = len - 1; + i = len - 1; READ_RGBA(&(map[i]), r, g, b, a); BLEND_SUB(r, g, b, a, p); p++; @@ -245,16 +281,16 @@ __imlib_DrawGradient(ImlibImage *im, int x, int y, int w, int h, p += jump; } break; - case OP_SUBTRACT: + case OP_SUBTRACT: for (yy = 0; yy < h; yy++) { for (xx = 0; xx < w; xx++) { i = vlut[yoff + yy] + hlut[xoff + xx]; if (i < 0) - i = 0; + i = 0; else if (i >= len) - i = len - 1; + i = len - 1; READ_RGBA(&(map[i]), r, g, b, a); BLEND_SUB(r, g, b, a, p); p++; @@ -262,16 +298,16 @@ __imlib_DrawGradient(ImlibImage *im, int x, int y, int w, int h, p += jump; } break; - case OP_RESHADE: + case OP_RESHADE: for (yy = 0; yy < h; yy++) { for (xx = 0; xx < w; xx++) { i = vlut[yoff + yy] + hlut[xoff + xx]; if (i < 0) - i = 0; + i = 0; else if (i >= len) - i = len - 1; + i = len - 1; READ_RGBA(&(map[i]), r, g, b, a); BLEND_RE(r, g, b, a, p); p++; @@ -279,7 +315,7 @@ __imlib_DrawGradient(ImlibImage *im, int x, int y, int w, int h, p += jump; } break; - default: + default: break; } diff --git a/src/grad.h b/src/grad.h index 0ea73dc..2df030e 100644 --- a/src/grad.h +++ b/src/grad.h @@ -21,6 +21,6 @@ void __imlib_FreeRange(ImlibRange *rg); void __imlib_AddRangeColor(ImlibRange *rg, DATA8 r, DATA8 g, DATA8 b, DATA8 a, int dist); DATA32 *__imlib_MapRange(ImlibRange *rg, int len); -void __imlib_DrawGradient(ImlibImage *im, int x, int y, int w, int h, ImlibRange *rg, double angle, ImlibOp op); +void __imlib_DrawGradient(ImlibImage *im, int x, int y, int w, int h, ImlibRange *rg, double angle, ImlibOp op, int clx, int cly, int clw, int clh); #endif diff --git a/src/rend.c b/src/rend.c index b8bde6a..e31e092 100644 --- a/src/rend.c +++ b/src/rend.c @@ -17,6 +17,121 @@ /* size of the lines per segment we scale / render at a time */ #define LINESIZE 16 +DATA32 +__imlib_RenderGetPixel(Display *d, Drawable w, Visual *v, Colormap cm, int depth, DATA8 r, DATA8 g, DATA8 b) +{ + Context *ct; + int actual_depth; + + ct = __imlib_GetContext(d, v, cm, depth); + actual_depth = depth; + if (depth == 16) actual_depth = __imlib_XActualDepth(d, v); + + if (ct->palette) + { + switch (ct->palette_type) + { + case 0: /* 332 */ + return ct->palette[((r >> 0) & 0xe0) | + ((g >> 3) & 0x1b) | + ((b >> 6) & 0x02)]; + break; + case 1: /* 232 */ + return ct->palette[((r >> 0) & 0xe0) | + ((g >> 3) & 0x1b) | + ((b >> 6) & 0x02)]; + break; + case 2: /* 222 */ + return ct->palette[((r >> 0) & 0xe0) | + ((g >> 3) & 0x1b) | + ((b >> 6) & 0x02)]; + break; + case 3: /* 221 */ + return ct->palette[((r >> 0) & 0xe0) | + ((g >> 3) & 0x1b) | + ((b >> 6) & 0x02)]; + break; + case 4: /* 121 */ + return ct->palette[((r >> 0) & 0xe0) | + ((g >> 3) & 0x1b) | + ((b >> 6) & 0x02)]; + break; + case 5: /* 111 */ + return ct->palette[((r >> 0) & 0xe0) | + ((g >> 3) & 0x1b) | + ((b >> 6) & 0x02)]; + break; + case 6: /* 1 */ + return ct->palette[((r >> 0) & 0xe0) | + ((g >> 3) & 0x1b) | + ((b >> 6) & 0x02)]; + break; + default: + return 0; + } + } + else + { + unsigned int rm, gm, bm; + int i, rshift, gshift, bshift; + DATA32 val; + + rm = v->red_mask; + gm = v->green_mask; + bm = v->blue_mask; + if ((rm == 0xf800) && (gm == 0x7e0) && (bm == 0x1f)) /* 565 */ + { + return (((r << 8) & 0xf800) | + ((g << 3) & 0x07e0) | + ((b >> 3) & 0x001f)); + } + if ((rm == 0xff0000) && (gm == 0xff00) && (bm == 0xff)) /* 888 */ + { + return (((r << 16) & 0xff0000) | + ((g << 8 ) & 0x00ff00) | + ((r ) & 0x0000ff)); + } + if ((rm == 0x7c00) && (gm == 0x3e0) && (bm == 0x1f)) /* 555 */ + { + return (((r << 7) & 0x7c00) | + ((g << 2) & 0x03e0) | + ((b >> 3) & 0x001f)); + } + for (i = 31; i >= 0; i--) + { + if (rm >= (1 << i)) + { + rshift = i - 7; + break; + } + } + for (i = 31; i >= 0; i--) + { + if (gm >= (1 << i)) + { + gshift = i - 7; + break; + } + } + for (i = 31; i >= 0; i--) + { + if (bm >= (1 << i)) + { + bshift = i - 7; + break; + } + } + if (rshift >= 0) val = ((r << rshift) & rm); + else val = ((r >> (-rshift)) & rm); + if (gshift >= 0) val |= ((g << gshift) & gm); + else val |= ((g >> (-gshift)) & gm); + if (bshift >= 0) val |= ((b << bshift) & bm); + else val |= ((b >> (-bshift)) & bm); + return val; + } + return 0; +} + void __imlib_generic_render(DATA32 *src, int jump, int w, int h, int dx, int dy, XImage *xim, Visual *v, Context *ct); @@ -438,7 +553,7 @@ __imlib_RenderImageSkewed(Display *d, ImlibImage *im, Drawable w, Drawable m, __imlib_BlendImageToImageSkewed(im, back, antialias, 1, 0, sx, sy, sw, sh, dx - dx1, dy - dy1, hsx, hsy, vsx, vsy, - cmod, op); + cmod, op, 0, 0, 0, 0); __imlib_RenderImage(d, back, w, m, v, cm, depth, 0, 0, dw, dh, dx1, dy1, dw, dh, 0, hiq, 0, dither_mask, 0, OP_COPY); diff --git a/src/rend.h b/src/rend.h index 96586d6..734400f 100644 --- a/src/rend.h +++ b/src/rend.h @@ -1,5 +1,9 @@ #ifndef __REND #define __REND 1 + +DATA32 +__imlib_RenderGetPixel(Display *d, Drawable w, Visual *v, Colormap cm, int depth, DATA8 r, DATA8 g, DATA8 b); + void __imlib_RenderImage(Display *d, ImlibImage *im, Drawable w, Drawable m, diff --git a/src/rotate.c b/src/rotate.c index 947685a..e8b2b20 100644 --- a/src/rotate.c +++ b/src/rotate.c @@ -279,7 +279,8 @@ __imlib_BlendImageToImageSkewed(ImlibImage *im_src, ImlibImage *im_dst, int ssx, int ssy, int ssw, int ssh, int ddx, int ddy, int hsx, int hsy, int vsx, int vsy, - ImlibColorModifier *cm, ImlibOp op) + ImlibColorModifier *cm, ImlibOp op, + int clx, int cly, int clw, int clh) { int x, y, dxh, dyh, dxv, dyv, i; double xy2; diff --git a/src/rotate.h b/src/rotate.h index f4d1384..9e69342 100644 --- a/src/rotate.h +++ b/src/rotate.h @@ -21,7 +21,9 @@ void __imlib_BlendImageToImageSkewed(ImlibImage *im_src, ImlibImage *im_dst, int ssx, int ssy, int ssw, int ssh, int ddx, int ddy, int hsx, int hsy, int vsx, int vsy, - ImlibColorModifier *cm, ImlibOp op); + ImlibColorModifier *cm, ImlibOp op, + int clx, int cly, int clw, int clh); + #ifdef DO_MMX_ASM void __imlib_mmx_RotateAA(DATA32 *src, DATA32 *dest, int sow, int sw, int sh,