2007-11-16 18:25:45 +00:00
|
|
|
/* ASE - Allegro Sprite Editor
|
2012-01-06 00:52:11 -03:00
|
|
|
* Copyright (C) 2001-2012 David Capello
|
2007-09-18 23:57:02 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include "raster/blend.h"
|
|
|
|
#include "raster/image.h"
|
|
|
|
|
|
|
|
BLEND_COLOR _rgba_blenders[] =
|
|
|
|
{
|
|
|
|
_rgba_blend_normal,
|
|
|
|
_rgba_blend_copy,
|
|
|
|
};
|
|
|
|
|
|
|
|
BLEND_COLOR _graya_blenders[] =
|
|
|
|
{
|
|
|
|
_graya_blend_normal,
|
|
|
|
_graya_blend_copy,
|
|
|
|
};
|
|
|
|
|
|
|
|
/**********************************************************************/
|
|
|
|
/* RGB blenders */
|
|
|
|
/**********************************************************************/
|
|
|
|
|
2010-12-05 11:44:01 -03:00
|
|
|
int _rgba_blend_normal(int back, int front, int opacity)
|
|
|
|
{
|
|
|
|
register int t;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-12-05 11:44:01 -03:00
|
|
|
if ((back & 0xff000000) == 0) {
|
|
|
|
return
|
|
|
|
(front & 0xffffff) |
|
|
|
|
(INT_MULT(_rgba_geta(front), opacity, t) << _rgba_a_shift);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
2010-12-05 11:44:01 -03:00
|
|
|
else if ((front & 0xff000000) == 0) {
|
|
|
|
return back;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
int B_r, B_g, B_b, B_a;
|
|
|
|
int F_r, F_g, F_b, F_a;
|
|
|
|
int D_r, D_g, D_b, D_a;
|
|
|
|
|
|
|
|
B_r = _rgba_getr(back);
|
|
|
|
B_g = _rgba_getg(back);
|
|
|
|
B_b = _rgba_getb(back);
|
|
|
|
B_a = _rgba_geta(back);
|
|
|
|
|
|
|
|
F_r = _rgba_getr(front);
|
|
|
|
F_g = _rgba_getg(front);
|
|
|
|
F_b = _rgba_getb(front);
|
|
|
|
F_a = _rgba_geta(front);
|
|
|
|
F_a = INT_MULT(F_a, opacity, t);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-12-05 11:44:01 -03:00
|
|
|
D_a = B_a + F_a - INT_MULT(B_a, F_a, t);
|
|
|
|
D_r = B_r + (F_r-B_r) * F_a / D_a;
|
|
|
|
D_g = B_g + (F_g-B_g) * F_a / D_a;
|
|
|
|
D_b = B_b + (F_b-B_b) * F_a / D_a;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2012-01-05 19:45:03 -03:00
|
|
|
return _rgba(D_r, D_g, D_b, D_a);
|
|
|
|
}
|
2010-12-05 11:44:01 -03:00
|
|
|
}
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
int _rgba_blend_copy(int back, int front, int opacity)
|
|
|
|
{
|
|
|
|
return front;
|
|
|
|
}
|
|
|
|
|
2010-12-05 11:44:01 -03:00
|
|
|
int _rgba_blend_forpath(int back, int front, int opacity)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
|
|
|
int F_r, F_g, F_b, F_a;
|
2010-12-05 11:44:01 -03:00
|
|
|
register int t;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
F_r = _rgba_getr(front);
|
|
|
|
F_g = _rgba_getg(front);
|
|
|
|
F_b = _rgba_getb(front);
|
|
|
|
F_a = _rgba_geta(front);
|
|
|
|
F_a = INT_MULT(F_a, opacity, t);
|
|
|
|
|
|
|
|
return _rgba(F_r, F_g, F_b, F_a);
|
|
|
|
}
|
|
|
|
|
2010-12-05 11:44:01 -03:00
|
|
|
int _rgba_blend_merge(int back, int front, int opacity)
|
2008-04-14 17:56:38 +00:00
|
|
|
{
|
|
|
|
int B_r, B_g, B_b, B_a;
|
|
|
|
int F_r, F_g, F_b, F_a;
|
|
|
|
int D_r, D_g, D_b, D_a;
|
2012-01-05 19:45:03 -03:00
|
|
|
|
2008-04-14 17:56:38 +00:00
|
|
|
B_r = _rgba_getr(back);
|
|
|
|
B_g = _rgba_getg(back);
|
|
|
|
B_b = _rgba_getb(back);
|
|
|
|
B_a = _rgba_geta(back);
|
|
|
|
|
|
|
|
F_r = _rgba_getr(front);
|
|
|
|
F_g = _rgba_getg(front);
|
|
|
|
F_b = _rgba_getb(front);
|
|
|
|
F_a = _rgba_geta(front);
|
|
|
|
|
|
|
|
if (B_a == 0) {
|
|
|
|
D_r = F_r;
|
|
|
|
D_g = F_g;
|
|
|
|
D_b = F_b;
|
|
|
|
}
|
|
|
|
else if (F_a == 0) {
|
|
|
|
D_r = B_r;
|
|
|
|
D_g = B_g;
|
|
|
|
D_b = B_b;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
D_r = B_r + (F_r-B_r) * opacity / 255;
|
|
|
|
D_g = B_g + (F_g-B_g) * opacity / 255;
|
|
|
|
D_b = B_b + (F_b-B_b) * opacity / 255;
|
|
|
|
}
|
|
|
|
D_a = B_a + (F_a-B_a) * opacity / 255;
|
2012-01-05 19:45:03 -03:00
|
|
|
|
2008-04-14 17:56:38 +00:00
|
|
|
return _rgba(D_r, D_g, D_b, D_a);
|
|
|
|
}
|
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
/**********************************************************************/
|
|
|
|
/* Grayscale blenders */
|
|
|
|
/**********************************************************************/
|
|
|
|
|
2010-12-05 11:44:01 -03:00
|
|
|
int _graya_blend_normal(int back, int front, int opacity)
|
|
|
|
{
|
|
|
|
register int t;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-12-05 11:44:01 -03:00
|
|
|
if ((back & 0xff00) == 0) {
|
|
|
|
return
|
|
|
|
(front & 0xff) |
|
|
|
|
(INT_MULT(_graya_geta (front), opacity, t) << _graya_a_shift);
|
|
|
|
}
|
|
|
|
else if ((front & 0xff00) == 0) {
|
|
|
|
return back;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
int B_g, B_a;
|
|
|
|
int F_g, F_a;
|
|
|
|
int D_g, D_a;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-12-05 11:44:01 -03:00
|
|
|
B_g = _graya_getv(back);
|
|
|
|
B_a = _graya_geta(back);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-12-05 11:44:01 -03:00
|
|
|
F_g = _graya_getv(front);
|
|
|
|
F_a = _graya_geta(front);
|
|
|
|
F_a = INT_MULT(F_a, opacity, t);
|
|
|
|
|
|
|
|
D_a = B_a + F_a - INT_MULT(B_a, F_a, t);
|
|
|
|
D_g = B_g + (F_g-B_g) * F_a / D_a;
|
|
|
|
|
|
|
|
return _graya(D_g, D_a);
|
|
|
|
}
|
|
|
|
}
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
int _graya_blend_copy(int back, int front, int opacity)
|
|
|
|
{
|
|
|
|
return front;
|
|
|
|
}
|
|
|
|
|
2010-12-05 11:44:01 -03:00
|
|
|
int _graya_blend_forpath(int back, int front, int opacity)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
|
|
|
int F_k, F_a;
|
2010-12-05 11:44:01 -03:00
|
|
|
register int t;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2008-02-29 19:29:49 +00:00
|
|
|
F_k = _graya_getv(front);
|
2007-09-18 23:57:02 +00:00
|
|
|
F_a = _graya_geta(front);
|
|
|
|
F_a = INT_MULT(F_a, opacity, t);
|
|
|
|
|
|
|
|
return _graya(F_k, F_a);
|
|
|
|
}
|
|
|
|
|
2010-12-05 11:44:01 -03:00
|
|
|
int _graya_blend_merge(int back, int front, int opacity)
|
2008-04-14 17:56:38 +00:00
|
|
|
{
|
|
|
|
int B_k, B_a;
|
|
|
|
int F_k, F_a;
|
|
|
|
int D_k, D_a;
|
2012-01-05 19:45:03 -03:00
|
|
|
|
2008-04-14 17:56:38 +00:00
|
|
|
B_k = _graya_getv(back);
|
|
|
|
B_a = _graya_geta(back);
|
|
|
|
|
|
|
|
F_k = _graya_getv(front);
|
|
|
|
F_a = _graya_geta(front);
|
|
|
|
|
|
|
|
if (B_a == 0) {
|
|
|
|
D_k = F_k;
|
|
|
|
}
|
|
|
|
else if (F_a == 0) {
|
|
|
|
D_k = B_k;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
D_k = B_k + (F_k-B_k) * opacity / 255;
|
|
|
|
}
|
|
|
|
D_a = B_a + (F_a-B_a) * opacity / 255;
|
2012-01-05 19:45:03 -03:00
|
|
|
|
2008-04-14 17:56:38 +00:00
|
|
|
return _graya(D_k, D_a);
|
|
|
|
}
|