[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[E-devel] Imlib2 alpha threshold in mask generation



Hello,

When using imlib2 to render mask bitmaps, the pixel alpha value is used
to determine whether or not to set the corresponding mask bit.
As things are now the mask bit is set if the alpha value is >= 128,
i.e. 50% opacity. This is bad when rendering pixmaps/masks for ARGB windows.

Attached patch adds imlib_context_get/set_mask_alpha_threshold(), which
allows getting/setting the alpha threshold above which a mask bit is set.
Default behavior is unchanged (default alpha threshold is 128).

If there are no objections I will commit this.

/Kim
diff -ur -X ../imlib2-clean/excl.lst ../imlib2-clean/src/lib/api.c ./src/lib/api.c
--- ../imlib2-clean/src/lib/api.c	2006-07-12 21:16:56.000000000 +0200
+++ ./src/lib/api.c	2006-09-03 12:07:39.000000000 +0200
@@ -103,6 +103,7 @@
    Imlib_Progress_Function progress_func;
    char                progress_granularity;
    char                dither_mask;
+   int                 mask_alpha_threshold;
    Imlib_Filter        filter;
    Imlib_Rectangle     cliprect;
    Imlib_TTF_Encoding  encoding;
@@ -194,6 +195,7 @@
    context->progress_func = NULL;
    context->progress_granularity = 0;
    context->dither_mask = 0;
+   context->mask_alpha_threshold = 128;
    context->filter = NULL;
    context->cliprect.x = 0;
    context->cliprect.y = 0;
@@ -479,6 +481,34 @@
 }
 
 /**
+ * @param mask_alpha_threshold The mask alpha threshold.
+ * 
+ * Selects, if you are rendering to a mask, the alpha threshold above which
+ * mask bits are set. The default mask alpha threshold is 128, meaning that
+ * a mask bit will be set if the pixel alpha is >= 128.
+ */
+void
+imlib_context_set_mask_alpha_threshold(int mask_alpha_threshold)
+{
+   if (!ctx)
+      ctx = imlib_context_new();
+   ctx->mask_alpha_threshold = mask_alpha_threshold;
+}
+
+/** 
+ * @return The current mask mask alpha threshold.
+ *
+ * Returns the current mask alpha threshold.
+ */
+int
+imlib_context_get_mask_alpha_threshold(void)
+{
+   if (!ctx)
+      ctx = imlib_context_new();
+   return ctx->mask_alpha_threshold;
+}
+
+/**
  * @param anti_alias The anti alias flag.
  * 
  * Toggles "anti-aliased" scaling of images. This
@@ -1759,7 +1789,7 @@
                                  ctx->depth, ctx->colormap, im, pixmap_return,
                                  mask_return, 0, 0, im->w, im->h, im->w,
                                  im->h, 0, ctx->dither, ctx->dither_mask,
-                                 ctx->color_modifier);
+                                 ctx->mask_alpha_threshold, ctx->color_modifier);
 }
 
 /**
@@ -1799,7 +1829,8 @@
                                  ctx->depth, ctx->colormap, im, pixmap_return,
                                  mask_return, 0, 0, im->w, im->h, width,
                                  height, ctx->anti_alias, ctx->dither,
-                                 ctx->dither_mask, ctx->color_modifier);
+                                 ctx->dither_mask, ctx->mask_alpha_threshold,
+                                 ctx->color_modifier);
 }
 
 /**
@@ -1840,7 +1871,8 @@
    __imlib_RenderImage(ctx->display, im, ctx->drawable, ctx->mask,
                        ctx->visual, ctx->colormap, ctx->depth, 0, 0, im->w,
                        im->h, x, y, im->w, im->h, 0, ctx->dither, ctx->blend,
-                       ctx->dither_mask, ctx->color_modifier, ctx->operation);
+                       ctx->dither_mask, ctx->mask_alpha_threshold,
+                       ctx->color_modifier, ctx->operation);
 }
 
 /**
@@ -1871,7 +1903,8 @@
                        ctx->visual, ctx->colormap, ctx->depth, 0, 0, im->w,
                        im->h, x, y, width, height, ctx->anti_alias,
                        ctx->dither, ctx->blend, ctx->dither_mask,
-                       ctx->color_modifier, ctx->operation);
+                       ctx->mask_alpha_threshold, ctx->color_modifier,
+                       ctx->operation);
 }
 
 /**
@@ -1910,7 +1943,7 @@
                        ctx->colormap, ctx->depth, source_x, source_y,
                        source_width, source_height, x, y, width, height,
                        ctx->anti_alias, ctx->dither, ctx->blend, 0,
-                       ctx->color_modifier, ctx->operation);
+                       0, ctx->color_modifier, ctx->operation);
 }
 
 DATA32
@@ -2757,7 +2790,7 @@
         __imlib_RenderImage(ctx->display, im, ctx->drawable, 0, ctx->visual,
                             ctx->colormap, ctx->depth, u->x, u->y, u->w, u->h,
                             x + u->x, y + u->y, u->w, u->h, 0, ctx->dither, 0,
-                            0, ctx->color_modifier, OP_COPY);
+                            0, 0, ctx->color_modifier, OP_COPY);
      }
    __imlib_SetMaxXImageCount(ctx->display, 0);
 }
@@ -5001,7 +5034,8 @@
                              destination_x, destination_y, h_angle_x,
                              h_angle_y, v_angle_x, v_angle_y, ctx->anti_alias,
                              ctx->dither, ctx->blend, ctx->dither_mask,
-                             ctx->color_modifier, ctx->operation);
+                             ctx->mask_alpha_threshold, ctx->color_modifier,
+                             ctx->operation);
 }
 
 /**
@@ -5041,7 +5075,8 @@
                              source_y, source_width, source_height,
                              destination_x, destination_y, angle_x, angle_y,
                              0, 0, ctx->anti_alias, ctx->dither, ctx->blend,
-                             ctx->dither_mask, ctx->color_modifier,
+                             ctx->dither_mask, ctx->mask_alpha_threshold,
+                             ctx->color_modifier,
                              ctx->operation);
 }
 #endif
diff -ur -X ../imlib2-clean/excl.lst ../imlib2-clean/src/lib/draw.c ./src/lib/draw.c
--- ../imlib2-clean/src/lib/draw.c	2004-11-01 10:45:30.000000000 +0100
+++ ./src/lib/draw.c	2006-08-13 17:55:24.000000000 +0200
@@ -16,7 +16,7 @@
                               Colormap cm, ImlibImage * im, Pixmap * p,
                               Mask * m, int sx, int sy, int sw, int sh, int dw,
                               int dh, char antialias, char hiq,
-                              char dither_mask, ImlibColorModifier * cmod)
+                              char dither_mask, int mat, ImlibColorModifier * cmod)
 {
    ImlibImagePixmap   *ip = NULL;
    Pixmap              pmap = 0;
@@ -54,7 +54,7 @@
         *m = mask;
      }
    __imlib_RenderImage(d, im, pmap, mask, v, cm, depth, sx, sy, sw, sh, 0, 0,
-                       dw, dh, antialias, hiq, 0, dither_mask, cmod, OP_COPY);
+                       dw, dh, antialias, hiq, 0, dither_mask, mat, cmod, OP_COPY);
    ip = __imlib_ProduceImagePixmap();
    ip->visual = v;
    ip->depth = depth;
diff -ur -X ../imlib2-clean/excl.lst ../imlib2-clean/src/lib/draw.h ./src/lib/draw.h
--- ../imlib2-clean/src/lib/draw.h	2006-04-09 10:14:49.000000000 +0200
+++ ./src/lib/draw.h	2006-08-13 17:54:34.000000000 +0200
@@ -9,7 +9,7 @@
 			      int sx, int sy, int sw, int sh,
 			      int dw, int dh,
 			      char anitalias, char hiq, char dither_mask,
-			      ImlibColorModifier *cmod);
+			      int mat, ImlibColorModifier *cmod);
 
 #endif
 
diff -ur -X ../imlib2-clean/excl.lst ../imlib2-clean/src/lib/Imlib2.h ./src/lib/Imlib2.h
--- ../imlib2-clean/src/lib/Imlib2.h	2006-04-08 16:17:48.000000000 +0200
+++ ./src/lib/Imlib2.h	2006-08-13 20:15:04.000000000 +0200
@@ -116,6 +116,7 @@
    void imlib_context_set_mask(Pixmap mask);
 # endif
    void imlib_context_set_dither_mask(char dither_mask);
+   void imlib_context_set_mask_alpha_threshold(int mask_alpha_threshold);
    void imlib_context_set_anti_alias(char anti_alias);
    void imlib_context_set_dither(char dither);
    void imlib_context_set_blend(char blend);
@@ -146,6 +147,7 @@
 # endif
    char imlib_context_get_dither_mask(void);
    char imlib_context_get_anti_alias(void);
+   int imlib_context_get_mask_alpha_threshold(void);
    char imlib_context_get_dither(void);
    char imlib_context_get_blend(void);
    Imlib_Color_Modifier imlib_context_get_color_modifier(void);
diff -ur -X ../imlib2-clean/excl.lst ../imlib2-clean/src/lib/rend.c ./src/lib/rend.c
--- ../imlib2-clean/src/lib/rend.c	2006-05-20 15:42:24.000000000 +0200
+++ ./src/lib/rend.c	2006-08-13 18:04:10.000000000 +0200
@@ -242,7 +242,7 @@
                     int sx, int sy, int sw, int sh,
                     int dx, int dy, int dw, int dh,
                     char antialias, char hiq, char blend, char dither_mask,
-                    ImlibColorModifier * cmod, ImlibOp op)
+                    int mat, ImlibColorModifier * cmod, ImlibOp op)
 {
    XImage             *xim = NULL, *mxim = NULL;
    Context            *ct;
@@ -256,7 +256,8 @@
    ImlibScaleInfo     *scaleinfo = NULL;
    int                 psx, psy, psw, psh;
    char                shm = 0;
-   ImlibRGBAFunction   rgbaer, masker = NULL;
+   ImlibRGBAFunction   rgbaer;
+   ImlibMaskFunction   masker = NULL;
    ImlibBlendFunction  blender = NULL;
    int                 do_mmx;
 
@@ -450,7 +451,7 @@
         if (m)
            masker(pointer, jump,
                   ((DATA8 *) mxim->data) + (y * (mxim->bytes_per_line)),
-                  mxim->bytes_per_line, dw, hh, dx, dy + y);
+                  mxim->bytes_per_line, dw, hh, dx, dy + y, mat);
         h -= LINESIZE;
      }
    /* free up our buffers and poit tables */
