#ifndef __DIBSURFHPP__ #define __DIBSURFHPP__ //******************************************************************* // // DESCRIPTION: Header file for CDIBSurface class // // AUTHOR: Andrew Farrier // // SourceSafe Version: $Revision: 68 $ // // HISTORY: Created 11/15/95 // //******************************************************************* #include #include #include #pragma warning (disable : 4786) struct DCData { HDC thedc; HBITMAP oldbits; DCData (void) { thedc = NULL; oldbits = NULL; } DCData (HDC p1,HBITMAP p2) { thedc = p1; oldbits = p2; } ~DCData (void) { thedc = NULL; oldbits = NULL; } DCData (const DCData& p1) { thedc = p1.thedc; oldbits = p1.oldbits; } DCData& operator= (const DCData& p1) { thedc = p1.thedc; oldbits = p1.oldbits; return *this; } }; //**************************************************************** // // Function Name: clamp // // Description: Will clamp x to be between min and max exclusive // // Returns: clamped value of x // //**************************************************************** template inline type clamp (const type& min,const type& x,const type& max) { if (x < min) return min; if (x>max) return max; return x; } //**************************************************************** // // Function Name: RGBQUADtoCOLORREF // // Description: Will convert from an RGBQUAD to a COLORREF // // Returns: the COLORREF equal to the RGBQUAD // //**************************************************************** inline COLORREF RGBQUADtoCOLORREF (RGBQUAD value) { int red,green,blue; COLORREF toret; red = value.rgbRed; green = value.rgbGreen; blue = value.rgbBlue; toret = RGB (red,green,blue); return toret; } //**************************************************************** // // Function Name: RGBtoCOLORREF // // Description: Will convert from an RGB packed int to a COLORREF // int is in the form 0x00RRGGBB // // Returns: the COLORREF equal to the packed value // //**************************************************************** inline COLORREF RGBtoCOLORREF (int value) { int red,green,blue; COLORREF toret; red = (value>>16) & 0xff; green = (value>>8) & 0xff; blue = value&0xff; toret = RGB (red,green,blue); return toret; } //**************************************************************** // // Function Name: COLORREFtoRGBQUAD // // Description: Will convert from a COLORREF value to an RGBQUAD // // Returns: the RGBQUAD equal to the COLORREF // //**************************************************************** inline RGBQUAD COLORREFtoRGBQUAD (COLORREF value) { RGBQUAD toret; toret.rgbRed = (value >> 16) & 0xff; toret.rgbGreen = (value >> 8) & 0xff; toret.rgbBlue = value & 0xff; return toret; } class CDIBSurface { private: static std::vector *m_FreeDC; static std::vector *m_AllDCs; static int m_DCStackRefCount; struct FloodData { unsigned char *mem; CPoint where; FloodData (unsigned char *p1,CPoint p2) {mem = p1;where = p2;} }; bool Create1BitMask (COLORREF colorref); bool Create4BitMask (COLORREF colorref); bool Create8BitMask (COLORREF colorref); bool Create16BitMask (COLORREF colorref); bool Create24BitMask (COLORREF colorref); int FloodFill24 (const CPoint& start,const COLORREF color); bool AlphaBlt16 (const int x,const int y,const int width,const int height,const CDIBSurface *src,const CDIBSurface *alpha,const int srcx,const int srcy,const int alphasrcx,const int alphasrcy); bool AlphaBlt24 (const int x,const int y,const int width,const int height,const CDIBSurface *src,const CDIBSurface *alpha,const int srcx,const int srcy,const int alphasrcx,const int alphasrcy); bool ColorBlt16 (const int x,const int y,const int width,const int height,const CDIBSurface* src,const int srcx,const int srcy,const COLORREF color,bool addred=true,bool addgreen=true,bool addblue=true,CDIBSurface *altmask=NULL); bool ColorBlt24 (const int x,const int y,const int width,const int height,const CDIBSurface* src,const int srcx,const int srcy,const COLORREF color,bool addred=true,bool addgreen=true,bool addblue=true,CDIBSurface *altmask=NULL); bool GrayBlt16 (const int x,const int y,const int width,const int height,const CDIBSurface* srcdib,const int srcx,const int srcy,CDIBSurface *altmask=NULL); bool GrayBlt24 (const int x,const int y,const int width,const int height,const CDIBSurface* srcdib,const int srcx,const int srcy,CDIBSurface *altmask=NULL); bool MultBlt16 (const int x,const int y,const int width,const int height,const CDIBSurface* src,const int srcx,const int srcy,const float red,const float green,const float blue,CDIBSurface *altmask=NULL); bool MultBlt24 (const int x,const int y,const int width,const int height,const CDIBSurface* src,const int srcx,const int srcy,const float red,const float green,const float blue,CDIBSurface *altmask=NULL); bool Convert24to16 (void); bool SetupLoadedBitmap (HBITMAP hbm); BITMAPINFO *AllocBitmapInfo (void) const; // delete when done with it void ClearData (void); struct DIBData { CDIBSurface *m_Mask; HDC m_SelectedDC; int m_SelectedDCRefCount; bool m_AllocedDC; HBITMAP m_OldBitmap; HBITMAP m_BackBits; // may be NULL, call GetBitmap() if you need to create it // HBITMAP m_OldBits; unsigned char *m_Data; unsigned char *m_UpperLeft; UINT m_Width,m_Height; UINT m_BitDepth; int m_Pitch; bool m_OwnPalette; bool m_UseMask; }; protected: UINT *m_RefCount; DIBData *m_DIBData; public: CDIBSurface (void); CDIBSurface (UINT Width,UINT Height,UINT BitDepth); CDIBSurface (const CDIBSurface&); CDIBSurface& operator= (const CDIBSurface&); ~CDIBSurface (void); bool Create (UINT Width,UINT Height,UINT BitDepth=0); void Destroy (void); bool operator== (const CDIBSurface& param) { if(!param.IsValid ()) return false; if(!IsValid ()) return false; ASSERT (m_DIBData); ASSERT (param.m_DIBData); return param.m_DIBData->m_Data == m_DIBData->m_Data; } HDC GetDC (void); HDC GetDC (void) const; void ReleaseDC (HDC) const; void UseDC (HDC); // These are not really consts, but behave like that (the state of the object // is not the same on return, but it has the same functionality). This was needed // to keep GetDC() const happy. HBITMAP GetBitmap (void) const; // actually creates the DIB section (if needed) void ReleaseBitmap (void) const; // call to free up GDI resources unsigned char *CDIBSurface::GetMem (void) { ASSERT (m_DIBData); if(!m_DIBData->m_Data) return NULL; if(!GdiFlush ()) return NULL; return m_DIBData->m_UpperLeft; } unsigned char *GetMem( int x, int y ); unsigned char *GetData( void ) { ASSERT( m_DIBData ); if( !(m_DIBData->m_Data && GdiFlush()) ) return( NULL ); return( m_DIBData->m_Data ); } const unsigned char *GetData( void ) const { ASSERT( m_DIBData ); if( !(m_DIBData->m_Data && GdiFlush()) ) return( NULL ); return( m_DIBData->m_Data ); } bool ReleaseMem (unsigned char *) { return (GdiFlush ()==TRUE);} const unsigned char *CDIBSurface::GetMem (void) const { ASSERT (m_DIBData); if(!m_DIBData->m_Data) return NULL; if(!GdiFlush ()) return NULL; return m_DIBData->m_UpperLeft; } void ReleaseMem (const unsigned char *) const {} int GetPitch (void) const { ASSERT (m_DIBData); return m_DIBData->m_Pitch; } int GetLocation (UINT x,UINT y) const { int tx,ty; ASSERT (m_DIBData); ASSERT (((UINT) x) < m_DIBData->m_Width); ASSERT (((UINT) y) < m_DIBData->m_Height); switch(m_DIBData->m_BitDepth) { case 1: x>>=3; break; case 4: x>>=1; break; case 8: break; case 16: x<<=1; break; case 24: x *= 3; break; default: ASSERT (false); break; } tx = (int) x; ty = (int) y; return((ty*m_DIBData->m_Pitch)+tx); } DWORD GetValue (UINT x,UINT y) const { const unsigned char *mem; DWORD toret; ASSERT (m_DIBData); ASSERT (((UINT) x) < m_DIBData->m_Width); ASSERT (((UINT) y) < m_DIBData->m_Height); mem = GetMem (); mem += GetLocation (x,y); toret = 0; switch(m_DIBData->m_BitDepth) { case 1: toret = (*mem >> ((~x)&0x07)) & 0x01; //lint !e504 break; case 4: if(x & 0x01) toret = *mem & 0x0f; else toret = *mem>>4; break; case 8: toret = *mem; break; case 16: toret = (*(mem+1)<<8) + *(mem); break; case 24: toret = ((*mem)<<16)+ ((*(mem+1))<<8) + (*(mem+2)); break; default: ASSERT (false); break; } ReleaseMem (mem); return toret; } void SetValue (UINT x,UINT y,DWORD value) { unsigned char *mem; DWORD toret; ASSERT (m_DIBData); ASSERT (((UINT) x) < m_DIBData->m_Width); ASSERT (((UINT) y) < m_DIBData->m_Height); mem = GetMem (); mem += GetLocation (x,y); toret = 0; switch(m_DIBData->m_BitDepth) { case 1: if (value & 0x01) *mem |= (0x01 << ((~x)&0x07)); else *mem &= ~(0x01 << ((~x)&0x07)); break; case 4: value &= 0x0f; if(x & 0x01) { *mem &= 0xf0; *mem |= value; } else { value <<= 4; *mem &= 0x0f; *mem |= value; } break; case 8: value &= 0xff; *mem = value; break; case 16: value &= 0xffff; *(mem+1) = value&0xff; *(mem) = ((value>>8) & 0xff); break; case 24: value &= 0xffffff; *(mem+2) = value&0xff; *(mem+1) = ((value>>8) & 0xff); *(mem) = ((value>>16) & 0xff); break; default: ASSERT (false); break; } ReleaseMem (mem); } COLORREF GetColor (UINT x,UINT y) const; void SetColor (UINT x,UINT y,COLORREF color); void SetColor( COLORREF color ); bool Fill (const CRect *therect,const COLORREF colorref=0); bool Fill (const int left,const int top,const int right,const int bottom,const COLORREF colorref=0) {return Fill (&CRect(left,top,right,bottom),colorref);} //lint !e50 bool Fill (const CPoint& topleft,const CPoint& botright,const COLORREF colorref=0) {return Fill (&CRect (topleft,botright),colorref);} //lint !e50 bool Fill (const CRect& therect,const COLORREF colorref=0) {return Fill (&therect,colorref);} bool FillHatchBrush (const CRect *therect, int stockHatchBrushStyle,const COLORREF colorref=0); bool FillHatchBrush (const int left,const int top,const int right, const int bottom,int stockHatchBrushStyle,const COLORREF colorref=0) {return FillHatchBrush (&CRect(left,top,right,bottom), stockHatchBrushStyle, colorref);} //lint !e50 bool HighlightFrame (const CRect& therect,bool up); // light is from upper left void HLine( int x1, int x2, int y, COLORREF crColor ); bool Blt (int x,int y,int width,int height,const CDIBSurface *src,int srcx,int srcy,DWORD rop=SRCCOPY); bool Blt (const CPoint& loc,const CSize& size,const CDIBSurface *src,const CPoint& srcloc,DWORD rop=SRCCOPY) {return Blt (loc.x,loc.y,size.cx,size.cy,src,srcloc.x,srcloc.y,rop);} bool Blt (const CRect& loc,const CDIBSurface *src,const CPoint& srcloc,DWORD rop=SRCCOPY) {return Blt (loc.left,loc.top,loc.Width(),loc.Height(),src,srcloc.x,srcloc.y,rop);} bool Blt (int x,int y,int width,int height,const CDIBSurface& src,int srcx,int srcy,DWORD rop=SRCCOPY) {return Blt (x,y,width,height,&src,srcx,srcy,rop);} bool Blt (const CPoint& loc,const CSize& size,const CDIBSurface& src,const CPoint& srcloc,DWORD rop=SRCCOPY) {return Blt (loc.x,loc.y,size.cx,size.cy,&src,srcloc.x,srcloc.y,rop);} bool Blt (const CRect& loc,const CDIBSurface& src,const CPoint& srcloc,DWORD rop=SRCCOPY) {return Blt (loc.left,loc.top,loc.Width(),loc.Height(),&src,srcloc.x,srcloc.y,rop);} bool Blt (int x,int y,int width,int height,HDC src,int srcx,int srcy,DWORD rop) { ASSERT (m_DIBData); ASSERT (src); ASSERT (IsValid ()); if((!src) || (!IsValid())) return false; HDC dc; bool toret; dc = GetDC (); toret = (::BitBlt (dc,x,y,width,height,src,srcx,srcy,rop)==TRUE); ReleaseDC (dc); return toret; } // these two are functionally equivalent to their normal versions but do not // perform format or palette conversions and do not use any GDI resources bool BltNonGDI (int x,int y,int width,int height,const CDIBSurface& src,int srcx,int srcy); bool MaskBltNonGDI (int x,int y,int width,int height,const CDIBSurface& src,int srcx,int srcy); bool MaskBlt (const int x,const int y,const int width,const int height,const HDC src,const HDC mask,const int srcx,const int srcy); bool MaskBlt (const int x,const int y,const int width,const int height,const CDIBSurface *src,const int srcx,const int srcy); bool AlphaBlt (const int x,const int y,const int width,const int height,const CDIBSurface *src,const CDIBSurface *alpha,const int srcx,const int srcy,const int alphasrcx=-1,const int alphasrcy=-1); bool AlphaBlt (const CRect& loc,const CDIBSurface *src,const CDIBSurface *alpha,const CPoint& srcloc) { return AlphaBlt (loc.left,loc.top,loc.Width (),loc.Height(),src,alpha,srcloc.x,srcloc.y); } bool AlphaBlt (const CRect& loc,const CDIBSurface *src,const CDIBSurface *alpha,const CPoint& srcloc,const CPoint& alphaloc) { return AlphaBlt (loc.left,loc.top,loc.Width (),loc.Height(),src,alpha,srcloc.x,srcloc.y,alphaloc.x,alphaloc.y); } bool AlphaBlt (const int x,const int y,const int width,const int height,const CDIBSurface& src,const CDIBSurface& alpha,const int srcx,const int srcy,const int alphasrcx=-1,const int alphasrcy=-1) { return AlphaBlt (x,y,width,height,&src,&alpha,srcx,srcy,alphasrcx,alphasrcy); } bool AlphaBlt (const CRect& loc,const CDIBSurface& src,const CDIBSurface& alpha,const CPoint& srcloc) { return AlphaBlt (loc.left,loc.top,loc.Width (),loc.Height(),&src,&alpha,srcloc.x,srcloc.y); } bool AlphaBlt (const CRect& loc,const CDIBSurface& src,const CDIBSurface& alpha,const CPoint& srcloc,const CPoint& alphaloc) { return AlphaBlt (loc.left,loc.top,loc.Width (),loc.Height(),&src,&alpha,srcloc.x,srcloc.y,alphaloc.x,alphaloc.y); } bool RotateBlt( int left, int top, int right, int bottom, const CDIBSurface& src, int x, int y, int ang ); bool RotateBlt( const CRect& loc, const CDIBSurface& src, const CPoint& srcloc, int ang ) { return( RotateBlt( loc.left, loc.top, loc.right, loc.bottom, src, srcloc.x, srcloc.y, ang ) ); } bool TransparentBlt( int left, int top, int right, int bottom, const CDIBSurface& src, int x, int y, const COLORREF bgClr ); bool TransparentBlt( const CRect& loc, const CDIBSurface& src, const CPoint& srcloc, const COLORREF bgClr ) { return( TransparentBlt( loc.left, loc.top, loc.right, loc.bottom, src, srcloc.x, srcloc.y, bgClr ) ); } bool ColorBlt (const int x,const int y,const int width,const int height,const CDIBSurface* src,const int srcx,const int srcy,const COLORREF color,bool addred=true,bool addgreen=true,bool addblue=true,CDIBSurface *altmask=NULL); bool ColorBlt (const CRect& loc,const CDIBSurface* src,const CPoint& srcloc,const COLORREF color,bool addred=true,bool addgreen=true,bool addblue=true,CDIBSurface *altmask=NULL) { return ColorBlt (loc.left,loc.top,loc.Width (),loc.Height (),src,srcloc.x,srcloc.y,color,addred,addgreen,addblue,altmask); } bool GrayBlt (const int x,const int y,const int width,const int height,const CDIBSurface* src,const int srcx,const int srcy, CDIBSurface *altmask=NULL); bool MultBlt (const int x,const int y,const int width,const int height,const CDIBSurface* src,const int srcx,const int srcy,const float red,const float green,const float blue,CDIBSurface *altmask=NULL); bool MultBlt (const CRect& loc,const CDIBSurface* src,const CPoint& srcloc,const float red,const float green,const float blue,CDIBSurface *altmask=NULL) { return MultBlt (loc.left,loc.top,loc.Width (),loc.Height (),src,srcloc.x,srcloc.y,red,green,blue,altmask); } bool SetClipArea (HRGN newcliparea) { return false; /* ASSERT (m_DIBData);if(SelectClipRgn (m_DIBData->m_BackDC,newcliparea) == ERROR) return false;return true;*/} bool StretchBlt (const CRect& loc,const CDIBSurface *src,const CRect& srcloc,DWORD rop=SRCCOPY) {return StretchBlt (loc.left,loc.top,loc.Width(),loc.Height(),src,srcloc.left,srcloc.top,srcloc.Width(),srcloc.Height(),rop);} bool StretchBlt (const CRect& loc,const CDIBSurface& src,const CRect& srcloc,DWORD rop=SRCCOPY) {return StretchBlt (loc.left,loc.top,loc.Width(),loc.Height(),&src,srcloc.left,srcloc.top,srcloc.Width(),srcloc.Height(),rop);} bool StretchBlt (int x,int y,int width,int height,const CDIBSurface *src,int srcx,int srcy,int srcwidth,int srcheight,DWORD rop) { ASSERT (m_DIBData); ASSERT (src); ASSERT (IsValid ()); if((!src) || (!IsValid())) return false; HDC dc1,dc2; bool toret; dc1 = GetDC (); dc2 = src->GetDC (); ASSERT (dc1 && dc2); toret = (::StretchBlt (dc1,x,y,width,height,dc2,srcx,srcy,srcwidth,srcheight,rop)==TRUE); ReleaseDC (dc1); src->ReleaseDC (dc2); return toret; } bool StretchBlt (int x,int y,int width,int height,HDC src,int srcx,int srcy,int srcwidth,int srcheight,DWORD rop) { ASSERT (m_DIBData); ASSERT (src); ASSERT (IsValid ()); if((!src) || (!IsValid())) return false; HDC dc; bool toret; dc = GetDC (); toret = (::StretchBlt (dc,x,y,width,height,src,srcx,srcy,srcwidth,srcheight,rop)==TRUE); ReleaseDC (dc); return toret; } int FloodFill (const CPoint& start,const COLORREF color); bool SetSize (UINT cx,UINT cy,UINT BitDepth) { ASSERT (m_DIBData);Destroy (); return Create (cx,cy,BitDepth);} UINT GetWidth (void) const { ASSERT (m_DIBData);return m_DIBData->m_Width;} UINT GetHeight (void) const { ASSERT (m_DIBData);return m_DIBData->m_Height;} UINT GetBitDepth (void) const { ASSERT (m_DIBData);return m_DIBData->m_BitDepth;} CSize GetSize( void ) const { ASSERT (m_DIBData); return CSize( m_DIBData->m_Width, m_DIBData->m_Height ); } CDIBSurface* Mask (void) { ASSERT (m_DIBData);return m_DIBData->m_Mask;} const CDIBSurface* Mask (void) const { ASSERT (m_DIBData);return m_DIBData->m_Mask;} bool UseMask (void) const { ASSERT (m_DIBData);return m_DIBData->m_UseMask;} void UseMask (bool newflag) { ASSERT (m_DIBData);if((!newflag) || ((m_DIBData->m_Mask) && (m_DIBData->m_Mask->IsValid ()))) m_DIBData->m_UseMask = newflag;} bool IsValid (void) const { ASSERT (m_DIBData);return m_DIBData->m_Data != NULL;} bool CopyBitmap(HBITMAP hbm,int x,int y,int dx,int dy); bool CalcMask (COLORREF colorref); bool CalcMask (const std::vector& colors); bool CalcMask (void); bool DestroyMask (void); bool ConvertBitDepth (int newdepth); bool ConvertToGray (void); // converts contents to 8-bit with gray palette //white is transparent WORD ConvertColorToWord( COLORREF crColor ) { return( WORD( ((0xf80000 & crColor) >> 19) | ((0xf800 & crColor) >> 6) | ((0xf8 & crColor) << 7) ) ); } RGBTRIPLE ConvertColorToTriple( COLORREF crColor ) { RGBTRIPLE rgb = { (0xff & crColor) >> 16, 0xff & (crColor >> 8), 0xff & crColor }; return( rgb ); } DWORD ConvertColorToLong( COLORREF crColor ) { return( DWORD( 0x00ffffff & crColor ) ); } COLORREF ConvertWordToColor( WORD wColor ) { return( RGB( (0x7c00 & wColor) >> 7, (0x03e0 & wColor) >> 2, (0x1f & wColor) << 3 ) ); } COLORREF ConvertTripleToColor( RGBTRIPLE rgbColor ) { return( RGB( rgbColor.rgbtRed, rgbColor.rgbtGreen, rgbColor.rgbtBlue ) ); } COLORREF ConvertLongToColor( DWORD dwColor ) { return( RGB( 0xff & dwColor, (0xff00 & dwColor) >> 8, (0xff0000 & dwColor) >> 16 ) ); } void ClearOutsideMask (void) // clears any part of the bitmap that is in the transparent part of the mask { if (Mask()) Blt (0, 0, GetWidth(), GetHeight(), Mask(), 0, 0, 0x00220326); // DSna } bool SplitRef (void); void AddRef (void) { ASSERT (m_RefCount); (*m_RefCount)++; if(!m_DCStackRefCount) { m_AllDCs = new std::vector; m_FreeDC = new std::vector; } m_DCStackRefCount++; } bool Release (void) { ASSERT (m_RefCount); ASSERT (*m_RefCount); ASSERT (m_DIBData); m_DCStackRefCount--; if(!m_DCStackRefCount) { std::vector::iterator iter; ASSERT (m_FreeDC->size () == m_AllDCs->size ()); iter = m_AllDCs->begin (); while(iter != m_AllDCs->end ()) { DeleteDC (iter->thedc); iter++; } delete m_FreeDC; delete m_AllDCs; m_FreeDC = NULL; m_AllDCs = NULL; } (*m_RefCount)--; if (!(*m_RefCount)) { Destroy (); delete m_RefCount; delete m_DIBData; m_RefCount = NULL; m_DIBData = NULL; return false; } return true; } #if 0 static void *operator new (size_t size) { void *temp; temp = new BYTE[size]; if(!temp) { return NULL; } memset (temp,0,size); ((CDIBSurface *) temp)->m_RefCount = 1; ((CDIBSurface *) temp)->m_Alloced = true; return temp; } static void operator delete (void *,size_t) { } #endif }; bool MaskBlt (HDC dest,const int x,const int y,const int width,const int height,const HDC src,const HDC mask,const int srcx,const int srcy); bool MaskBlt (HDC dest,const int x,const int y,const int width,const int height,const HDC src,const HDC mask,const int srcx,const int srcy,const int maskx,const int masky); bool MaskBlt (HDC dest,const int x,const int y,const int width,const int height,const CDIBSurface *src,const int srcx,const int srcy); inline bool MaskBlt (HDC dest,const CPoint& loc,const CSize& size,const CDIBSurface *src,const CPoint& srcloc) {return MaskBlt (dest,loc.x,loc.y,size.cx,size.cy,src,srcloc.x,srcloc.y);} inline bool MaskBlt (HDC dest,const CRect& loc,const CDIBSurface *src,const CPoint& srcloc) {return MaskBlt (dest,loc.left,loc.top,loc.Width(),loc.Height(),src,srcloc.x,srcloc.y);} #endif