diff --git a/mozilla/gfx/src/makefile.win b/mozilla/gfx/src/makefile.win index 16edaddc57f..fc22fdc77cd 100644 --- a/mozilla/gfx/src/makefile.win +++ b/mozilla/gfx/src/makefile.win @@ -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 \ diff --git a/mozilla/gfx/src/nsBlender.cpp b/mozilla/gfx/src/nsBlender.cpp new file mode 100644 index 00000000000..9b1ac7acd0b --- /dev/null +++ b/mozilla/gfx/src/nsBlender.cpp @@ -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>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>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;iIndex[(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<> 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=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; +} + +//------------------------------------------------------------ + diff --git a/mozilla/gfx/src/nsBlender.h b/mozilla/gfx/src/nsBlender.h new file mode 100644 index 00000000000..743688ca614 --- /dev/null +++ b/mozilla/gfx/src/nsBlender.h @@ -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 \ No newline at end of file diff --git a/mozilla/gfx/src/nsIBlender.h b/mozilla/gfx/src/nsIBlender.h index 9635b78c824..225ec9d9e3a 100644 --- a/mozilla/gfx/src/nsIBlender.h +++ b/mozilla/gfx/src/nsIBlender.h @@ -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; diff --git a/mozilla/gfx/src/windows/makefile.win b/mozilla/gfx/src/windows/makefile.win index 084d90a7b3a..7d76bfe1218 100644 --- a/mozilla/gfx/src/windows/makefile.win +++ b/mozilla/gfx/src/windows/makefile.win @@ -45,6 +45,7 @@ OBJS = \ $(NULL) LINCS= \ + -I..\ -I$(PUBLIC)\raptor \ -I$(PUBLIC)\xpcom \ -I$(PUBLIC)\dom \ diff --git a/mozilla/gfx/src/windows/nsBlenderWin.cpp b/mozilla/gfx/src/windows/nsBlenderWin.cpp index 30c419eecb9..2f03068c838 100644 --- a/mozilla/gfx/src/windows/nsBlenderWin.cpp +++ b/mozilla/gfx/src/windows/nsBlenderWin.cpp @@ -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>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>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;iIndex[(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<> 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=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; -} - -//------------------------------------------------------------ - diff --git a/mozilla/gfx/src/windows/nsBlenderWin.h b/mozilla/gfx/src/windows/nsBlenderWin.h index 26ecf7c50b8..50b78ef3452 100644 --- a/mozilla/gfx/src/windows/nsBlenderWin.h +++ b/mozilla/gfx/src/windows/nsBlenderWin.h @@ -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