@@ -517,7 +518,7 @@
                           int sx, int sy, int sw, int sh, int dx, int dy,
                           int hsx, int hsy, int vsx, int vsy,
                           char antialias, char hiq, char blend,
-                          char dither_mask, ImlibColorModifier * cmod,
+                          char dither_mask, int mat, ImlibColorModifier * cmod,
                           ImlibOp op)
 {
    Context            *ct;
@@ -584,7 +585,7 @@
                                    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);
+                       dx1, dy1, dw, dh, 0, hiq, 0, dither_mask, mat, 0, OP_COPY);
    __imlib_FreeImage(back);
 }
 
diff -ur -X ../imlib2-clean/excl.lst ../imlib2-clean/src/lib/rend.h ./src/lib/rend.h
--- ../imlib2-clean/src/lib/rend.h	2006-04-09 10:14:49.000000000 +0200
+++ ./src/lib/rend.h	2006-08-13 17:48:21.000000000 +0200
@@ -13,7 +13,7 @@
 		    int sx, int sy, int sw, int sh,
 		    int dx, int dy, int dw, int dh,
 		    char anitalias, char hiq, char blend, char dither_mask,
-		    ImlibColorModifier *cmod, ImlibOp op);
+		    int mat, ImlibColorModifier *cmod, ImlibOp op);
 
 __hidden void
 __imlib_RenderImageSkewed(Display *d, ImlibImage *im, Drawable w,
@@ -21,7 +21,7 @@
 			  int sx, int sy, int sw, int sh, int dx, int dy,
 			  int hsx, int hsy, int vsx, int vsy,
 			  char antialias, char hiq, char blend,
-			  char dither_mask, ImlibColorModifier *cmod,
+			  char dither_mask, int mat, ImlibColorModifier *cmod,
 			  ImlibOp op);
 
 #endif
