123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- #include "bltcanvas.h"
- #include <tataki/bitmap/bitmap.h>
- BltCanvas::~BltCanvas()
- {
- if (hdc == NULL) return ;
- // kill the bitmap and its DC
- SelectObject(hdc, prevbmp);
- if (ourbmp)
- {
- //GdiFlush();
- DeleteObject(hbmp);
- }
- DeleteDC(hdc);
- hdc = NULL;
- if (skinbmps)
- {
- for (int i=0;i<skinbmps->getNumItems();i++)
- skinbmps->enumItem(i)->Release();
- delete skinbmps;
- }
- if (envelope)
- envelope->Release();
- }
- BltCanvas::BltCanvas(HBITMAP bmp)
- {
- prevbmp = NULL;
- bits = NULL;
- fcoord = TRUE;
- ourbmp = FALSE;
- skinbmps = NULL;
- envelope = NULL;
- hbmp = bmp;
- ASSERT(hbmp != NULL);
- // create tha DC
- hdc = CreateCompatibleDC(NULL);
- prevbmp = (HBITMAP)SelectObject(hdc, hbmp);
- }
- BltCanvas::BltCanvas()
- {
- hbmp = NULL;
- prevbmp = NULL;
- bits = NULL;
- fcoord = TRUE;
- ourbmp = FALSE;
- bpp = 32; // TODO: benski> pass as parameter?
- skinbmps = NULL;
- envelope = NULL;
- hdc = CreateCompatibleDC(NULL);
- }
- BltCanvas::BltCanvas(int w, int h, HWND wnd, int nb_bpp/*, unsigned char *pal, int palsize*/)
- {
- hbmp = NULL;
- prevbmp = NULL;
- bits = NULL;
- fcoord = TRUE;
- ourbmp = FALSE;
- bpp = nb_bpp;
- skinbmps = NULL;
- envelope = NULL;
- hdc = CreateCompatibleDC(NULL);
- AllocBitmap(w,h,nb_bpp);
- if (hbmp)
- {
- // create tha DC
-
- if (!hdc) {
- // int x = GetLastError();
- }
- prevbmp = (HBITMAP)SelectObject(hdc, hbmp);
- }
- }
- void BltCanvas::AllocBitmap(int w, int h, int nb_bpp)
- {
- ASSERT(!hbmp);
- ASSERT(w != 0 && h != 0);
- if (w == 0) w = 1;
- if (h == 0) h = 1;
- BITMAPINFO bmi;
- MEMZERO(&bmi, sizeof(BITMAPINFO));
- //bmi.bmiHeader.biClrUsed = 0; // we memzero above, no need
- //bmi.bmiHeader.biClrImportant = 0; // we memzero above, no need
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = ABS(w);
- bmi.bmiHeader.biHeight = -ABS(h);
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = nb_bpp;
- bmi.bmiHeader.biCompression = BI_RGB;
- //bmi.bmiHeader.biSizeImage = 0; // we memzero above, no need
- //bmi.bmiHeader.biXPelsPerMeter = 0; // we memzero above, no need
- //bmi.bmiHeader.biYPelsPerMeter = 0; // we memzero above, no need
- //GdiFlush();
- hbmp = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
-
- if (hbmp == NULL)
- {
- return ;
- }
-
- ourbmp=TRUE;
- GetObject(hbmp, sizeof(BITMAP), &bm);
- width = bm.bmWidth;
- height = ABS(bm.bmHeight);
- pitch = bm.bmWidthBytes;
- }
- void *BltCanvas::getBits()
- {
- return bits;
- }
- HBITMAP BltCanvas::getBitmap()
- {
- return hbmp;
- }
- SkinBitmap *BltCanvas::getSkinBitmap()
- {
- // make a SkinBitmap envelope
- if (!envelope)
- envelope = new SkinBitmap(getBitmap(), getHDC(), 1, getBits());
- // do not delete envelope, it's deleted in destructor
- return envelope;
- }
- SkinBitmap *BltCanvas::makeSkinBitmap()
- {
- // make a clone of the bitmap - JF> what was that crap about envelopes?
- SkinBitmap *clone = new SkinBitmap(getBitmap(), getHDC(), 1);
- if (!skinbmps)
- skinbmps = new PtrList<SkinBitmap>;
- skinbmps->addItem(clone);
- return clone;
- }
- void BltCanvas::disposeSkinBitmap(SkinBitmap *b)
- {
- if (skinbmps->haveItem(b))
- {
- skinbmps->removeItem(b);
- b->Release();
- }
- else
- {
- DebugString("disposeSkinBitmap called on unknown pointer, you should call it from the object used to makeSkinBitmap()\n");
- }
- }
- void BltCanvas::fillBits(COLORREF color)
- {
- if (bpp == 32)
- { // clear out the bits
- DWORD *dwbits = (DWORD *)bits;
- MEMFILL<DWORD>(dwbits, color, bm.bmWidth * bm.bmHeight);
- }
- }
- void BltCanvas::vflip(int vert_cells)
- {
- ASSERT(bits != NULL);
- // BITMAP bm;
- // int r = GetObject(hbmp, sizeof(BITMAP), &bm);
- // if (r == 0) return;
- int w = bm.bmWidth, h = bm.bmHeight;
- int bytes = 4 * w;
- __int8 *tmpbuf = (__int8 *)MALLOC(bytes);
- if (tmpbuf)
- {
- int cell_h = h / vert_cells;
- for (int j = 0; j < vert_cells; j++)
- for (int i = 0; i < cell_h / 2; i++)
- {
- char *p1, *p2;
- p1 = (__int8 *)bits + bytes * i + (j * cell_h * bytes);
- p2 = (__int8 *)bits + bytes * ((cell_h - 1) - i) + (j * cell_h * bytes);
- if (p1 == p2) continue;
- MEMCPY(tmpbuf, p1, bytes);
- MEMCPY(p1, p2, bytes);
- MEMCPY(p2, tmpbuf, bytes);
- }
- FREE(tmpbuf);
- }
- }
- void BltCanvas::hflip(int hor_cells)
- {
- ASSERT(bits != NULL);
- // todo: optimize
- int w = bm.bmWidth, h = bm.bmHeight;
- for (int i = 0;i < hor_cells;i++)
- for (int x = 0;x < w / 2 / hor_cells;x++)
- for (int y = 0;y < h;y++)
- {
- int *p = ((int *)bits) + x + y * w + (i * w / hor_cells);
- int *d = ((int *)bits) + ((w / hor_cells) - x) + y * w + (i * w / hor_cells) - 1;
- int t = *p;
- *p = *d;
- *d = t;
- }
- }
- void BltCanvas::maskColor(COLORREF from, COLORREF to)
- {
- int n = bm.bmWidth * bm.bmHeight;
- //GdiFlush();
- DWORD *b = (DWORD *)getBits();
- from &= 0xffffff;
- while (n--)
- {
- if ((*b & 0xffffff) == from)
- {
- *b = to;
- }
- else *b |= 0xff000000; // force all other pixels non masked
- b++;
- }
- }
- void BltCanvas::makeAlpha(int newalpha)
- {
- int w, h;
- getDim(&w, &h, NULL);
- premultiply((ARGB32 *)getBits(), w*h, newalpha);
- }
- #if 0
- void BltCanvas::premultiply(ARGB32 *m_pBits, int nwords, int newalpha)
- {
- if (newalpha == -1)
- {
- for (; nwords > 0; nwords--, m_pBits++)
- {
- unsigned char *pixel = (unsigned char *)m_pBits;
- unsigned int alpha = pixel[3];
- if (alpha == 255) continue;
- pixel[0] = (pixel[0] * alpha) >> 8; // blue
- pixel[1] = (pixel[1] * alpha) >> 8; // green
- pixel[2] = (pixel[2] * alpha) >> 8; // red
- }
- }
- else
- {
- for (; nwords > 0; nwords--, m_pBits++)
- {
- unsigned char *pixel = (unsigned char *)m_pBits;
- pixel[0] = (pixel[0] * newalpha) >> 8; // blue
- pixel[1] = (pixel[1] * newalpha) >> 8; // green
- pixel[2] = (pixel[2] * newalpha) >> 8; // red
- pixel[3] = (pixel[3] * newalpha) >> 8; // alpha
- }
- }
- }
- #endif
- // benski> this may not be completely safe. it's meant for skinbitmap::blittorect
- // it doesn't take into account skin bitmaps, enveloped bitmaps, or any other things like that
- void BltCanvas::DestructiveResize(int w, int h, int nb_bpp)
- {
- if (hdc != NULL)
- {
- SelectObject(hdc, prevbmp);
- prevbmp=0;
- }
- if (ourbmp && hbmp)
- {
- DeleteObject(hbmp);
- hbmp=NULL;
- ourbmp=FALSE;
- }
- // create tha DC
- if (hdc == NULL)
- hdc = CreateCompatibleDC(NULL);
- AllocBitmap(w,h,nb_bpp);
- prevbmp = (HBITMAP)SelectObject(hdc, hbmp);
- if (envelope) envelope->Release();
- envelope=0;
- }
|