Abstracted the nsBlender class

This commit is contained in:
dcone%netscape.com 1998-10-29 19:22:42 +00:00
Родитель fcea19d2da
Коммит 3d66397f2a
7 изменённых файлов: 1231 добавлений и 922 удалений

Просмотреть файл

@ -29,7 +29,7 @@ DEFINES=-D_IMPL_NS_GFX -DWIN32_LEAN_AND_MEAN
CPPSRCS=nsColor.cpp nsColorNames.cpp nsColorNamesRGB.cpp nsFont.cpp \
nsImageGroup.cpp nsImageManager.cpp nsImageNetContextAsync.cpp \
nsImageRenderer.cpp nsImageRequest.cpp nsImageSystemServices.cpp \
nsImageURL.cpp nsRect.cpp nsTransform2D.cpp \
nsImageURL.cpp nsRect.cpp nsTransform2D.cpp nsBlender.cpp \
nsDeviceContext.cpp nsImageNetContextSync.cpp
EXPORTS=nsColor.h nsColorNames.h nsCoord.h nsFont.h nsRect.h nsPoint.h \
@ -47,7 +47,8 @@ CPP_OBJS=.\$(OBJDIR)\nsColor.obj .\$(OBJDIR)\nsColorNames.obj \
.\$(OBJDIR)\nsTransform2D.obj \
.\$(OBJDIR)\nsDeviceContext.obj \
.\$(OBJDIR)\nsImageNetContextSync.obj \
.\$(OBJDIR)\nsJSRenderingContext.obj
.\$(OBJDIR)\nsJSRenderingContext.obj \
.\$(OBJDIR)\nsBlender.obj
LINCS=-I$(PUBLIC)\util -I$(PUBLIC)\img \
-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor \

889
gfx/src/nsBlender.cpp Normal file
Просмотреть файл