diff -ur -X ../imlib2-clean/excl.lst ../imlib2-clean/src/lib/rgba.c ./src/lib/rgba.c
--- ../imlib2-clean/src/lib/rgba.c	2006-08-13 16:41:31.000000000 +0200
+++ ./src/lib/rgba.c	2006-09-03 12:12:12.000000000 +0200
@@ -2327,6 +2327,7 @@
 
 /*****************************************************************************/
 /* MACROS for plain RGBA -> A1 conversion */
+#if 0 /* Old fixed-threshold macros - Remove? */
 
 #ifdef WORDS_BIGENDIAN
 # define WRITE1_RGBA_A1(src, dest)                   \
@@ -2340,19 +2341,38 @@
 src++
 #endif
 
+#else
+
+#ifdef WORDS_BIGENDIAN
+# define WRITE1_RGBA_A1(src, dest, threshold) \
+if ((*src >> 24) >= threshold)      \
+  *dest |= (1 << (7 - (x & 0x7)));  \
+if ((x & 0x7) == 0x7) dest++;       \
+src++
+#else
+# define WRITE1_RGBA_A1(src, dest, threshold) \
+if ((*src >> 24) >= threshold)      \
+  *dest |= (1 << (x & 0x7));        \
+if ((x & 0x7) == 0x7) dest++;       \
+src++
+#endif
+
+#endif
+
 /*****************************************************************************/
 /* MACROS for dithered RGBA -> A1 conversion */
+/* FIXME: Mask alpha threshold is not handled (thus the default 128 is used) */
 # define DITHER_RGBA_A1_LUT(num) \
 (_dither_a1[(((x + num) & 0x7) << DM_BS1) | ((y & 0x7) << DM_BS2) | ((src[num] >> 24))])
 #ifdef WORDS_BIGENDIAN
-#define WRITE1_RGBA_A1_DITHER(src, dest)              \
+#define WRITE1_RGBA_A1_DITHER(src, dest, threshold) \
 *dest |= (DITHER_RGBA_A1_LUT(0)) << (7 - (x & 0x7)); \
-if ((x & 0x7) == 0x7) dest++;                         \
+if ((x & 0x7) == 0x7) dest++;                        \
 src++;
 #else
-#define WRITE1_RGBA_A1_DITHER(src, dest)              \
+#define WRITE1_RGBA_A1_DITHER(src, dest, threshold) \
 *dest |= (DITHER_RGBA_A1_LUT(0)) << (0 + (x & 0x7)); \
-if ((x & 0x7) == 0x7) dest++;                         \
+if ((x & 0x7) == 0x7) dest++;                        \
 src++;
 #endif
 
@@ -4696,7 +4716,7 @@
 static void
 __imlib_RGBA_to_A1_fast(DATA32 * src, int src_jump,
                         DATA8 * dest, int dow,
-                        int width, int height, int dx, int dy)
+                        int width, int height, int dx, int dy, int threshold)
 {
    int                 x, y, w, h;
    int                 dest_jump = dow - (width >> 3);
@@ -4708,7 +4728,7 @@
      {
         for (x = 0; x < w; x++)
           {
-             WRITE1_RGBA_A1(src, dest);
+             WRITE1_RGBA_A1(src, dest, threshold);
           }
         src += src_jump;
         dest += dest_jump;
@@ -4721,7 +4741,7 @@
 static void
 __imlib_RGBA_to_A1_dither(DATA32 * src, int src_jump,
                           DATA8 * dest, int dow,
-                          int width, int height, int dx, int dy)
+                          int width, int height, int dx, int dy, int threshold)
 {
    int                 x, y, w, h;
    int                 dest_jump = dow - (width >> 3);
@@ -4733,7 +4753,7 @@
      {
         for (x = dx; x < w; x++)
           {
-             WRITE1_RGBA_A1_DITHER(src, dest);
+             WRITE1_RGBA_A1_DITHER(src, dest, threshold);
           }
         src += src_jump;
         dest += dest_jump;
@@ -4958,7 +4978,7 @@
    return NULL;
 }
 
-ImlibRGBAFunction
+ImlibMaskFunction
 __imlib_GetMaskFunction(char hiq)
 {
    return hiq ? &__imlib_RGBA_to_A1_dither : &__imlib_RGBA_to_A1_fast;
diff -ur -X ../imlib2-clean/excl.lst ../imlib2-clean/src/lib/rgba.h ./src/lib/rgba.h
--- ../imlib2-clean/src/lib/rgba.h	2006-04-09 10:14:49.000000000 +0200
+++ ./src/lib/rgba.h	2006-08-13 18:02:10.000000000 +0200
@@ -14,11 +14,13 @@
 
 typedef void (*ImlibRGBAFunction)(DATA32*, int, DATA8*,
 				  int, int, int, int, int);
+typedef void (*ImlibMaskFunction)(DATA32*, int, DATA8*,
+				  int, int, int, int, int, int);
 __hidden ImlibRGBAFunction
 __imlib_GetRGBAFunction(int depth, 
 			unsigned long rm, unsigned long gm, unsigned long bm, 
 			char hiq, DATA8 palette_type);
-__hidden ImlibRGBAFunction
+__hidden ImlibMaskFunction
 __imlib_GetMaskFunction(char hiq);
 
 #ifdef DO_MMX_ASM