mirror of
https://github.com/gnustep/libs-back.git
synced 2025-02-23 20:01:22 +00:00
Alpha fixes
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@14152 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
fbda96e6a9
commit
28e92746b8
3 changed files with 138 additions and 136 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2002-07-14 Adam Fedor <fedor@gnu.org>
|
||||||
|
|
||||||
|
* Source/x11/XGServer.m ([XGServer -dealloc]): Don't close
|
||||||
|
the display (except when DEBUG), till we figure out why it
|
||||||
|
always crashes here.
|
||||||
|
|
||||||
|
2002-07-13 Adam Fedor <fedor@gnu.org>
|
||||||
|
|
||||||
|
* Source/xlib/XGBitmap.m (_pixmap_combine_alpha): Fix and
|
||||||
|
cleanup alpha blending (Rescale by alpha)
|
||||||
|
(_bitmap_combine_alpha): Idem. (Patch from deek@d2dc.net).
|
||||||
|
|
||||||
2002-06-28 Adam Fedor <fedor@gnu.org>
|
2002-06-28 Adam Fedor <fedor@gnu.org>
|
||||||
|
|
||||||
* Source/xlib/XGFont.m ([XGFontInfo -xCharStructForGlyph:glyph]):
|
* Source/xlib/XGFont.m ([XGFontInfo -xCharStructForGlyph:glyph]):
|
||||||
|
|
|
@ -420,7 +420,11 @@ _parse_display_name(NSString *name, int *dn, int *sn)
|
||||||
DESTROY(inputServer);
|
DESTROY(inputServer);
|
||||||
[self _destroyServerWindows];
|
[self _destroyServerWindows];
|
||||||
NSFreeMapTable(screenList);
|
NSFreeMapTable(screenList);
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* FIXME: Avoid doing this until we figure out why we always
|
||||||
|
segfault here */
|
||||||
XCloseDisplay(dpy);
|
XCloseDisplay(dpy);
|
||||||
|
#endif
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,26 +54,26 @@
|
||||||
|
|
||||||
#define InitRGBShiftsAndMasks(rs,rw,gs,gw,bs,bw,as,aw) \
|
#define InitRGBShiftsAndMasks(rs,rw,gs,gw,bs,bw,as,aw) \
|
||||||
do { \
|
do { \
|
||||||
_rshift = rs; \
|
_rshift = (rs); \
|
||||||
_rmask = (1<<rw) -1; \
|
_rmask = (1<<(rw)) -1; \
|
||||||
_rwidth = rw; \
|
_rwidth = (rw); \
|
||||||
_gshift = gs; \
|
_gshift = (gs); \
|
||||||
_gmask = (1<<gw) -1; \
|
_gmask = (1<<(gw)) -1; \
|
||||||
_gwidth = gw; \
|
_gwidth = (gw); \
|
||||||
_bshift = bs; \
|
_bshift = (bs); \
|
||||||
_bmask = (1<<bw) -1; \
|
_bmask = (1<<(bw)) -1; \
|
||||||
_bwidth = bw; \
|
_bwidth = (bw); \
|
||||||
_amask = (1<<aw) -1; \
|
_amask = (1<<(aw)) -1; \
|
||||||
_ashift = as; \
|
_ashift = (as); \
|
||||||
_awidth = aw; \
|
_awidth = (aw); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
#define PixelToRGB(pixel,r,g,b) \
|
#define PixelToRGB(pixel,r,g,b) \
|
||||||
do { \
|
do { \
|
||||||
r = (pixel >> _rshift) & _rmask; \
|
(r) = (pixel >> _rshift) & _rmask; \
|
||||||
g = (pixel >> _gshift) & _gmask; \
|
(g) = (pixel >> _gshift) & _gmask; \
|
||||||
b = (pixel >> _bshift) & _bmask; \
|
(b) = (pixel >> _bshift) & _bmask; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
/* Note that RGBToPixel assumes that the
|
/* Note that RGBToPixel assumes that the
|
||||||
|
@ -88,6 +88,10 @@
|
||||||
|((b) << _bshift); \
|
|((b) << _bshift); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
#define CLAMP(a) \
|
||||||
|
do { \
|
||||||
|
(a) = MAX(0, MIN(255, (a))); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/* Composite source image (pixmap) onto a destination image with alpha.
|
/* Composite source image (pixmap) onto a destination image with alpha.
|
||||||
Only works for op=Sover now
|
Only works for op=Sover now
|
||||||
|
@ -107,14 +111,9 @@ _pixmap_combine_alpha(RContext *context,
|
||||||
float fraction)
|
float fraction)
|
||||||
{
|
{
|
||||||
unsigned long pixel;
|
unsigned long pixel;
|
||||||
unsigned short oldAlpha = 0;
|
|
||||||
unsigned long oldPixel = 0;
|
unsigned long oldPixel = 0;
|
||||||
unsigned short oldAr = 0;
|
|
||||||
unsigned short oldAg = 0;
|
fraction = MAX(0.0, MIN(1.0, fraction));
|
||||||
unsigned short oldAb = 0;
|
|
||||||
unsigned char oldBr = 0;
|
|
||||||
unsigned char oldBg = 0;
|
|
||||||
unsigned char oldBb = 0;
|
|
||||||
|
|
||||||
if (drawMechanism == XGDM_FAST15
|
if (drawMechanism == XGDM_FAST15
|
||||||
|| drawMechanism == XGDM_FAST16
|
|| drawMechanism == XGDM_FAST16
|
||||||
|
@ -144,68 +143,70 @@ _pixmap_combine_alpha(RContext *context,
|
||||||
//which picture goes wrong.
|
//which picture goes wrong.
|
||||||
InitRGBShiftsAndMasks(11,5,5,6,0,5,0,8);
|
InitRGBShiftsAndMasks(11,5,5,6,0,5,0,8);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (row = 0; row < srect.height; row++)
|
for (row = 0; row < srect.height; row++)
|
||||||
{
|
{
|
||||||
unsigned col;
|
unsigned col;
|
||||||
|
|
||||||
for (col = 0; col < srect.width; col++)
|
for (col = 0; col < srect.width; col++)
|
||||||
{
|
{
|
||||||
unsigned r, g, b, alpha;
|
unsigned sr, sg, sb, sa; // source
|
||||||
pixel = XGetPixel(source_im->image,
|
unsigned dr, dg, db, da; // dest
|
||||||
col+srect.x, row+srect.y);
|
double alpha, ialpha;
|
||||||
|
|
||||||
PixelToRGB(pixel,r,g,b);
|
// Get the source pixel information
|
||||||
|
pixel = XGetPixel (source_im->image, srect.x+col, srect.y+row);
|
||||||
|
PixelToRGB (pixel, sr, sg, sb);
|
||||||
|
|
||||||
pixel = 255;
|
|
||||||
if (source_alpha)
|
if (source_alpha)
|
||||||
|
{
|
||||||
pixel = XGetPixel(source_alpha->image,
|
pixel = XGetPixel(source_alpha->image,
|
||||||
col+srect.x, row+srect.y);
|
srect.x+col, srect.y+row);
|
||||||
|
sa = (pixel >> _ashift) & _amask;
|
||||||
if (fraction < 1)
|
|
||||||
pixel *= fraction;
|
|
||||||
alpha = (pixel >> _ashift) & _amask;
|
|
||||||
|
|
||||||
if (alpha == 0)
|
|
||||||
continue; // background unchanged.
|
|
||||||
if (alpha != _amask)
|
|
||||||
{ // We really have something to mix!
|
|
||||||
unsigned short ialpha = _amask - alpha;
|
|
||||||
/*
|
|
||||||
* Get the background pixel and convert to RGB.
|
|
||||||
*/
|
|
||||||
pixel = XGetPixel(dest_im->image, col, row);
|
|
||||||
if (pixel != oldPixel)
|
|
||||||
{
|
|
||||||
oldPixel = pixel;
|
|
||||||
PixelToRGB(pixel, oldBr,oldBg,oldBb);
|
|
||||||
oldAlpha = 0;
|
|
||||||
}
|
|
||||||
if (alpha != oldAlpha)
|
|
||||||
{
|
|
||||||
oldAlpha = alpha;
|
|
||||||
oldAr = ialpha * oldBr;
|
|
||||||
oldAg = ialpha * oldBg;
|
|
||||||
oldAb = ialpha * oldBb;
|
|
||||||
}
|
|
||||||
|
|
||||||
// mix in alpha to produce RGB out
|
|
||||||
r = (oldAr + (r*alpha))/_amask;
|
|
||||||
g = (oldAg + (g*alpha))/_amask;
|
|
||||||
b = (oldAb + (b*alpha))/_amask;
|
|
||||||
}
|
}
|
||||||
RGBToPixel(r,g,b,pixel);
|
else
|
||||||
|
sa = _amask;
|
||||||
|
|
||||||
|
if (sa == 0) // dest wouldn't be changed
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (fraction < 1.0)
|
||||||
|
sa *= fraction;
|
||||||
|
|
||||||
|
alpha = ((double) sa) / _amask;
|
||||||
|
|
||||||
|
// Now get dest pixel
|
||||||
|
pixel = XGetPixel(dest_im->image, col, row);
|
||||||
|
PixelToRGB (pixel, dr, dg, db);
|
||||||
|
|
||||||
|
if (dest_alpha)
|
||||||
|
{
|
||||||
|
pixel = XGetPixel(dest_alpha->image, col, row);
|
||||||
|
da = (pixel >> _ashift) & _amask;
|
||||||
|
}
|
||||||
|
else // no alpha channel, background is opaque
|
||||||
|
da = _amask;
|
||||||
|
|
||||||
|
ialpha = (1.0 - alpha);
|
||||||
|
dr = (sr * alpha) + (dr * ialpha);
|
||||||
|
dg = (sg * alpha) + (dg * ialpha);
|
||||||
|
db = (sb * alpha) + (db * ialpha);
|
||||||
|
|
||||||
|
// calc final alpha
|
||||||
|
if (sa == _amask || da == _amask)
|
||||||
|
da = _amask;
|
||||||
|
else
|
||||||
|
da = sa + (da * ialpha);
|
||||||
|
|
||||||
|
CLAMP(dr);
|
||||||
|
CLAMP(dg);
|
||||||
|
CLAMP(db);
|
||||||
|
CLAMP(da);
|
||||||
|
|
||||||
|
RGBToPixel(dr, dg, db, pixel);
|
||||||
XPutPixel(dest_im->image, col, row, pixel);
|
XPutPixel(dest_im->image, col, row, pixel);
|
||||||
if (dest_alpha)
|
if (dest_alpha)
|
||||||
{
|
XPutPixel(dest_alpha->image, col, row, da << _ashift);
|
||||||
unsigned short dalpha;
|
|
||||||
unsigned long dpixel;
|
|
||||||
/* Alpha gets mixed the same as all the
|
|
||||||
other color components */
|
|
||||||
dpixel = XGetPixel(dest_alpha->image, col, row);
|
|
||||||
dalpha = (dpixel >> _ashift) & _amask;
|
|
||||||
dalpha = alpha + dalpha * (_amask - alpha)/_amask;
|
|
||||||
XPutPixel(dest_alpha->image, col, row, dalpha << _ashift );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,7 +223,6 @@ _pixmap_combine_alpha(RContext *context,
|
||||||
pixel = (unsigned long)-1; // Never valid?
|
pixel = (unsigned long)-1; // Never valid?
|
||||||
c2.pixel = pixel;
|
c2.pixel = pixel;
|
||||||
|
|
||||||
|
|
||||||
for (row = 0; row < srect.height; row++)
|
for (row = 0; row < srect.height; row++)
|
||||||
{
|
{
|
||||||
unsigned col;
|
unsigned col;
|
||||||
|
@ -858,14 +858,6 @@ _bitmap_combine_alpha(RContext *context,
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned long pixel;
|
unsigned long pixel;
|
||||||
unsigned short oldAlpha = 0;
|
|
||||||
unsigned long oldPixel = 0;
|
|
||||||
unsigned short oldAr = 0;
|
|
||||||
unsigned short oldAg = 0;
|
|
||||||
unsigned short oldAb = 0;
|
|
||||||
unsigned char oldBr = 0;
|
|
||||||
unsigned char oldBg = 0;
|
|
||||||
unsigned char oldBb = 0;
|
|
||||||
|
|
||||||
/* Two cases, the *_FAST* method, which
|
/* Two cases, the *_FAST* method, which
|
||||||
is covered in the first a part of the if
|
is covered in the first a part of the if
|
||||||
|
@ -915,74 +907,68 @@ _bitmap_combine_alpha(RContext *context,
|
||||||
|
|
||||||
for (col = 0; col < drect.width; col++)
|
for (col = 0; col < drect.width; col++)
|
||||||
{
|
{
|
||||||
unsigned short r = *rptr++;
|
unsigned short sr = (*rptr++ >> (8 - _rwidth));
|
||||||
unsigned short g = *gptr++;
|
unsigned short sg = (*gptr++ >> (8 - _gwidth));
|
||||||
unsigned short b = *bptr++;
|
unsigned short sb = (*bptr++ >> (8 - _bwidth));
|
||||||
unsigned short alpha = *aptr++;;
|
unsigned short sa = (*aptr++ >> (8 - _awidth));
|
||||||
|
unsigned dr, dg, db, da;
|
||||||
|
double alpha = (double) sa / ((1 << _rwidth) - 1);
|
||||||
|
|
||||||
|
if (sa == 0) // dest wouldn't be changed
|
||||||
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert 8-bit components down to the 5-bit values
|
* Unscale alpha value in each color component
|
||||||
* that the display system can actually handle.
|
|
||||||
*/
|
*/
|
||||||
r >>= (8 - _rwidth);
|
if (sa < _amask)
|
||||||
g >>= (8 - _gwidth);
|
|
||||||
b >>= (8 - _bwidth);
|
|
||||||
|
|
||||||
if (has_alpha)
|
|
||||||
{
|
{
|
||||||
if (dest_alpha)
|
double multiplier = (double) _amask / sa;
|
||||||
{
|
|
||||||
unsigned short dalpha;
|
sr *= multiplier;
|
||||||
unsigned long dpixel;
|
sg *= multiplier;
|
||||||
/* Alpha gets mixed the same as all the
|
sb *= multiplier;
|
||||||
other color components */
|
}
|
||||||
dpixel = XGetPixel(dest_alpha->image, col, row);
|
|
||||||
dalpha = (dpixel >> _ashift) & _amask;
|
|
||||||
dalpha = alpha + dalpha * (_amask - alpha)/_amask;
|
|
||||||
XPutPixel(dest_alpha->image, col, row,
|
|
||||||
dalpha << _ashift);
|
|
||||||
}
|
|
||||||
if (alpha == 0)
|
|
||||||
continue; // background unchanged.
|
|
||||||
|
|
||||||
if (alpha != _amask)
|
// get the destination pixel
|
||||||
{
|
pixel = XGetPixel(dest_im->image, col, row);
|
||||||
unsigned short ialpha = _amask - alpha;
|
PixelToRGB(pixel, dr, dg, db);
|
||||||
/*
|
|
||||||
* Get the background pixel and convert to RGB.
|
if (dest_alpha)
|
||||||
*/
|
{
|
||||||
pixel = XGetPixel(dest_im->image, col, row);
|
pixel = XGetPixel(dest_alpha->image, col, row);
|
||||||
if (pixel != oldPixel)
|
da = (pixel >> _ashift) & _amask;
|
||||||
{
|
}
|
||||||
oldPixel = pixel;
|
else // no alpha channel, background is opaque
|
||||||
PixelToRGB(pixel,oldBr,oldBg,oldBb);
|
da = _amask;
|
||||||
oldAlpha = 0;
|
|
||||||
}
|
|
||||||
if (alpha != oldAlpha)
|
|
||||||
{
|
|
||||||
oldAlpha = alpha;
|
|
||||||
oldAr = ialpha * oldBr;
|
|
||||||
oldAg = ialpha * oldBg;
|
|
||||||
oldAb = ialpha * oldBb;
|
|
||||||
}
|
|
||||||
|
|
||||||
// mix in alpha to produce RGB out
|
if (sa == _amask || da == 0) // source only
|
||||||
r = (oldAr + (r * alpha)) / _amask;
|
{
|
||||||
g = (oldAg + (g * alpha)) / _amask;
|
dr = sr;
|
||||||
b = (oldAb + (b * alpha)) / _amask;
|
dg = sg;
|
||||||
}
|
db = sb;
|
||||||
|
da = sa;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Not using alpha, but we still have to set it
|
double ialpha = (1.0 - alpha);
|
||||||
in the pixmap */
|
dr = (sr * alpha) + (dr * ialpha);
|
||||||
if (dest_alpha)
|
dg = (sg * alpha) + (dg * ialpha);
|
||||||
XPutPixel(dest_alpha->image, col, row,
|
db = (sb * alpha) + (db * ialpha);
|
||||||
_amask << _ashift);
|
if (da == _amask || da == _amask)
|
||||||
|
da = _amask;
|
||||||
|
else
|
||||||
|
da = sa + (da * ialpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
RGBToPixel(r,g,b,pixel);
|
CLAMP(dr);
|
||||||
|
CLAMP(dg);
|
||||||
|
CLAMP(db);
|
||||||
|
CLAMP(da);
|
||||||
|
|
||||||
|
RGBToPixel(dr, dg, db, pixel);
|
||||||
XPutPixel(dest_im->image, col, row, pixel);
|
XPutPixel(dest_im->image, col, row, pixel);
|
||||||
|
if (dest_alpha)
|
||||||
|
XPutPixel(dest_alpha->image, col, row, da << _ashift);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue