📄 bitmap.c
字号:
// $Id: bitmap.c,v 1.14 2000/11/06 03:39:50 ymwei Exp $//// Bitmap 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: bitmap.c,v 1.14 2000/11/06 03:39:50 ymwei Exp $";#endifextern pthread_mutex_t gdilock;extern BOOL dc_GenerateECRgn(PDC pdc, BOOL fForce);extern void ShowCursorForGDI(BOOL fShow, const RECT* prc);/****************************** Bitmap Support *******************************/void GUIAPI FillBox (HDC hdc, int x, int y, int w, int h){ PCLIPRECT pClipRect; PDC pdc; 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; } } // 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; IntersectRect (&rcOutput, &rcOutput, &pdc->ecrgn.rcBound); pthread_mutex_lock (&gdilock); if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(FALSE, &rcOutput); // set graphics context. GAL_SetGC (pdc->gc); GAL_SetFgColor (pdc->gc, pdc->brushcolor); 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_FillBox (pdc->gc, x, y, w, h, pdc->brushcolor); } pClipRect = pClipRect->next; } if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(TRUE, &rcOutput); pthread_mutex_unlock(&gdilock); if (dc_IsGeneralHDC(hdc)) pthread_mutex_unlock (&pdc->pGCRInfo->lock);}void GUIAPI FillBoxWithBitmap(HDC hdc, int x, int y, int w, int h, PBITMAP pBitmap){ PCLIPRECT pClipRect; PDC pdc; void* scaledBitmap; int sw = pBitmap->bmWidth, sh = pBitmap->bmHeight; RECT rcOutput; if (w <= 0 || h <= 0) { w = sw; h = sh; } 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; } } // 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); if(w == sw && h == sh) scaledBitmap = pBitmap->bmBits; else { if ((scaledBitmap = malloc (w * h * GAL_BytesPerPixel (pdc->gc))) == NULL) goto free_ret; GAL_ScaleBox (pdc->gc, sw, sh, pBitmap->bmBits, w, h, scaledBitmap); } // set graphics context. GAL_SetGC (pdc->gc); 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); if(pdc->bkmode & BM_TRANSPARENT) GAL_PutBoxMask (pdc->gc, x, y, w, h, scaledBitmap); else GAL_PutBox (pdc->gc, x, y, w, h, scaledBitmap); } 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); if (w != sw || h != sh) { free (scaledBitmap); }}static void bmpGetBoxPart (int bpp, int w, int h, void* part, int ow, int oh, void* full, int xo, int yo){ int i; int offset; int lineoffset; int linebytes; lineoffset = ow * bpp; linebytes = w * bpp; offset = (ow * yo + xo) * bpp; for (i=0; i<h; i++) { memcpy (part, full + offset, linebytes); part += linebytes; offset += lineoffset; }}void GUIAPI FillBoxWithBitmapPart (HDC hdc, int x, int y, int w, int h, int bw, int bh, PBITMAP pBitmap, int xo, int yo){ PCLIPRECT pClipRect; PDC pdc; void* scaledBitmap = NULL; void* partBitmap = NULL; int sw = pBitmap->bmWidth, sh = pBitmap->bmHeight; RECT rcOutput; int bpp; pdc = dc_HDC2PDC(hdc); bpp = GAL_BytesPerPixel (pdc->gc); if (dc_IsGeneralHDC(hdc)) { pthread_mutex_lock (&pdc->pGCRInfo->lock); if (!dc_GenerateECRgn (pdc, FALSE)) { pthread_mutex_unlock (&pdc->pGCRInfo->lock); return; } } // 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); // set graphics context. GAL_SetGC(pdc->gc); if (bw <= 0 || bh <= 0) { scaledBitmap = pBitmap->bmBits; bw = sw; bh = sh; } else if (bw == sw && bh == sh) scaledBitmap = pBitmap->bmBits; else { if ((scaledBitmap = malloc (bw * bh * bpp)) == NULL) goto free_ret; GAL_ScaleBox (pdc->gc, sw, sh, pBitmap->bmBits, bw, bh, scaledBitmap); } // extract part box if ((partBitmap = malloc (w * h * bpp)) == NULL) goto free_ret; bmpGetBoxPart (bpp, w, h, partBitmap, bw, bh, scaledBitmap, xo, yo); 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, partBitmap); } 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); if (bw != sw || bh != sh) free (scaledBitmap); free (partBitmap);}void GUIAPI PutSavedBoxOnDC (HDC hdc, int x, int y, int w, int h, void* vbuf){ PCLIPRECT pClipRect; PDC pdc; 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; } } // 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); 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, vbuf); } pClipRect = pClipRect->next; } if( !dc_IsMemHDC(hdc) ) ShowCursorForGDI(TRUE, &rcOutput); pthread_mutex_unlock(&gdilock); if (dc_IsGeneralHDC(hdc)) pthread_mutex_unlock (&pdc->pGCRInfo->lock);}void ScreenCopy (int sx, int sy, HDC hdc, int dx, int dy){ PCLIPRECT pClipRect; PDC pdc; int offx, offy; int boxLeft, boxTop, boxWidth, boxHeight; RECT* prc; 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; } } else return; coor_LP2SP(pdc, &dx, &dy); offx = sx - dx; offy = sy - dy; pthread_mutex_lock (&gdilock); ShowCursorForGDI(FALSE, &g_rcScr); GAL_SetGC (PHYSICALGC); GAL_DisableClipping (pdc->gc); pClipRect = pdc->ecrgn.head; while (pClipRect) { prc = &pClipRect->rc; boxLeft = prc->left + offx; boxTop = prc->top + offy; boxWidth = prc->right - prc->left; boxHeight = prc->bottom - prc->top;// FIXME// vga_waitretrace (); GAL_CopyBox (pdc->gc, boxLeft, boxTop, boxWidth, boxHeight, prc->left, prc->top); pClipRect = pClipRect->next; } ShowCursorForGDI(TRUE, &g_rcScr); pthread_mutex_unlock(&gdilock); if (dc_IsGeneralHDC(hdc)) pthread_mutex_unlock (&pdc->pGCRInfo->lock);}void GUIAPI BitBlt(HDC hsdc, int sx, int sy, int sw, int sh, HDC hddc, int dx, int dy, DWORD dwRop){ PCLIPRECT pClipRect; PDC psdc, pddc; RECT rcOutput; psdc = dc_HDC2PDC(hsdc); pddc = dc_HDC2PDC(hddc); if (dc_IsGeneralHDC(hddc)) { pthread_mutex_lock (&pddc->pGCRInfo->lock); if (!dc_GenerateECRgn (pddc, FALSE)) { pthread_mutex_unlock (&pddc->pGCRInfo->lock); return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -