/* * Copyright (c) 2004 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /* $Id$ */ #include #include hashtable * h_bitmaps; khm_int32 hash_id(const void *p) { #pragma warning(push) #pragma warning(disable: 4311) return (khm_int32) p; #pragma warning(pop) } khm_int32 comp_id(const void *p1, const void *p2) { #pragma warning(push) #pragma warning(disable: 4311) return ((khm_int32)p1) - ((khm_int32)p2); #pragma warning(pop) } void del_ref_object(const void *k, void * data) { DeleteObject((HGDIOBJ) data); } KHMEXP void KHMAPI khui_init_rescache(void) { h_bitmaps = hash_new_hashtable(127, hash_id, comp_id, NULL, del_ref_object); } KHMEXP void KHMAPI khui_exit_rescache(void) { hash_del_hashtable(h_bitmaps); } KHMEXP void KHMAPI khui_cache_bitmap(UINT id, HBITMAP hbm) { hash_add(h_bitmaps, (void *)(size_t) id, (void *) hbm); } KHMEXP HBITMAP KHMAPI khui_get_cached_bitmap(UINT id) { return (HBITMAP) hash_lookup(h_bitmaps, (void *)(size_t) id); } KHMEXP khui_ilist * KHMAPI khui_create_ilist(int cx, int cy, int n, int ng, int opt) { BITMAPV5HEADER head; HDC hdc; khui_ilist * il = malloc(sizeof(khui_ilist)); il->cx = cx; il->cy = cy; il->n = n; il->ng = ng; il->nused = 0; hdc = GetDC(NULL); head.bV5Size = sizeof(head); head.bV5Width = cx * n; head.bV5Height = cy; head.bV5Planes = 1; head.bV5BitCount = 24; head.bV5Compression = BI_RGB; head.bV5SizeImage = 0; head.bV5XPelsPerMeter = 2835; head.bV5YPelsPerMeter = 2835; head.bV5ClrUsed = 0; head.bV5ClrImportant = 0; head.bV5AlphaMask = 0; head.bV5CSType = LCS_WINDOWS_COLOR_SPACE; head.bV5Intent = LCS_GM_GRAPHICS; head.bV5ProfileData = 0; head.bV5ProfileSize = 0; head.bV5Reserved = 0; il->img = CreateDIBitmap(hdc, (BITMAPINFOHEADER *) &head, 0, NULL, NULL, DIB_RGB_COLORS); il->mask = CreateBitmap(cx * n, cy, 1, 1, NULL); il->idlist = malloc(sizeof(int) * n); return il; } KHMEXP BOOL KHMAPI khui_delete_ilist(khui_ilist * il) { DeleteObject(il->img); DeleteObject(il->mask); free(il->idlist); free(il); return TRUE; } KHMEXP int KHMAPI khui_ilist_add_masked_id(khui_ilist *il, HBITMAP hbm, COLORREF cbkg, int id) { int idx; idx = khui_ilist_add_masked(il,hbm,cbkg); if(idx >= 0) { il->idlist[idx] = id; } return idx; } KHMEXP int KHMAPI khui_ilist_lookup_id(khui_ilist *il, int id) { int i; for(i=0;inused;i++) { if(il->idlist[i] == id) return i; } return -1; } KHMEXP int KHMAPI khui_ilist_add_masked(khui_ilist * il, HBITMAP hbm, COLORREF cbkg) { HDC dcr,dci,dct,dcb; HBITMAP hb_oldb, hb_oldi, hb_oldt; int sx, i; int x,y; dcr = GetDC(NULL); dci = CreateCompatibleDC(dcr); dct = CreateCompatibleDC(dcr); dcb = CreateCompatibleDC(dcr); ReleaseDC(NULL,dcr); i = il->nused++; il->idlist[i] = -1; sx = i * il->cx; hb_oldb = SelectObject(dcb, hbm); hb_oldi = SelectObject(dci, il->img); hb_oldt = SelectObject(dct, il->mask); SetBkColor(dct, RGB(0,0,0)); SetTextColor(dct, RGB(255,255,255)); BitBlt(dci, sx, 0, il->cx, il->cy, dcb, 0, 0, SRCCOPY); for(y=0;y < il->cy; y++) for(x=0; xcx; x++) { COLORREF c = GetPixel(dcb, x, y); if(c==cbkg) { SetPixel(dct, sx + x, y, RGB(255,255,255)); SetPixel(dci, sx + x, y, RGB(0,0,0)); } else { SetPixel(dct, sx + x, y, RGB(0,0,0)); } } SelectObject(dct, hb_oldt); SelectObject(dci, hb_oldi); SelectObject(dcb, hb_oldb); DeleteDC(dcb); DeleteDC(dct); DeleteDC(dci); return i; } KHMEXP void KHMAPI khui_ilist_draw(khui_ilist * il, int idx, HDC dc, int x, int y, int opt) { HDC dci; HBITMAP hb_oldi; if(idx < 0) return; dci = CreateCompatibleDC(dc); hb_oldi = SelectObject(dci, il->img); /*BitBlt(dc, x, y, il->cx, il->cy, dci, idx*il->cx, 0, SRCCOPY); */ MaskBlt(dc, x, y, il->cx, il->cy, dci, idx * il->cx, 0, il->mask, idx * il->cx, 0, MAKEROP4(SRCPAINT, SRCCOPY)); /* MaskBlt(dc, x, y, il->cx, il->cy, dci, idx * il->cx, 0, il->mask, idx * il->cx, 0, MAKEROP4(SRCINVERT, SRCCOPY)); */ SelectObject(dci, hb_oldi); DeleteDC(dci); } KHMEXP void KHMAPI khui_ilist_draw_bg(khui_ilist * il, int idx, HDC dc, int x, int y, int opt, COLORREF bgcolor) { HDC dcm; HBITMAP hb_oldm, hb_mem; HBRUSH hbr; RECT r; dcm = CreateCompatibleDC(dc); hb_mem = CreateCompatibleBitmap(dc, il->cx, il->cy); hb_oldm = SelectObject(dcm, hb_mem); hbr = CreateSolidBrush(bgcolor); r.left = 0; r.top = 0; r.right = il->cx; r.bottom = il->cy; FillRect(dcm, &r, hbr); khui_ilist_draw(il,idx,dcm,0,0,opt); BitBlt(dc,x,y,il->cx,il->cy,dcm,0,0,SRCCOPY); SelectObject(dcm, hb_oldm); DeleteObject(hb_mem); DeleteObject(hbr); DeleteDC(dcm); } KHMEXP void KHMAPI khui_bitmap_from_hbmp(khui_bitmap * kbm, HBITMAP hbm) { HDC hdc; BITMAPINFO bmi; hdc = CreateCompatibleDC(NULL); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); kbm->hbmp = hbm; if(GetDIBits(hdc, hbm, 0, 0, NULL, &bmi, DIB_RGB_COLORS)) { kbm->cx = bmi.bmiHeader.biWidth; kbm->cy = bmi.bmiHeader.biHeight; } else { kbm->cx = -1; kbm->cy = -1; } DeleteDC(hdc); } KHMEXP void KHMAPI khui_delete_bitmap(khui_bitmap * kbm) { if (kbm->hbmp) DeleteObject(kbm->hbmp); kbm->hbmp = NULL; } KHMEXP void KHMAPI khui_draw_bitmap(HDC hdc, int x, int y, khui_bitmap * kbm) { HDC hdcb = CreateCompatibleDC(hdc); HBITMAP hbmold = SelectObject(hdcb, kbm->hbmp); BitBlt(hdc, x, y, kbm->cx, kbm->cy, hdcb, 0, 0, SRCCOPY); SelectObject(hdcb, hbmold); DeleteDC(hdcb); }