📄 icon.c
字号:
// $Id: icon.c,v 1.7 2000/08/28 03:08:21 weiym Exp $//// Icon operations of GDI.//// Copyright (C) 2000, Wei Yongming.//// Current maintainer: Wei Yongming./*** This library is free software; you can redistribute it and/or** modify it under the terms of the GNU Library General Public** License as published by the Free Software Foundation; either** version 2 of the License, or (at your option) any later version.**** This library is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU** Library General Public License for more details.**** You should have received a copy of the GNU Library General Public** License along with this library; if not, write to the Free** Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,** MA 02111-1307, USA*/// Create date: 2000/06/12, derived from original gdi.c//// Modify records://// Who When Where For What Status//-----------------------------------------------------------------------------//// TODO:// #include <stdio.h>#include <stdlib.h>#include <pthread.h>#include <semaphore.h>#include "common.h"#include "gdi.h"#include "window.h"#include "cliprect.h"#include "gal.h"#include "internals.h"#include "dc.h"#ifndef lintstatic char fileid[] = "$Id: icon.c,v 1.7 2000/08/28 03:08:21 weiym Exp $";#endif/************************* Icon-related structures *************************/typedef struct _ICONDIRENTRY { BYTE bWidth; BYTE bHeight; BYTE bColorCount; BYTE bReserved; WORD wPlanes; WORD wBitCount; DWORD dwBytesInRes; DWORD dwImageOffset;}ICONDIRENTRY;#define SIZEOF_ICONDIRENTRY 16typedef struct _ICONDIR { WORD cdReserved; WORD cdType; // must be 1. WORD cdCount;}ICONDIR;typedef struct _ICON { int width; int height; void* AndBits; void* XorBits;}ICON;typedef ICON* PICON;extern pthread_mutex_t gdilock;extern BOOL dc_GenerateECRgn(PDC pdc, BOOL fForce);extern void ShowCursorForGDI(BOOL fShow, const RECT* prc);/************************* Icon support **************************************/// Icon creating and destroying.HICON GUIAPI LoadIconFromFile (HDC hdc, const char* filename, int which){ FILE* fp; WORD wTemp; BYTE bTemp; int w, h, colornum; DWORD size, offset; DWORD imagesize, imagew, imageh; BYTE* image; if( !(fp = fopen(filename, "rb")) ) return 0; fseek(fp, sizeof(WORD), SEEK_SET); // the cbType of struct ICONDIR. fread(&wTemp, sizeof(WORD), 1, fp); if(wTemp != 1) goto error; // get ICON images count. fread (&wTemp, sizeof (WORD), 1, fp); if (which >= wTemp) which = wTemp - 1; if (which < 0) which = 0; // seek to the right ICONDIRENTRY if needed. if (which != 0) fseek (fp, SIZEOF_ICONDIRENTRY * which, SEEK_CUR); // cursor info, read the members of struct ICONDIRENTRY. fread(&bTemp, sizeof(BYTE), 1, fp); w = bTemp; // the width of first cursor. fread(&bTemp, sizeof(BYTE), 1, fp); h = bTemp; // the height of first cursor. if((w%16) != 0 || (h%16) != 0) goto error; fread(&bTemp, sizeof(BYTE), 1, fp); // the bColorCount. if(bTemp != 2 && bTemp != 16) goto error; fseek(fp, sizeof(BYTE), SEEK_CUR); // skip the bReserved. fread(&wTemp, sizeof(WORD), 1, fp); // the wPlanes. if(wTemp != 0) goto error; fread(&wTemp, sizeof(WORD), 1, fp); // the wBitCount; if(wTemp > 4) goto error; fread(&size, sizeof(DWORD), 1, fp); fread(&offset, sizeof(DWORD), 1, fp); // read the cursor image info. fseek(fp, offset, SEEK_SET); fseek(fp, sizeof(DWORD), SEEK_CUR); // skip the biSize member. fread(&imagew, sizeof(DWORD), 1, fp); fread(&imageh, sizeof(DWORD), 1, fp); // check the biPlanes member; fread(&wTemp, sizeof(WORD), 1, fp); if(wTemp != 1) goto error; // check the biBitCount member; fread(&wTemp, sizeof(WORD), 1, fp); if(wTemp > 4) goto error; colornum = (int)wTemp; fseek(fp, sizeof(DWORD), SEEK_CUR); // skip the biCompression members. fread(&imagesize, sizeof(DWORD), 1, fp); // skip the rest members and the color table. fseek(fp, sizeof(DWORD)*4 + sizeof(BYTE)*(4<<colornum), SEEK_CUR); // allocate memory for image. // Use alloca, the stack may be enough for the image. image = (BYTE*) alloca (imagesize); // read image fread(image, imagesize, 1, fp); fclose(fp); return CreateIcon (hdc, w, h, image + (imagesize - w*h/8), image, colornum);error: fclose(fp); return 0;}HICON GUIAPI CreateIcon (HDC hdc, int w, int h, const BYTE* pAndBits, const BYTE* pXorBits, int colornum){ PICON picon; int bpp; bpp = GAL_BytesPerPixel (dc_HDC2PDC (hdc)->gc); if( (w%16) != 0 || (h%16) != 0 ) return 0; // allocate memory. if( !(picon = (PICON)malloc(sizeof(ICON))) ) return 0; if( !(picon->AndBits = malloc(w * h * bpp)) ) { free(picon); return 0; } if( !(picon->XorBits = malloc(w * h * bpp)) ) { free(picon->AndBits); free(picon); return 0; } picon->width = w; picon->height = h; if(colornum == 1) { ExpandMonoBitmap (hdc, w, h, pAndBits, BMP_FLOW_UP, w >> 3, picon->AndBits, 0xFFFFFFFF, 0); ExpandMonoBitmap (hdc, w, h, pXorBits, BMP_FLOW_UP, w >> 3, picon->XorBits, 0xFFFFFFFF, 0); } else if(colornum == 4) { ExpandMonoBitmap (hdc, w, h, pAndBits, BMP_FLOW_UP, w >> 3, picon->AndBits, 0xFFFFFFFF, 0); Expand16CBitmap (hdc, w, h, pXorBits, BMP_FLOW_UP, w >> 1, picon->XorBits, NULL); } return (HICON)picon;}BOOL GUIAPI DestroyIcon(HICON hicon){ PICON picon = (PICON)hicon; free(picon->AndBits); free(picon->XorBits); free(picon); return TRUE;}void GUIAPI DrawIcon(HDC hdc, int x, int y, int w, int h, HICON hicon){ PCLIPRECT pClipRect; PDC pdc; PICON picon = (PICON)hicon; int i; int imagesize; BYTE* iconimage; BYTE* andbits = NULL; BYTE* xorbits = NULL; RECT rcOutput; pdc = dc_HDC2PDC(hdc); if (dc_IsGeneralHDC(hdc)) { pthread_mutex_lock (&pdc->pGCRInfo->lock); if (!dc_GenerateECRgn (pdc, FALSE)) { pthread_mutex_unlock (&pdc->pGCRInfo->lock); return; } } if(w <= 0) w = picon->width; if(h <= 0) h = picon->height; // Transfer logical to device to screen here. w += x; h += y; coor_LP2SP(pdc, &x, &y); coor_LP2SP(pdc, &w, &h); rcOutput.left = x; rcOutput.top = y; rcOutput.right = w; rcOutput.bottom = h; NormalizeRect (&rcOutput); w -= x; h -= y; pthread_mutex_lock (&gdilock); IntersectRect (&rcOutput, &rcOutput, &pdc->ecrgn.rcBound); if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(FALSE, &rcOutput); GAL_SetGC (pdc->gc); imagesize = w * h * GAL_BytesPerPixel (pdc->gc); if ((iconimage = malloc (imagesize)) == NULL) goto free_ret; if (w != picon->width || h != picon->height) { andbits = malloc (imagesize); xorbits = malloc (imagesize); if (andbits == NULL || xorbits == NULL) goto free_ret; GAL_ScaleBox (pdc->gc, picon->width, picon->height, picon->AndBits, w, h, andbits); GAL_ScaleBox (pdc->gc, picon->width, picon->height, picon->XorBits, w, h, xorbits); } else { andbits = picon->AndBits; xorbits = picon->XorBits; } GAL_GetBox (pdc->gc, x, y, w, h, iconimage); for(i = 0; i < imagesize; i++) { iconimage[i] &= andbits [i]; iconimage[i] ^= xorbits [i]; } pClipRect = pdc->ecrgn.head; while (pClipRect) { if (DoesIntersect (&rcOutput, &pClipRect->rc)) { GAL_SetClipping(pdc->gc, pClipRect->rc.left, pClipRect->rc.top, pClipRect->rc.right - 1, pClipRect->rc.bottom - 1); GAL_PutBox(pdc->gc, x, y, w, h, iconimage); } pClipRect = pClipRect->next; }free_ret: if (!dc_IsMemHDC(hdc)) ShowCursorForGDI (TRUE, &rcOutput); pthread_mutex_unlock (&gdilock); if (dc_IsGeneralHDC(hdc)) pthread_mutex_unlock (&pdc->pGCRInfo->lock); free (iconimage); if (w != picon->width || h != picon->height) { free (andbits); free (xorbits); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -