diff options
author | scuri <scuri> | 2009-10-27 19:45:36 +0000 |
---|---|---|
committer | scuri <scuri> | 2009-10-27 19:45:36 +0000 |
commit | c4ca69d3fa84dca98dce71c7a71b61413d6be165 (patch) | |
tree | 8c149cd3deaf31fa406270b26a45982471c8b88e | |
parent | 8a059c0ddda38d88aee6c8657b41ef81adb0171c (diff) |
Fixed: compositing in IMAGERGB when canvas has a semi-transparent alpha channel and a color with semi transparent alpha are used.
-rw-r--r-- | html/en/func/attributes.html | 4 | ||||
-rw-r--r-- | html/en/func/color.html | 9 | ||||
-rw-r--r-- | html/en/history.html | 5 | ||||
-rw-r--r-- | src/drv/cdirgb.c | 35 |
4 files changed, 31 insertions, 22 deletions
diff --git a/html/en/func/attributes.html b/html/en/func/attributes.html index 60768e4..984af01 100644 --- a/html/en/func/attributes.html +++ b/html/en/func/attributes.html @@ -17,7 +17,7 @@ canvas:SetForeground(color: lightuserdata) [in Lua]</pre> color is used in all primitives (lines, areas, marks and text). Default value: <b> <tt>CD_BLACK</tt></b>. Value <tt><b>CD_QUERY</b> </tt>simply returns the current value.</p> - <p>Notice that CD_QUERY conflicts with color RGBA=(255,255,255,255) (full + <p>Notice that CD_QUERY conflicts with color RGBA=(255,255,255,0) (full transparent white). Use <strong>SetForeground</strong> to avoid the conflict. See also <a href="color.html">Color Coding</a>.</p> <pre class="function"><span class="mainFunction">long int <a name="cdBackground">cdCanvasBackground</a>(cdCanvas* canvas, long int color); [in C]</span> @@ -31,7 +31,7 @@ canvas:SetBackground(color: lightuserdata) [in Lua]</pre> background color only makes sense for <strong>Clear</strong><tt><font> </font></tt>and for primitives affected by the background opacity attribute. Default value: <b><tt>CD_WHITE</tt></b>. Value <tt><b>CD_QUERY</b> </tt>simply returns the current value.</p> - <p>Notice that CD_QUERY conflicts with color RGBA=(255,255,255,255) (full + <p>Notice that CD_QUERY conflicts with color RGBA=(255,255,255,0) (full transparent white). Use <strong>SetBackground</strong> to avoid the conflict. See also <a href="color.html">Color Coding</a>.</p> <pre class="function"><span class="mainFunction">int <a name="cdWriteMode">cdCanvasWriteMode</a>(cdCanvas* canvas, int mode); [in C]</span> diff --git a/html/en/func/color.html b/html/en/func/color.html index 9ec9928..8efd8a4 100644 --- a/html/en/func/color.html +++ b/html/en/func/color.html @@ -52,12 +52,13 @@ cd.DecodeColor(color: lightuserdata) -> (r, g, b: number) [in Lua]</pre> cd.EncodeAlpha(color: lightuserdata, alpha: number) -> (color: lightuserdata) [in Lua]</pre> <p>Returns the given color coded with the alpha information. ATENTION: At the - moment only the Win32 with GDI+ and the IMAGERGB drivers support alpha - components in color coding. Se in <a href="../drv/gdiplus.html">Windows Using - GDI+ Base Driver</a> and <a href="../drv/irgb.html">IMAGERGB driver</a>. The + moment only the <a href="../drv/gdiplus.html">Win32 with GDI+</a>, the + <a href="../drv/xrender.html">XRender</a> and the <a href="../drv/irgb.html">IMAGERGB</a> + drivers support alpha components in color coding. The internal representation of the component is inverted, because the default value must be 0 and opaque for backward compatibility, so you should use the <strong>cdDecodeAlpha</strong> - function ot the <strong>cdAlpha</strong> macro to retrieve the alpha component.</p> + function or the <strong>cdAlpha</strong> macro to retrieve the alpha component. + 0 is transparent, 255 is opaque.</p> <pre class="function"><span class="mainFunction">unsigned char <a name="cdDecodeAlpha">cdDecodeAlpha</a>(long int color) [in C]</span> cd.DecodeAlpha(color: lightuserdata) -> (a: number) [in Lua]</pre> diff --git a/html/en/history.html b/html/en/history.html index 8dd485a..81db388 100644 --- a/html/en/history.html +++ b/html/en/history.html @@ -19,7 +19,7 @@ <body> <h2>History of Changes</h2> -<h3>CVS (23/Oct/2009)</h3> +<h3>CVS (27/Oct/2009)</h3> <ul> <li><span class="style1">Changed</span><span class="hist_changed">:</span> Freetype updated to version 2.3.11.</li> @@ -37,6 +37,9 @@ objects in Lua.</li> <li><span style="color: #FF0000">Fixed:</span> <strong>CanvasText</strong> for WD when using text with multiple lines.</li> + <li><span style="color: #FF0000">Fixed:</span> compositing in IMAGERGB when + canvas has a semi-transparent alpha channel and a color with semi transparent alpha + are used.</li> </ul> <h3><a href="http://sourceforge.net/projects/canvasdraw/files/5.2/">Version 5.2</a> (26/Jun/2009)</h3> <ul> diff --git a/src/drv/cdirgb.c b/src/drv/cdirgb.c index 7f6f64b..d623abc 100644 --- a/src/drv/cdirgb.c +++ b/src/drv/cdirgb.c @@ -56,13 +56,13 @@ struct _cdCtxCanvas #define _sNormX(_ctxcanvas, _x) (_x < 0? 0: _x < _ctxcanvas->canvas->w? _x: _ctxcanvas->canvas->w-1) #define _sNormY(_ctxcanvas, _y) (_y < 0? 0: _y < _ctxcanvas->canvas->h? _y: _ctxcanvas->canvas->h-1) -#define RGB_COMPOSE(_SRC, _SRC_ALPHA, _DST, _TMP_MULTI, _TMP_ALPHA) (unsigned char)(((_SRC_ALPHA)*(_SRC) + (_TMP_MULTI)*(_DST)) / (_TMP_ALPHA)) +#define RGB_COMPOSE_OVER(_SRC, _SRC_ALPHA, _DST, _TMP_MULTI, _TMP_ALPHA) (unsigned char)(((_SRC_ALPHA)*(_SRC) + (_TMP_MULTI)*(_DST)) / (_TMP_ALPHA)) #define RGBA_COLOR_COMBINE(_ctxcanvas, _pdst_red, _pdst_green, _pdst_blue, _pdst_alpha, _src_red, _src_green, _src_blue, _src_alpha) \ { \ unsigned char _tmp_red = 0, _tmp_green = 0, _tmp_blue = 0; \ \ - if (_pdst_alpha) /* (_pdst_alpha != NULL) */ \ + if (_pdst_alpha) /* destiny has alpha */ \ { \ if (_src_alpha != 255) /* some transparency */ \ { \ @@ -84,12 +84,17 @@ struct _cdCtxCanvas } \ else /* (0<*_pdst_alpha<255 && 0<_src_alpha<255) destiny and source are semi-transparent */ \ { \ - /* Closed Compositing Formulas for SRC over DST, Colors Not Premultiplied by Alpha: */ \ + /* Closed Compositing SRC over DST (see smith95a.pdf) */ \ + /* Colors NOT Premultiplied by Alpha */ \ + /* DST = SRC * SRC_ALPHA + DST * DST_ALPHA * (1 - SRC_ALPHA) */ \ + /* DST_ALPHA = SRC_ALPHA + DST_ALPHA * (1 - SRC_ALPHA) */ \ + /* DST /= DST_ALPHA */ \ int _tmp_multi = *_pdst_alpha * (255 - _src_alpha); \ - int _tmp_alpha = _src_alpha + _tmp_multi; \ - _tmp_red = RGB_COMPOSE(_src_red, _src_alpha, *_pdst_red, _tmp_multi, _tmp_alpha); \ - _tmp_green = RGB_COMPOSE(_src_green, _src_alpha, *_pdst_green, _tmp_multi, _tmp_alpha); \ - _tmp_blue = RGB_COMPOSE(_src_blue, _src_alpha, *_pdst_blue, _tmp_multi, _tmp_alpha); \ + int _tmp_src_alpha = _src_alpha*255; \ + int _tmp_alpha = _tmp_src_alpha + _tmp_multi; \ + _tmp_red = RGB_COMPOSE_OVER(_src_red, _tmp_src_alpha, *_pdst_red, _tmp_multi, _tmp_alpha); \ + _tmp_green = RGB_COMPOSE_OVER(_src_green, _tmp_src_alpha, *_pdst_green, _tmp_multi, _tmp_alpha); \ + _tmp_blue = RGB_COMPOSE_OVER(_src_blue, _tmp_src_alpha, *_pdst_blue, _tmp_multi, _tmp_alpha); \ *_pdst_alpha = (unsigned char)(_tmp_alpha / 255); \ } \ } \ @@ -109,7 +114,7 @@ struct _cdCtxCanvas *_pdst_alpha = (unsigned char)255; /* set destiny as opaque */ \ } \ } \ - else /* (_pdst_alpha == NULL) */ \ + else /* destiny does NOT have alpha */ \ { \ if (_src_alpha != 255) /* source has some transparency */ \ { \ @@ -147,9 +152,9 @@ struct _cdCtxCanvas *_pdst_blue ^= _tmp_blue; \ break; \ case CD_NOT_XOR: \ - *_pdst_red = (unsigned char)~(_tmp_red ^ *_pdst_red); \ - *_pdst_green = (unsigned char)~(_tmp_green ^ *_pdst_green); \ - *_pdst_blue = (unsigned char)~(_tmp_blue ^ *_pdst_blue); \ + *_pdst_red = (unsigned char)~(_tmp_red ^ *_pdst_red); \ + *_pdst_green = (unsigned char)~(_tmp_green ^ *_pdst_green); \ + *_pdst_blue = (unsigned char)~(_tmp_blue ^ *_pdst_blue); \ break; \ } \ } @@ -406,7 +411,7 @@ static void cdclear(cdCtxCanvas* ctxcanvas) memset(ctxcanvas->red, cdRed(ctxcanvas->canvas->background), size); memset(ctxcanvas->green, cdGreen(ctxcanvas->canvas->background), size); memset(ctxcanvas->blue, cdBlue(ctxcanvas->canvas->background), size); - if (ctxcanvas->alpha) memset(ctxcanvas->alpha, cdAlpha(ctxcanvas->canvas->background), size); + if (ctxcanvas->alpha) memset(ctxcanvas->alpha, cdAlpha(ctxcanvas->canvas->background), size); /* here is the normal alpha coding */ } static void irgPostProcessIntersect(unsigned char* clip, int size) @@ -1525,8 +1530,8 @@ static cdCtxImage* cdcreateimage(cdCtxCanvas* ctxcanvas, int w, int h) if (ctxcanvas->alpha) ctximage->alpha = ctximage->red + 3*size; - memset(ctximage->red, 0xFF, 3*size); - if (ctximage->alpha) memset(ctximage->alpha, 0, size); /* transparent */ + memset(ctximage->red, 0xFF, 3*size); /* white */ + if (ctximage->alpha) memset(ctximage->alpha, 0, size); /* transparent, this is the normal alpha coding */ return ctximage; } @@ -1927,7 +1932,7 @@ static void cdcreatecanvas(cdCanvas* canvas, void *data) ctxcanvas->alpha = ctxcanvas->red + 3*size; memset(ctxcanvas->red, 0xFF, 3*size); /* white */ - if (ctxcanvas->alpha) memset(ctxcanvas->alpha, 0, size); /* transparent */ + if (ctxcanvas->alpha) memset(ctxcanvas->alpha, 0, size); /* transparent, this is the normal alpha coding */ } ctxcanvas->clip = (unsigned char*)malloc(w*h); |