@ -0,0 +1,889 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsBlender.h"
static NS_DEFINE_IID(kIBlenderIID, NS_IBLENDER_IID);
/** --------------------------------------------------------------------------
* General constructor for a nsBlender object
* @update dc - 10/29/98
*/
nsBlender :: nsBlender()
{
NS_INIT_REFCNT();
mSaveBytes = nsnull;
mSaveLS = 0;
}
/** --------------------------------------------------------------------------
* Initialize a nsBlender object, or re-initialize if it is re-used
* @update dc - 10/29/98
* @param aSrc -- source drawing surface
* @param aDst -- destination drawing surface
* @result NS_OK if everything initialized
*/
nsBlender :: ~nsBlender()
{
}
NS_IMPL_ISUPPORTS(nsBlender, kIBlenderIID);
//------------------------------------------------------------
nsresult
nsBlender::Init(nsDrawingSurface aSrc, nsDrawingSurface aDst)
{
return NS_OK;
}
/** --------------------------------------------------------------------------
* Calculate how many bytes per span for a given depth
* @update dc - 10/29/98
* @param aWidth -- width of the line
* @param aBitsPixel -- how many bytes per pixel in the bitmap
* @result The number of bytes per line
*/
PRInt32
nsBlender :: CalcBytesSpan(PRUint32 aWidth, PRUint32 aBitsPixel)
{
PRInt32 spanbytes;
spanbytes = (aWidth * aBitsPixel) >> 5;
if ((aWidth * aBitsPixel) & 0x1F)
spanbytes++;
spanbytes <<= 2;
return spanbytes;
}
/** --------------------------------------------------------------------------
* Blend two 32 bit image arrays
* @update dc - 10/29/98
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void
nsBlender::Do32Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea)
{
PRUint8 *d1,*d2,*s1,*s2;
PRUint32 val1,val2;
PRInt32 x,y,temp1,numlines,xinc,yinc;
PRUint8 *saveptr,*sv2;
saveptr = mSaveBytes;
aBlendVal = (aBlendVal*255)/100;
val2 = aBlendVal;
val1 = 255-val2;
// now go thru the image and blend (remember, its bottom upwards)
s1 = aSImage;
d1 = aDImage;
numlines = aNumlines;
xinc = 1;
yinc = 1;
if (aSaveBlendArea){
for (y = 0; y < aNumlines; y++){
s2 = s1;
d2 = d1;
sv2 = saveptr;
for (x = 0; x < aNumbytes; x++){
*sv2 = *d2;
temp1 = (((*d2) * val1) + ((*s2) * val2)) >> 8;
if (temp1 > 255)
temp1 = 255;
*d2 = (PRUint8)temp1;
sv2++;
d2++;
s2++;
}
s1 += aSLSpan;
d1 += aDLSpan;
saveptr+= mSaveLS;
}
} else {
for (y = 0; y < aNumlines; y++){
s2 = s1;
d2 = d1;
for (x = 0; x < aNumbytes; x++) {
temp1 = (((*d2) * val1) + ((*s2) * val2)) >> 8;
if (temp1 > 255)
temp1 = 255;
*d2 = (PRUint8)temp1;
d2++;
s2++;
}
s1 += aSLSpan;
d1 += aDLSpan;
}
}
}
/** --------------------------------------------------------------------------
* Blend two 24 bit image arrays using an 8 bit alpha mask
* @update dc - 10/29/98
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void
nsBlender::Do24BlendWithMask(PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRUint8 *aMImage,PRInt32 aSLSpan,PRInt32 aDLSpan,PRInt32 aMLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea)
{
PRUint8 *d1,*d2,*s1,*s2,*m1,*m2;
PRInt32 x,y;
PRUint32 val1,val2;
PRUint32 temp1,numlines,xinc,yinc;
PRInt32 sspan,dspan,mspan;
sspan = aSLSpan;
dspan = aDLSpan;
mspan = aMLSpan;
// now go thru the image and blend (remember, its bottom upwards)
s1 = aSImage;
d1 = aDImage;
m1 = aMImage;
numlines = aNumlines;
xinc = 1;
yinc = 1;
for (y = 0; y < aNumlines; y++){
s2 = s1;
d2 = d1;
m2 = m1;
for(x=0;x<aNumbytes;x++){
val1 = (*m2);
val2 = 255-val1;
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
if(temp1>255)
temp1 = 255;
*d2 = (unsigned char)temp1;
d2++;
s2++;
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
if(temp1>255)
temp1 = 255;
*d2 = (unsigned char)temp1;
d2++;
s2++;
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
if(temp1>255)
temp1 = 255;
*d2 = (unsigned char)temp1;
d2++;
s2++;
m2++;
}
s1 += sspan;
d1 += dspan;
m1 += mspan;
}
}
/** --------------------------------------------------------------------------
* Blend two 24 bit image arrays using a passed in blend value
* @update dc - 10/29/98
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void
nsBlender::Do24Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea)
{
PRUint8 *d1,*d2,*s1,*s2;
PRUint32 val1,val2;
PRInt32 x,y,temp1,numlines,xinc,yinc;
PRUint8 *saveptr,*sv2;
saveptr = mSaveBytes;
aBlendVal = (aBlendVal*255)/100;
val2 = aBlendVal;
val1 = 255-val2;
// now go thru the image and blend (remember, its bottom upwards)
s1 = aSImage;
d1 = aDImage;
numlines = aNumlines;
xinc = 1;
yinc = 1;
if(aSaveBlendArea){
for(y = 0; y < aNumlines; y++){
s2 = s1;
d2 = d1;
sv2 = saveptr;
for(x = 0; x < aNumbytes; x++){
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
if(temp1>255)
temp1 = 255;
*sv2 = *d2;
*d2 = (PRUint8)temp1;
sv2++;
d2++;
s2++;
}
s1 += aSLSpan;
d1 += aDLSpan;
saveptr+= mSaveLS;
}
}else{
for(y = 0; y < aNumlines; y++){
s2 = s1;
d2 = d1;
for(x = 0; x < aNumbytes; x++){
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
if(temp1>255)
temp1 = 255;
*d2 = (PRUint8)temp1;
d2++;
s2++;
}
s1 += aSLSpan;
d1 += aDLSpan;
}
}
}
//------------------------------------------------------------
#define RED16(x) (((x) & 0xf800) >> 8)
#define GREEN16(x) (((x) & 0x07e0) >> 3)
#define BLUE16(x) (((x) & 0x001f) << 3)
/** --------------------------------------------------------------------------
* Blend two 16 bit image arrays using a passed in blend value
* @update dc - 10/29/98
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void
nsBlender::Do16Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea)
{
PRUint16 *d1,*d2,*s1,*s2;
PRUint32 val1,val2,red,green,blue,stemp,dtemp;
PRInt32 x,y,numlines,xinc,yinc;
PRUint16 *saveptr,*sv2;
PRInt16 dspan,sspan,span,savesp;
// since we are using 16 bit pointers, the num bytes need to be cut by 2
saveptr = (PRUint16*)mSaveBytes;
aBlendVal = (aBlendVal * 255) / 100;
val2 = aBlendVal;
val1 = 255-val2;
// now go thru the image and blend (remember, its bottom upwards)
s1 = (PRUint16*)aSImage;
d1 = (PRUint16*)aDImage;
dspan = aDLSpan >> 1;
sspan = aSLSpan >> 1;
span = aNumbytes >> 1;
savesp = mSaveLS >> 1;
numlines = aNumlines;
xinc = 1;
yinc = 1;
if (aSaveBlendArea){
for (y = 0; y < aNumlines; y++){
s2 = s1;
d2 = d1;
sv2 = saveptr;
for (x = 0; x < span; x++){
stemp = *s2;
dtemp = *d2;
red = (RED16(dtemp) * val1 + RED16(stemp) * val2) >> 8;
if (red > 255)
red = 255;
green = (GREEN16(dtemp) * val1 + GREEN16(stemp) * val2) >> 8;
if (green > 255)
green = 255;
blue = (BLUE16(dtemp) * val1 + BLUE16(stemp) * val2) >> 8;
if (blue > 255)
blue = 255;
*sv2 = *d2;
*d2 = (PRUint16)((red & 0xf8) << 8) | ((green & 0xfc) << 3) | ((blue & 0xf8) >> 3);
sv2++;
d2++;
s2++;
}
s1 += sspan;
d1 += dspan;
saveptr += savesp;
}
} else {
for (y = 0; y < aNumlines; y++){
s2 = s1;
d2 = d1;
for (x = 0; x < span; x++){
stemp = *s2;
dtemp = *d2;
red = (RED16(dtemp) * val1 + RED16(stemp) * val2) >> 8;
if (red > 255)
red = 255;
green = (GREEN16(dtemp) * val1 + GREEN16(stemp) * val2) >> 8;
if (green > 255)
green = 255;
blue = (BLUE16(dtemp) * val1 + BLUE16(stemp) * val2) >> 8;
if (blue > 255)
blue = 255;
*d2 = (PRUint16)((red & 0xf8) << 8) | ((green & 0xfc) << 3) | ((blue & 0xf8) >> 3);
d2++;
s2++;
}
s1 += sspan;
d1 += dspan;
}
}
}
/** --------------------------------------------------------------------------
* Blend two 8 bit image arrays using an 8 bit alpha mask
* @update dc - 10/29/98
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void
nsBlender::Do8BlendWithMask(PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRUint8 *aMImage,PRInt32 aSLSpan,PRInt32 aDLSpan,PRInt32 aMLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea)
{
PRUint8 *d1,*d2,*s1,*s2,*m1,*m2;
PRInt32 x,y;
PRUint32 val1,val2,temp1,numlines,xinc,yinc;
PRInt32 sspan,dspan,mspan;
sspan = aSLSpan;
dspan = aDLSpan;
mspan = aMLSpan;
// now go thru the image and blend (remember, its bottom upwards)
s1 = aSImage;
d1 = aDImage;
m1 = aMImage;
numlines = aNumlines;
xinc = 1;
yinc = 1;
for (y = 0; y < aNumlines; y++){
s2 = s1;
d2 = d1;
m2 = m1;
for(x=0;x<aNumbytes;x++){
val1 = (*m2);
val2 = 255-val1;
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
if(temp1>255)
temp1 = 255;
*d2 = (unsigned char)temp1;
d2++;
s2++;
m2++;
}
s1 += sspan;
d1 += dspan;
m1 += mspan;
}
}
//------------------------------------------------------------
extern void inv_colormap(PRInt16 colors,PRUint8 *aCMap,PRInt16 bits,PRUint32 *dist_buf,PRUint8 *aRGBMap );
/** --------------------------------------------------------------------------
* Blend two 8 bit image arrays using a passed in blend value
* @update dc - 10/29/98
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void
nsBlender::Do8Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRInt32 aSLSpan,PRInt32 aDLSpan,nsColorMap *aColorMap,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea)
{
PRUint32 r,g,b,r1,g1,b1,i;
PRUint8 *d1,*d2,*s1,*s2;
PRInt32 x,y,val1,val2,numlines,xinc,yinc;;
PRUint8 *mapptr,*invermap;
PRUint32 *distbuffer;
PRUint32 quantlevel,tnum,num,shiftnum;
aBlendVal = (aBlendVal*255)/100;
val2 = aBlendVal;
val1 = 255-val2;
// calculate the inverse map
mapptr = aColorMap->Index;
quantlevel = aBlendQuality+2;
shiftnum = (8-quantlevel)+8;
tnum = 2;
for(i=1;i<quantlevel;i++)
tnum = 2*tnum;
num = tnum;
for(i=1;i<3;i++)
num = num*tnum;
distbuffer = new PRUint32[num];
invermap = new PRUint8[num*3];
inv_colormap(256,mapptr,quantlevel,distbuffer,invermap );
// now go thru the image and blend (remember, its bottom upwards)
s1 = aSImage;
d1 = aDImage;
numlines = aNumlines;
xinc = 1;
yinc = 1;
for(y = 0; y < aNumlines; y++){
s2 = s1;
d2 = d1;
for(x = 0; x < aNumbytes; x++){
i = (*d2);
r = aColorMap->Index[(3 * i) + 2];
g = aColorMap->Index[(3 * i) + 1];
b = aColorMap->Index[(3 * i)];
i =(*s2);
r1 = aColorMap->Index[(3 * i) + 2];
g1 = aColorMap->Index[(3 * i) + 1];
b1 = aColorMap->Index[(3 * i)];
r = ((r*val1)+(r1*val2))>>shiftnum;
if(r>tnum)
r = tnum;
g = ((g*val1)+(g1*val2))>>shiftnum;
if(g>tnum)
g = tnum;
b = ((b*val1)+(b1*val2))>>shiftnum;
if(b>tnum)
b = tnum;
r = (r<<(2*quantlevel))+(g<<quantlevel)+b;
(*d2) = invermap[r];
d2++;
s2++;
}
s1 += aSLSpan;
d1 += aDLSpan;
}
delete[] distbuffer;
delete[] invermap;
}
//------------------------------------------------------------
static PRInt32 bcenter, gcenter, rcenter;
static PRUint32 gdist, rdist, cdist;
static PRInt32 cbinc, cginc, crinc;
static PRUint32 *gdp, *rdp, *cdp;
static PRUint8 *grgbp, *rrgbp, *crgbp;
static PRInt32 gstride, rstride;
static PRInt32 x, xsqr, colormax;
static PRInt32 cindex;
static void maxfill(PRUint32 *buffer,PRInt32 side );
static PRInt32 redloop( void );
static PRInt32 greenloop( PRInt32 );
static PRInt32 blueloop( PRInt32 );
/** --------------------------------------------------------------------------
* Create an inverse colormap for a given color table
* @update dc - 10/29/98
* @param colors -- Number of colors
* @param aCMap -- The color map
* @param aBits -- The bits to make the color map from
* @param dist_buf -- a buffer to hold the temporary colors in while we calculate the map
* @param aRGBMap -- the map to put the inverse colors into for the color table
* @return VOID
*/
void
inv_colormap(PRInt16 colors,PRUint8 *aCMap,PRInt16 aBits,PRUint32 *dist_buf,PRUint8 *aRGBMap )
{
PRInt32 nbits = 8 - aBits;
PRUint32 r,g,b;
colormax = 1 << aBits;
x = 1 << nbits;
xsqr = 1 << (2 * nbits);
// Compute "strides" for accessing the arrays. */
gstride = colormax;
rstride = colormax * colormax;
maxfill( dist_buf, colormax );
for (cindex = 0;cindex < colors;cindex++ ){
r = aCMap[(3 * cindex) + 2];
g = aCMap[(3 * cindex) + 1];
b = aCMap[(3 * cindex)];
rcenter = r >> nbits;
gcenter = g >> nbits;
bcenter = b >> nbits;
rdist = r - (rcenter * x + x/2);
gdist = g - (gcenter * x + x/2);
cdist = b - (bcenter * x + x/2);
cdist = rdist*rdist + gdist*gdist + cdist*cdist;
crinc = 2 * ((rcenter + 1) * xsqr - (r * x));
cginc = 2 * ((gcenter + 1) * xsqr - (g * x));
cbinc = 2 * ((bcenter + 1) * xsqr - (b * x));
// Array starting points.
cdp = dist_buf + rcenter * rstride + gcenter * gstride + bcenter;
crgbp = aRGBMap + rcenter * rstride + gcenter * gstride + bcenter;
(void)redloop();
}
}
/** --------------------------------------------------------------------------
* find a red max or min value in a color cube
* @update dc - 10/29/98
* @return a red component in a certain span
*/
static PRInt32
redloop()
{
PRInt32 detect,r,first;
PRInt32 txsqr = xsqr + xsqr;
static PRInt32 rxx;
detect = 0;
rdist = cdist;
rxx = crinc;
rdp = cdp;
rrgbp = crgbp;
first = 1;
for (r=rcenter;r<colormax;r++,rdp+=rstride,rrgbp+=rstride,rdist+=rxx,rxx+=txsqr,first=0){
if ( greenloop( first ) )
detect = 1;
else
if ( detect )
break;
}
rxx=crinc-txsqr;
rdist = cdist-rxx;
rdp=cdp-rstride;
rrgbp=crgbp-rstride;
first=1;
for (r=rcenter-1;r>=0;r--,rdp-=rstride,rrgbp-=rstride,rxx-=txsqr,rdist-=rxx,first=0){
if ( greenloop( first ) )
detect = 1;
else
if ( detect )
break;
}
return detect;
}
/** --------------------------------------------------------------------------
* find a green max or min value in a color cube
* @update dc - 10/29/98
* @return a red component in a certain span
*/
static PRInt32
greenloop(PRInt32 aRestart)
{
PRInt32 detect,g,first;
PRInt32 txsqr = xsqr + xsqr;
static PRInt32 here, min, max;
static PRInt32 ginc, gxx, gcdist;
static PRUint32 *gcdp;
static PRUint8 *gcrgbp;
if(aRestart){
here = gcenter;
min = 0;
max = colormax - 1;
ginc = cginc;
}
detect = 0;
gcdp=rdp;
gdp=rdp;
gcrgbp=rrgbp;
grgbp=rrgbp;
gcdist=rdist;
gdist=rdist;
// loop up.
for(g=here,gxx=ginc,first=1;g<=max;
g++,gdp+=gstride,gcdp+=gstride,grgbp+=gstride,gcrgbp+=gstride,
gdist+=gxx,gcdist+=gxx,gxx+=txsqr,first=0){
if(blueloop(first)){
if (!detect){
if (g>here){
here = g;
rdp = gcdp;
rrgbp = gcrgbp;
rdist = gcdist;
ginc = gxx;
}
detect=1;
}
}else
if (detect){
break;
}
}
// loop down
gcdist = rdist-gxx;
gdist = gcdist;
gdp=rdp-gstride;
gcdp=gdp;
grgbp=rrgbp-gstride;
gcrgbp = grgbp;
for (g=here-1,gxx=ginc-txsqr,
first=1;g>=min;g--,gdp-=gstride,gcdp-=gstride,grgbp-=gstride,gcrgbp-=gstride,
gxx-=txsqr,gdist-=gxx,gcdist-=gxx,first=0){
if (blueloop(first)){
if (!detect){
here = g;
rdp = gcdp;
rrgbp = gcrgbp;
rdist = gcdist;
ginc = gxx;
detect = 1;
}
} else
if ( detect ){
break;
}
}
return detect;
}
/** --------------------------------------------------------------------------
* find a blue max or min value in a color cube
* @update dc - 10/29/98
* @return a red component in a certain span
*/
static PRInt32
blueloop(PRInt32 aRestart )
{
PRInt32 detect,b,i=cindex;
register PRUint32 *dp;
register PRUint8 *rgbp;
register PRInt32 bxx;
PRUint32 bdist;
register PRInt32 txsqr = xsqr + xsqr;
register PRInt32 lim;
static PRInt32 here, min, max;
static PRInt32 binc;
if (aRestart){
here = bcenter;
min = 0;
max = colormax - 1;
binc = cbinc;
}
detect = 0;
bdist = gdist;
// Basic loop, finds first applicable cell.
for (b=here,bxx=binc,dp=gdp,rgbp=grgbp,lim=max;b<=lim;
b++,dp++,rgbp++,bdist+=bxx,bxx+=txsqr){
if(*dp>bdist){
if(b>here){
here = b;
gdp = dp;
grgbp = rgbp;
gdist = bdist;
binc = bxx;
}
detect = 1;
break;
}
}
// Second loop fills in a run of closer cells.
for (;b<=lim;b++,dp++,rgbp++,bdist+=bxx,bxx+=txsqr){
if (*dp>bdist){
*dp = bdist;
*rgbp = i;
}
else{
break;
}
}
// Basic loop down, do initializations here
lim = min;
b = here - 1;
bxx = binc - txsqr;
bdist = gdist - bxx;
dp = gdp - 1;
rgbp = grgbp - 1;
// The 'find' loop is executed only if we didn't already find something.
if (!detect)
for (;b>=lim;b--,dp--,rgbp--,bxx-=txsqr,bdist-=bxx){
if (*dp>bdist){
here = b;
gdp = dp;
grgbp = rgbp;
gdist = bdist;
binc = bxx;
detect = 1;
break;
}
}
// Update loop.
for (;b>=lim;b--,dp--,rgbp--,bxx-=txsqr,bdist-=bxx){
if (*dp>bdist){
*dp = bdist;
*rgbp = i;
} else{
break;
}
}
// If we saw something, update the edge trackers.
return detect;
}
/** --------------------------------------------------------------------------
* fill in a span with a max value
* @update dc - 10/29/98
* @return VOID
*/
static void
maxfill(PRUint32 *buffer,PRInt32 side )
{
register PRInt32 maxv = ~0L;
register PRInt32 i;
register PRUint32 *bp;
for (i=side*side*side,bp=buffer;i>0;i--,bp++)
*bp = maxv;
}
//------------------------------------------------------------

183
gfx/src/nsBlender.h Normal file
Просмотреть файл

@ -0,0 +1,183 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsBlender_h___
#define nsBlender_h___
#include "nsIBlender.h"
#include "nsPoint.h"
#include "nsRect.h"
#include "nsIImage.h"
//----------------------------------------------------------------------
// Blender interface
class nsBlender : public nsIBlender
{
public:
NS_DECL_ISUPPORTS
/** --------------------------------------------------------------------------
* General constructor for a nsBlender object
* @update dc - 10/29/98
*/
nsBlender();
/** --------------------------------------------------------------------------
* Destructor for a nsBlender object
* @update dc - 10/29/98
*/
~nsBlender();
/** --------------------------------------------------------------------------
* Initialize a nsBlender object, or re-initialize if it is re-used
* @update dc - 10/29/98
* @param aSrc -- source drawing surface
* @param aDst -- destination drawing surface
* @result NS_OK if everything initialized
*/
virtual nsresult Init(nsDrawingSurface aSrc,nsDrawingSurface aDst);
protected:
/** --------------------------------------------------------------------------
* Calculate how many bytes per span for a given depth
* @update dc - 10/29/98
* @param aWidth -- width of the line
* @param aBitsPixel -- how many bytes per pixel in the bitmap
* @result The number of bytes per line
*/
PRInt32 CalcBytesSpan(PRUint32 aWidth,PRUint32 aBitsPixel);
/** --------------------------------------------------------------------------
* Blend two 32 bit image arrays
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void Do32Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea);
/** --------------------------------------------------------------------------
* Blend two 24 bit image arrays using an 8 bit alpha mask
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void Do24BlendWithMask(PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
PRUint8 *aMImage,PRInt32 aSLSpan,PRInt32 aDLSpan,PRInt32 aMLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea);
/** --------------------------------------------------------------------------
* Blend two 24 bit image arrays using a passed in blend value
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void Do24Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea);
/** --------------------------------------------------------------------------
* Blend two 16 bit image arrays using a passed in blend value
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void Do16Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea);
/** --------------------------------------------------------------------------
* Blend two 8 bit image arrays using an 8 bit alpha mask
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void Do8BlendWithMask(PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
PRUint8 *aMImage,PRInt32 aSLSpan,PRInt32 aDLSpan,PRInt32 aMLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea);
/** --------------------------------------------------------------------------
* Blend two 8 bit image arrays using a passed in blend value
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void Do8Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
PRInt32 aSLSpan,PRInt32 aDLSpan,nsColorMap *aColorMap,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea);
PRUint8 *mSaveBytes; // place to save bits
PRInt32 mSaveLS;
};
#endif

Просмотреть файл

@ -61,13 +61,13 @@ public:
nsDrawingSurface aDest, PRInt32 aDX, PRInt32 aDY, float aSrcOpacity,PRBool aSaveBlendArea) = 0;
/**
* Return the source drawing surface that the blending it going to
* Return the source drawing surface to be blended
* @return The platform specific drawing surface
*/
virtual nsDrawingSurface GetSrcDS()=0;
/**
* Return the destination drawing surface that the blending it going to
* Return the destination drawing surface to be blended and modified
* @return The platform specific drawing surface
*/
virtual nsDrawingSurface GetDstDS()=0;

Просмотреть файл

@ -45,6 +45,7 @@ OBJS = \
$(NULL)
LINCS= \
-I..\
-I$(PUBLIC)\raptor \
-I$(PUBLIC)\xpcom \
-I$(PUBLIC)\dom \

Просмотреть файл

@ -24,18 +24,16 @@
#include "ddraw.h"
#endif
static NS_DEFINE_IID(kIBlenderIID, NS_IBLENDER_IID);
//------------------------------------------------------------
//static NS_DEFINE_IID(kIBlenderIID, NS_IBLENDER_IID);
/** --------------------------------------------------------------------------
* Construct and set the initial values for this windows specific blender
* @update dc - 10/29/98
*/
nsBlenderWin :: nsBlenderWin()
{
NS_INIT_REFCNT();
mSaveBytes = nsnull;
mSrcBytes = nsnull;
mDstBytes = nsnull;
mSaveLS = 0;
mSaveNumLines = 0;
mSrcbinfo = nsnull;
mDstbinfo = nsnull;
@ -48,23 +46,23 @@ nsBlenderWin :: nsBlenderWin()
mDstDS = nsnull;
}
//------------------------------------------------------------
/** --------------------------------------------------------------------------
* Release and cleanup all the windows specific information for this blender
* @update dc - 10/29/98
*/
nsBlenderWin :: ~nsBlenderWin()
{
NS_IF_RELEASE(mSrcDS);
NS_IF_RELEASE(mDstDS);
// get rid of the DIB's
if (nsnull != mSrcbinfo)
DeleteDIB(&mSrcbinfo, &mSrcBytes);
if (nsnull != mDstbinfo)
DeleteDIB(&mDstbinfo, &mDstBytes);
if (mSaveBytes != nsnull)
{
if (mSaveBytes != nsnull){
delete [] mSaveBytes;
mSaveBytes == nsnull;
}
@ -74,10 +72,10 @@ nsBlenderWin :: ~nsBlenderWin()
mSaveNumLines = 0;
}
NS_IMPL_ISUPPORTS(nsBlenderWin, kIBlenderIID);
//------------------------------------------------------------
/** --------------------------------------------------------------------------
* Set all the windows specific data for a blender to some initial values
* @update dc - 10/29/98
*/
nsresult
nsBlenderWin::Init(nsDrawingSurface aSrc, nsDrawingSurface aDst)
{
@ -99,8 +97,20 @@ nsBlenderWin::Init(nsDrawingSurface aSrc, nsDrawingSurface aDst)
return NS_OK;
}
//------------------------------------------------------------
/** --------------------------------------------------------------------------
* Run the blend using the passed in drawing surfaces
* @update dc - 10/29/98
* @param aSX -- left location for the blend
* @param aSY -- top location for the blend
* @param aWidth -- width of the blend
* @param aHeight -- height of the blend
* @param aDst -- Destination drawing surface for the blend
* @param aDX -- left location for the destination of the blend
* @param aDY -- top location for the destination of the blend
* @param aSrcOpacity -- the percentage for the blend
* @param aSaveBlendArea -- If true, will save off the blended area to restore later
* @result NS_OK if the blend worked.
*/
nsresult
nsBlenderWin::Blend(PRInt32 aSX, PRInt32 aSY, PRInt32 aWidth, PRInt32 aHeight,
nsDrawingSurface aDst, PRInt32 aDX, PRInt32 aDY, float aSrcOpacity,PRBool aSaveBlendArea)
@ -320,8 +330,12 @@ nsBlenderWin::Blend(PRInt32 aSX, PRInt32 aSY, PRInt32 aWidth, PRInt32 aHeight,
return result;
}
//------------------------------------------------------------
/** --------------------------------------------------------------------------
* Replace the bits saved from the last blend if the restore flag was set
* @update dc - 10/29/98
* @param aDst -- Destination drawing surface to restore to
* @result PR_TRUE if the restore worked.
*/
PRBool
nsBlenderWin::RestoreImage(nsDrawingSurface aDst)
{
@ -368,6 +382,16 @@ HBITMAP dstbits, tb1;
#ifdef NGLAYOUT_DDRAW
/** --------------------------------------------------------------------------
* Lock a surface down for Direct draw
* @update mp - 10/01/98
* @param IDirectDrawSurface --
* @param DDSURFACEDESC --
* @param BITMAP --
* @param RECT --
* @param DWORD --
* @result PR_TRUE lock was succesful
*/
PRBool nsBlenderWin :: LockSurface(IDirectDrawSurface *aSurface, DDSURFACEDESC *aDesc, BITMAP *aBitmap, RECT *aRect, DWORD aLockFlags)
{
if (nsnull != aSurface)
@ -407,8 +431,26 @@ PRBool nsBlenderWin :: LockSurface(IDirectDrawSurface *aSurface, DDSURFACEDESC *
#endif
//------------------------------------------------------------
/** --------------------------------------------------------------------------
* Calculate the metrics for the alpha layer before the blend
* @update mp - 10/01/98
* @param aSrcInfo -- a pointer to a source bitmap
* @param aDestInfo -- a pointer to the destination bitmap
* @param aSrcUL -- upperleft for the source blend
* @param aMaskInfo -- a pointer to the mask bitmap
* @param aMaskUL -- upperleft for the mask bitmap
* @param aWidth -- width of the blend
* @param aHeight -- heigth of the blend
* @param aNumLines -- a pointer to number of lines to do for the blend
* @param aNumbytes -- a pointer to the number of bytes per line for the blend
* @param aSImage -- a pointer to a the bit pointer for the source
* @param aDImage -- a pointer to a the bit pointer for the destination
* @param aMImage -- a pointer to a the bit pointer for the mask
* @param aSLSpan -- number of bytes per span for the source
* @param aDLSpan -- number of bytes per span for the destination
* @param aMLSpan -- number of bytes per span for the mask
* @result PR_TRUE if calculation was succesful
*/
PRBool
nsBlenderWin::CalcAlphaMetrics(BITMAP *aSrcInfo,BITMAP *aDestInfo,nsPoint *aSrcUL,
BITMAP *aMaskInfo,nsPoint *aMaskUL,
@ -478,25 +520,16 @@ PRInt32 startx,starty;
return doalpha;
}
//------------------------------------------------------------
PRInt32
nsBlenderWin :: CalcBytesSpan(PRUint32 aWidth, PRUint32 aBitsPixel)
{
PRInt32 spanbytes;
spanbytes = (aWidth * aBitsPixel) >> 5;
if ((aWidth * aBitsPixel) & 0x1F)
spanbytes++;
spanbytes <<= 2;
return spanbytes;
}
//-----------------------------------------------------------
/** --------------------------------------------------------------------------
* Build the device independent bitmap
* @update mp - 10/01/98
* @param aBHead -- a pointer DIB header we are filling in
* @param aBits -- a pointer to the bits for this DIB
* @param aWidth -- the width of the DIB
* @param aHeight -- the height of the DIB
* @param aDepth -- depth of the DIB
* @result NS_OK if the build was succesful
*/
nsresult
nsBlenderWin :: BuildDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits,PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth)
{
@ -575,8 +608,13 @@ nsBlenderWin :: BuildDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits,PRInt
return NS_ERROR_FAILURE;
}
//------------------------------------------------------------
/** --------------------------------------------------------------------------
* Delete the device independent bitmap
* @update mp - 10/01/98
* @param aBHead -- a pointer DIB header we are filling in
* @param aBits -- a pointer to the bits for this DIB
* @result VOID
*/
void
nsBlenderWin::DeleteDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits)
{
@ -587,783 +625,3 @@ nsBlenderWin::DeleteDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits)
aBits = 0;
}
//------------------------------------------------------------
// This routine can not be fast enough (and it's the same as the
// 24 bit routine, so maybe it can be killed...)
void
nsBlenderWin::Do32Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea)
{
PRUint8 *d1,*d2,*s1,*s2;
PRUint32 val1,val2;
PRInt32 x,y,temp1,numlines,xinc,yinc;
PRUint8 *saveptr,*sv2;
saveptr = mSaveBytes;
aBlendVal = (aBlendVal*255)/100;
val2 = aBlendVal;
val1 = 255-val2;
// now go thru the image and blend (remember, its bottom upwards)
s1 = aSImage;
d1 = aDImage;
numlines = aNumlines;
xinc = 1;
yinc = 1;
if (aSaveBlendArea)
{
for (y = 0; y < aNumlines; y++)
{
s2 = s1;
d2 = d1;
sv2 = saveptr;
for (x = 0; x < aNumbytes; x++)
{
*sv2 = *d2;
temp1 = (((*d2) * val1) + ((*s2) * val2)) >> 8;
if (temp1 > 255)
temp1 = 255;
*d2 = (PRUint8)temp1;
sv2++;
d2++;
s2++;
}
s1 += aSLSpan;
d1 += aDLSpan;
saveptr+= mSaveLS;
}
}
else
{
for (y = 0; y < aNumlines; y++)
{
s2 = s1;
d2 = d1;
for (x = 0; x < aNumbytes; x++)
{
temp1 = (((*d2) * val1) + ((*s2) * val2)) >> 8;
if (temp1 > 255)
temp1 = 255;
*d2 = (PRUint8)temp1;
d2++;
s2++;
}
s1 += aSLSpan;
d1 += aDLSpan;
}
}
}
//------------------------------------------------------------
// This routine can not be fast enough
void
nsBlenderWin::Do24BlendWithMask(PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRUint8 *aMImage,PRInt32 aSLSpan,PRInt32 aDLSpan,PRInt32 aMLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea)
{
PRUint8 *d1,*d2,*s1,*s2,*m1,*m2;
PRInt32 x,y;
PRUint32 val1,val2;
PRUint32 temp1,numlines,xinc,yinc;
PRInt32 sspan,dspan,mspan;
sspan = aSLSpan;
dspan = aDLSpan;
mspan = aMLSpan;
// now go thru the image and blend (remember, its bottom upwards)
s1 = aSImage;
d1 = aDImage;
m1 = aMImage;
numlines = aNumlines;
xinc = 1;
yinc = 1;
for (y = 0; y < aNumlines; y++)
{
s2 = s1;
d2 = d1;
m2 = m1;
for(x=0;x<aNumbytes;x++)
{
val1 = (*m2);
val2 = 255-val1;
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
if(temp1>255)
temp1 = 255;
*d2 = (unsigned char)temp1;
d2++;
s2++;
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
if(temp1>255)
temp1 = 255;
*d2 = (unsigned char)temp1;
d2++;
s2++;
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
if(temp1>255)
temp1 = 255;
*d2 = (unsigned char)temp1;
d2++;
s2++;
m2++;
}
s1 += sspan;
d1 += dspan;
m1 += mspan;
}
}
//------------------------------------------------------------
// This routine can not be fast enough
void
nsBlenderWin::Do24Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea)
{
PRUint8 *d1,*d2,*s1,*s2;
PRUint32 val1,val2;
PRInt32 x,y,temp1,numlines,xinc,yinc;
PRUint8 *saveptr,*sv2;
saveptr = mSaveBytes;
aBlendVal = (aBlendVal*255)/100;
val2 = aBlendVal;
val1 = 255-val2;
// now go thru the image and blend (remember, its bottom upwards)
s1 = aSImage;
d1 = aDImage;
numlines = aNumlines;
xinc = 1;
yinc = 1;
if(aSaveBlendArea)
{
for(y = 0; y < aNumlines; y++)
{
s2 = s1;
d2 = d1;
sv2 = saveptr;
for(x = 0; x < aNumbytes; x++)
{
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
if(temp1>255)
temp1 = 255;
*sv2 = *d2;
*d2 = (PRUint8)temp1;
sv2++;
d2++;
s2++;
}
s1 += aSLSpan;
d1 += aDLSpan;
saveptr+= mSaveLS;
}
}
else
{
for(y = 0; y < aNumlines; y++)
{
s2 = s1;
d2 = d1;
for(x = 0; x < aNumbytes; x++)
{
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
if(temp1>255)
temp1 = 255;
*d2 = (PRUint8)temp1;
d2++;
s2++;
}
s1 += aSLSpan;
d1 += aDLSpan;
}
}
}
//------------------------------------------------------------
#define RED16(x) (((x) & 0xf800) >> 8)
#define GREEN16(x) (((x) & 0x07e0) >> 3)
#define BLUE16(x) (((x) & 0x001f) << 3)
// This routine can not be fast enough
void
nsBlenderWin::Do16Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea)
{
PRUint16 *d1,*d2,*s1,*s2;
PRUint32 val1,val2,red,green,blue,stemp,dtemp;
PRInt32 x,y,numlines,xinc,yinc;
PRUint16 *saveptr,*sv2;
PRInt16 dspan,sspan,span,savesp;
// since we are using 16 bit pointers, the num bytes need to be cut by 2
saveptr = (PRUint16*)mSaveBytes;
aBlendVal = (aBlendVal * 255) / 100;
val2 = aBlendVal;
val1 = 255-val2;
// now go thru the image and blend (remember, its bottom upwards)
s1 = (PRUint16*)aSImage;
d1 = (PRUint16*)aDImage;
dspan = aDLSpan >> 1;
sspan = aSLSpan >> 1;
span = aNumbytes >> 1;
savesp = mSaveLS >> 1;
numlines = aNumlines;
xinc = 1;
yinc = 1;
if (aSaveBlendArea)
{
for (y = 0; y < aNumlines; y++)
{
s2 = s1;
d2 = d1;
sv2 = saveptr;
for (x = 0; x < span; x++)
{
stemp = *s2;
dtemp = *d2;
red = (RED16(dtemp) * val1 + RED16(stemp) * val2) >> 8;
if (red > 255)
red = 255;
green = (GREEN16(dtemp) * val1 + GREEN16(stemp) * val2) >> 8;
if (green > 255)
green = 255;
blue = (BLUE16(dtemp) * val1 + BLUE16(stemp) * val2) >> 8;
if (blue > 255)
blue = 255;
*sv2 = *d2;
*d2 = (PRUint16)((red & 0xf8) << 8) | ((green & 0xfc) << 3) | ((blue & 0xf8) >> 3);
sv2++;
d2++;
s2++;
}
s1 += sspan;
d1 += dspan;
saveptr += savesp;
}
}
else
{
for (y = 0; y < aNumlines; y++)
{
s2 = s1;
d2 = d1;
for (x = 0; x < span; x++)
{
stemp = *s2;
dtemp = *d2;
red = (RED16(dtemp) * val1 + RED16(stemp) * val2) >> 8;
if (red > 255)
red = 255;
green = (GREEN16(dtemp) * val1 + GREEN16(stemp) * val2) >> 8;
if (green > 255)
green = 255;
blue = (BLUE16(dtemp) * val1 + BLUE16(stemp) * val2) >> 8;
if (blue > 255)
blue = 255;
*d2 = (PRUint16)((red & 0xf8) << 8) | ((green & 0xfc) << 3) | ((blue & 0xf8) >> 3);
d2++;
s2++;
}
s1 += sspan;
d1 += dspan;
}
}
}
//------------------------------------------------------------
// This routine can not be fast enough
void
nsBlenderWin::Do8BlendWithMask(PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRUint8 *aMImage,PRInt32 aSLSpan,PRInt32 aDLSpan,PRInt32 aMLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea)
{
PRUint8 *d1,*d2,*s1,*s2,*m1,*m2;
PRInt32 x,y;
PRUint32 val1,val2,temp1,numlines,xinc,yinc;
PRInt32 sspan,dspan,mspan;
sspan = aSLSpan;
dspan = aDLSpan;
mspan = aMLSpan;
// now go thru the image and blend (remember, its bottom upwards)
s1 = aSImage;
d1 = aDImage;
m1 = aMImage;
numlines = aNumlines;
xinc = 1;
yinc = 1;
for (y = 0; y < aNumlines; y++)
{
s2 = s1;
d2 = d1;
m2 = m1;
for(x=0;x<aNumbytes;x++)
{
val1 = (*m2);
val2 = 255-val1;
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
if(temp1>255)
temp1 = 255;
*d2 = (unsigned char)temp1;
d2++;
s2++;
m2++;
}
s1 += sspan;
d1 += dspan;
m1 += mspan;
}
}
//------------------------------------------------------------
extern void inv_colormap(PRInt16 colors,PRUint8 *aCMap,PRInt16 bits,PRUint32 *dist_buf,PRUint8 *aRGBMap );
// This routine can not be fast enough
void
nsBlenderWin::Do8Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRInt32 aSLSpan,PRInt32 aDLSpan,nsColorMap *aColorMap,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea)
{
PRUint32 r,g,b,r1,g1,b1,i;
PRUint8 *d1,*d2,*s1,*s2;
PRInt32 x,y,val1,val2,numlines,xinc,yinc;;
PRUint8 *mapptr,*invermap;
PRUint32 *distbuffer;
PRUint32 quantlevel,tnum,num,shiftnum;
aBlendVal = (aBlendVal*255)/100;
val2 = aBlendVal;
val1 = 255-val2;
// calculate the inverse map
mapptr = aColorMap->Index;
quantlevel = aBlendQuality+2;
shiftnum = (8-quantlevel)+8;
tnum = 2;
for(i=1;i<quantlevel;i++)
tnum = 2*tnum;
num = tnum;
for(i=1;i<3;i++)
num = num*tnum;
distbuffer = new PRUint32[num];
invermap = new PRUint8[num*3];
inv_colormap(256,mapptr,quantlevel,distbuffer,invermap );
// now go thru the image and blend (remember, its bottom upwards)
s1 = aSImage;
d1 = aDImage;
numlines = aNumlines;
xinc = 1;
yinc = 1;
for(y = 0; y < aNumlines; y++)
{
s2 = s1;
d2 = d1;
for(x = 0; x < aNumbytes; x++)
{
i = (*d2);
r = aColorMap->Index[(3 * i) + 2];
g = aColorMap->Index[(3 * i) + 1];
b = aColorMap->Index[(3 * i)];
i =(*s2);
r1 = aColorMap->Index[(3 * i) + 2];
g1 = aColorMap->Index[(3 * i) + 1];
b1 = aColorMap->Index[(3 * i)];
r = ((r*val1)+(r1*val2))>>shiftnum;
if(r>tnum)
r = tnum;
g = ((g*val1)+(g1*val2))>>shiftnum;
if(g>tnum)
g = tnum;
b = ((b*val1)+(b1*val2))>>shiftnum;
if(b>tnum)
b = tnum;
r = (r<<(2*quantlevel))+(g<<quantlevel)+b;
(*d2) = invermap[r];
d2++;
s2++;
}
s1 += aSLSpan;
d1 += aDLSpan;
}
delete[] distbuffer;
delete[] invermap;
}
//------------------------------------------------------------
static PRInt32 bcenter, gcenter, rcenter;
static PRUint32 gdist, rdist, cdist;
static PRInt32 cbinc, cginc, crinc;
static PRUint32 *gdp, *rdp, *cdp;
static PRUint8 *grgbp, *rrgbp, *crgbp;
static PRInt32 gstride, rstride;
static PRInt32 x, xsqr, colormax;
static PRInt32 cindex;
static void maxfill(PRUint32 *buffer,PRInt32 side );
static PRInt32 redloop( void );
static PRInt32 greenloop( PRInt32 );
static PRInt32 blueloop( PRInt32 );
//------------------------------------------------------------
void
inv_colormap(PRInt16 colors,PRUint8 *aCMap,PRInt16 aBits,PRUint32 *dist_buf,PRUint8 *aRGBMap )
{
PRInt32 nbits = 8 - aBits;
PRUint32 r,g,b;
colormax = 1 << aBits;
x = 1 << nbits;
xsqr = 1 << (2 * nbits);
// Compute "strides" for accessing the arrays. */
gstride = colormax;
rstride = colormax * colormax;
maxfill( dist_buf, colormax );
for (cindex = 0;cindex < colors;cindex++ )
{
r = aCMap[(3 * cindex) + 2];
g = aCMap[(3 * cindex) + 1];
b = aCMap[(3 * cindex)];
rcenter = r >> nbits;
gcenter = g >> nbits;
bcenter = b >> nbits;
rdist = r - (rcenter * x + x/2);
gdist = g - (gcenter * x + x/2);
cdist = b - (bcenter * x + x/2);
cdist = rdist*rdist + gdist*gdist + cdist*cdist;
crinc = 2 * ((rcenter + 1) * xsqr - (r * x));
cginc = 2 * ((gcenter + 1) * xsqr - (g * x));
cbinc = 2 * ((bcenter + 1) * xsqr - (b * x));
// Array starting points.
cdp = dist_buf + rcenter * rstride + gcenter * gstride + bcenter;
crgbp = aRGBMap + rcenter * rstride + gcenter * gstride + bcenter;
(void)redloop();
}
}
//------------------------------------------------------------
// redloop -- loop up and down from red center.
static PRInt32
redloop()
{
PRInt32 detect,r,first;
PRInt32 txsqr = xsqr + xsqr;
static PRInt32 rxx;
detect = 0;
rdist = cdist;
rxx = crinc;
rdp = cdp;
rrgbp = crgbp;
first = 1;
for (r=rcenter;r<colormax;r++,rdp+=rstride,rrgbp+=rstride,rdist+=rxx,rxx+=txsqr,first=0)
{
if ( greenloop( first ) )
detect = 1;
else
if ( detect )
break;
}
rxx=crinc-txsqr;
rdist = cdist-rxx;
rdp=cdp-rstride;
rrgbp=crgbp-rstride;
first=1;
for (r=rcenter-1;r>=0;r--,rdp-=rstride,rrgbp-=rstride,rxx-=txsqr,rdist-=rxx,first=0)
{
if ( greenloop( first ) )
detect = 1;
else
if ( detect )
break;
}
return detect;
}
//------------------------------------------------------------
// greenloop -- loop up and down from green center.
static PRInt32
greenloop(PRInt32 aRestart)
{
PRInt32 detect,g,first;
PRInt32 txsqr = xsqr + xsqr;
static PRInt32 here, min, max;
static PRInt32 ginc, gxx, gcdist;
static PRUint32 *gcdp;
static PRUint8 *gcrgbp;
if(aRestart)
{
here = gcenter;
min = 0;
max = colormax - 1;
ginc = cginc;
}
detect = 0;
gcdp=rdp;
gdp=rdp;
gcrgbp=rrgbp;
grgbp=rrgbp;
gcdist=rdist;
gdist=rdist;
// loop up.
for(g=here,gxx=ginc,first=1;g<=max;
g++,gdp+=gstride,gcdp+=gstride,grgbp+=gstride,gcrgbp+=gstride,
gdist+=gxx,gcdist+=gxx,gxx+=txsqr,first=0)
{
if(blueloop(first))
{
if (!detect)
{
if (g>here)
{
here = g;
rdp = gcdp;
rrgbp = gcrgbp;
rdist = gcdist;
ginc = gxx;
}
detect=1;
}
}
else
if (detect)
{
break;
}
}
// loop down
gcdist = rdist-gxx;
gdist = gcdist;
gdp=rdp-gstride;
gcdp=gdp;
grgbp=rrgbp-gstride;
gcrgbp = grgbp;
for (g=here-1,gxx=ginc-txsqr,
first=1;g>=min;g--,gdp-=gstride,gcdp-=gstride,grgbp-=gstride,gcrgbp-=gstride,
gxx-=txsqr,gdist-=gxx,gcdist-=gxx,first=0)
{
if (blueloop(first))
{
if (!detect)
{
here = g;
rdp = gcdp;
rrgbp = gcrgbp;
rdist = gcdist;
ginc = gxx;
detect = 1;
}
}
else
if ( detect )
{
break;
}
}
return detect;
}
//------------------------------------------------------------
static PRInt32
blueloop(PRInt32 aRestart )
{
PRInt32 detect,b,i=cindex;
register PRUint32 *dp;
register PRUint8 *rgbp;
register PRInt32 bxx;
PRUint32 bdist;
register PRInt32 txsqr = xsqr + xsqr;
register PRInt32 lim;
static PRInt32 here, min, max;
static PRInt32 binc;
if (aRestart)
{
here = bcenter;
min = 0;
max = colormax - 1;
binc = cbinc;
}
detect = 0;
bdist = gdist;
// Basic loop, finds first applicable cell.
for (b=here,bxx=binc,dp=gdp,rgbp=grgbp,lim=max;b<=lim;
b++,dp++,rgbp++,bdist+=bxx,bxx+=txsqr)
{
if(*dp>bdist)
{
if(b>here)
{
here = b;
gdp = dp;
grgbp = rgbp;
gdist = bdist;
binc = bxx;
}
detect = 1;
break;
}
}
// Second loop fills in a run of closer cells.
for (;b<=lim;b++,dp++,rgbp++,bdist+=bxx,bxx+=txsqr)
{
if (*dp>bdist)
{
*dp = bdist;
*rgbp = i;
}
else
{
break;
}
}
// Basic loop down, do initializations here
lim = min;
b = here - 1;
bxx = binc - txsqr;
bdist = gdist - bxx;
dp = gdp - 1;
rgbp = grgbp - 1;
// The 'find' loop is executed only if we didn't already find something.
if (!detect)
for (;b>=lim;b--,dp--,rgbp--,bxx-=txsqr,bdist-=bxx)
{
if (*dp>bdist)
{
here = b;
gdp = dp;
grgbp = rgbp;
gdist = bdist;
binc = bxx;
detect = 1;
break;
}
}
// Update loop.
for (;b>=lim;b--,dp--,rgbp--,bxx-=txsqr,bdist-=bxx)
{
if (*dp>bdist)
{
*dp = bdist;
*rgbp = i;
}
else
{
break;
}
}
// If we saw something, update the edge trackers.
return detect;
}
//------------------------------------------------------------
static void
maxfill(PRUint32 *buffer,PRInt32 side )
{
register PRInt32 maxv = ~0L;
register PRInt32 i;
register PRUint32 *bp;
for (i=side*side*side,bp=buffer;i>0;i--,bp++)
*bp = maxv;
}
//------------------------------------------------------------

Просмотреть файл

@ -19,7 +19,7 @@
#ifndef nsBlenderWin_h___
#define nsBlenderWin_h___
#include "nsIBlender.h"
#include "nsBlender.h"
#include "nsPoint.h"
#include "nsRect.h"
#include "nsIImage.h"
@ -32,25 +32,79 @@
//----------------------------------------------------------------------
// Blender interface
class nsBlenderWin : public nsIBlender
class nsBlenderWin : public nsBlender
{
public:
NS_DECL_ISUPPORTS
nsBlenderWin();
~nsBlenderWin();
/** --------------------------------------------------------------------------
* Construct and set the initial values for this windows specific blender
* @update dc - 10/29/98
*/
nsBlenderWin();
virtual nsresult Init(nsDrawingSurface aSrc,nsDrawingSurface aDst);
virtual nsresult Blend(PRInt32 aSX, PRInt32 aSY, PRInt32 aWidth, PRInt32 aHeight,
/** --------------------------------------------------------------------------
* Release and cleanup all the windows specific information for this blender
* @update dc - 10/29/98
*/
~nsBlenderWin();
/** --------------------------------------------------------------------------
* Set all the windows specific data for a blender to some initial values
* @update dc - 10/29/98
*/
virtual nsresult Init(nsDrawingSurface aSrc,nsDrawingSurface aDst);
/** --------------------------------------------------------------------------
* Run the blend using the passed in drawing surfaces
* @update dc - 10/29/98
* @param aSX -- left location for the blend
* @param aSY -- top location for the blend
* @param aWidth -- width of the blend
* @param aHeight -- height of the blend
* @param aDst -- Destination drawing surface for the blend
* @param aDX -- left location for the destination of the blend
* @param aDY -- top location for the destination of the blend
* @param aSrcOpacity -- the percentage for the blend
* @param aSaveBlendArea -- If true, will save off the blended area to restore later
* @result NS_OK if the blend worked.
*/
virtual nsresult Blend(PRInt32 aSX, PRInt32 aSY, PRInt32 aWidth, PRInt32 aHeight,
nsDrawingSurface aDest, PRInt32 aDX, PRInt32 aDY, float aSrcOpacity,PRBool aSaveBlendArea);
nsDrawingSurface GetSrcDS() {return(mSrcDS);}
nsDrawingSurface GetDstDS() {return(mDstDS);}
/** --------------------------------------------------------------------------
* Replace the bits saved from the last blend if the restore flag was set
* @update dc - 10/29/98
* @param aDst -- Destination drawing surface to restore to
* @result PR_TRUE if the restore worked.
*/
PRBool RestoreImage(nsDrawingSurface aDst);
private:
/** --------------------------------------------------------------------------
* Calculate the metrics for the alpha layer before the blend
* @update dc - 10/29/98
* @param aSrcInfo -- a pointer to a source bitmap
* @param aDestInfo -- a pointer to the destination bitmap
* @param aSrcUL -- upperleft for the source blend
* @param aMaskInfo -- a pointer to the mask bitmap
* @param aMaskUL -- upperleft for the mask bitmap
* @param aWidth -- width of the blend
* @param aHeight -- heigth of the blend
* @param aNumLines -- a pointer to number of lines to do for the blend
* @param aNumbytes -- a pointer to the number of bytes per line for the blend
* @param aSImage -- a pointer to a the bit pointer for the source
* @param aDImage -- a pointer to a the bit pointer for the destination
* @param aMImage -- a pointer to a the bit pointer for the mask
* @param aSLSpan -- number of bytes per span for the source
* @param aDLSpan -- number of bytes per span for the destination
* @param aMLSpan -- number of bytes per span for the mask
* @result PR_TRUE if calculation was succesful
*/
PRBool CalcAlphaMetrics(BITMAP *aSrcInfo,BITMAP *aDestInfo,nsPoint *ASrcUL,
BITMAP *aMapInfo,nsPoint *aMaskUL,
PRInt32 aWidth,PRInt32 aHeight,
@ -58,7 +112,6 @@ public:
PRInt32 *aNumbytes,PRUint8 **aSImage,PRUint8 **aDImage,
PRUint8 **aMImage,PRInt32 *aSLSpan,PRInt32 *aDLSpan,PRInt32 *aMLSpan);
PRInt32 CalcBytesSpan(PRUint32 aWidth,PRUint32 aBitsPixel);
/**
* Create a DIB header and bits for a bitmap
@ -77,92 +130,18 @@ public:
*/
void DeleteDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits);
void Do32Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea);
/**
* Blend two 24 bit image arrays using an 8 bit alpha mask
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void Do24BlendWithMask(PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
PRUint8 *aMImage,PRInt32 aSLSpan,PRInt32 aDLSpan,PRInt32 aMLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea);
/**
* Blend two 24 bit image arrays using a passed in blend value
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void Do24Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea);
/**
* Blend two 16 bit image arrays using a passed in blend value
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void Do16Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea);
/**
* Blend two 8 bit image arrays using an 8 bit alpha mask
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void Do8BlendWithMask(PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
PRUint8 *aMImage,PRInt32 aSLSpan,PRInt32 aDLSpan,PRInt32 aMLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea);
/**
* Blend two 8 bit image arrays using a passed in blend value
* @param aNumlines Number of lines to blend
* @param aNumberBytes Number of bytes per line to blend
* @param aSImage Pointer to beginning of the source bytes
* @param aDImage Pointer to beginning of the destination bytes
* @param aMImage Pointer to beginning of the mask bytes
* @param aSLSpan number of bytes per line for the source bytes
* @param aDLSpan number of bytes per line for the destination bytes
* @param aMLSpan number of bytes per line for the Mask bytes
* @param aBlendQuality The quality of this blend, this is for tweening if neccesary
* @param aSaveBlendArea informs routine if the area affected area will be save first
*/
void Do8Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
PRInt32 aSLSpan,PRInt32 aDLSpan,nsColorMap *aColorMap,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea);
#ifdef NGLAYOUT_DDRAW
/** --------------------------------------------------------------------------
* Lock a surface down for Direct draw
* @update mp - 10/01/98
* @param IDirectDrawSurface --
* @param DDSURFACEDESC --
* @param BITMAP --
* @param RECT --
* @param DWORD --
* @result PR_TRUE lock was succesful
*/
PRBool LockSurface(IDirectDrawSurface *aSurface, DDSURFACEDESC *aDesc, BITMAP *aBitmap, RECT *aRect, DWORD aLockFlags);
#endif
@ -176,10 +155,8 @@ public:
PRInt32 mSRowBytes;
PRInt32 mDRowBytes;
PRInt32 mSaveLS;
PRInt32 mSaveNumLines;
PRInt32 mSaveNumBytes;
PRUint8 *mSaveBytes; // place to save bits
PRUint8 *mRestorePtr; // starting area of save dst
PRUint32 mResLS; // line span for restore area