📄 wingdi.c
字号:
/* * Copyright (c) 1999, 2000, 2001 Greg Haerr <greg@censoft.com> * * Win32 API upper level graphics drawing routines */#include "windows.h"#include "wintern.h"#include "device.h"#include <stdlib.h>#include <string.h>#define MAXSYSCOLORS 29 /* # of COLOR_* system colors*/#define MAXSTOCKOBJECTS 18 /* # of stock objects*/#if ERASEMOVEBOOL mwERASEMOVE = TRUE; /* default XORMOVE repaint algorithm*/#elseBOOL mwERASEMOVE = FALSE; /* default ERASEMOVE repaint algorithm*/#endif/* cast a pointer to an integer*/#if DOS_TURBOC#define PTRTOINT unsigned long#else#define PTRTOINT unsigned int#endifstatic HDC cliphdc; /* current window cliprects*//* default bitmap for new DCs*/static MWBITMAPOBJ default_bitmap = { {OBJ_BITMAP, TRUE}, 1, 1, 1, 1, 1, 1};static BOOL MwExtTextOut(HDC hdc, int x, int y, UINT fuOptions, CONST RECT *lprc, LPCVOID lpszString, UINT cbCount, CONST INT *lpDx, int flags);static int MwDrawText(HDC hdc, LPCVOID lpString, int nCount, LPRECT lpRect, UINT uFormat, int flags);HDC WINAPIGetDCEx(HWND hwnd,HRGN hrgnClip,DWORD flags){ HDC hdc; if(!hwnd) /* handle NULL hwnd => desktop*/ hwnd = rootwp; /* handle private DC's*/ if(hwnd->owndc && !(flags & DCX_WINDOW)) return hwnd->owndc; /* add caching?*/ hdc = GdItemNew(struct hdc); if(!hdc) return NULL; hdc->psd = &scrdev; hdc->hwnd = hwnd; if(flags & DCX_DEFAULTCLIP) { flags &= ~DCX_DEFAULTCLIP; if(hwnd->style & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS; if(hwnd->style & WS_CLIPCHILDREN) flags |= DCX_CLIPCHILDREN; } hdc->flags = flags; hdc->bkmode = OPAQUE; hdc->textalign = TA_LEFT | TA_TOP | TA_NOUPDATECP; hdc->bkcolor = RGB(255, 255, 255); /* WHITE*/ hdc->textcolor = RGB(0, 0, 0); /* BLACK*/ hdc->brush = (MWBRUSHOBJ *)GetStockObject(WHITE_BRUSH); hdc->pen = (MWPENOBJ *)GetStockObject(BLACK_PEN); hdc->font = (MWFONTOBJ *)GetStockObject(SYSTEM_FONT);#if UPDATEREGIONS if(hrgnClip) { /* make a copy of passed region*/ hdc->region = (MWRGNOBJ *)CreateRectRgn(0, 0, 0, 0); CombineRgn((HRGN)hdc->region, hrgnClip, NULL, RGN_COPY); }#endif /* make default bitmap compatible with scrdev * otherwise problems occur later because selecting * in the default bitmap overwrite planes and bpp * in a memory dc, and thus it becomes incompatible * with scrdev. */ default_bitmap.planes = scrdev.planes; default_bitmap.bpp = scrdev.bpp; hdc->bitmap = &default_bitmap; hdc->drawmode = R2_COPYPEN; hdc->pt.x = 0; hdc->pt.y = 0; /* assign private DC if CS_OWNDC and not WindowDC*/ if((hwnd->pClass->style & CS_OWNDC) && !(flags & DCX_WINDOW)) { /* must exclude update region due to BeginPaint GetDCEx call*/ hdc->flags |= DCX_EXCLUDEUPDATE; hwnd->owndc = hdc; } return hdc;}HDC WINAPIGetDC(HWND hwnd){ /* * Exclude update regions when drawing with GetDC. * This is required because some programs use GetDC * when painting outside of BeginPaint/EndPaint, and * the update region is empty then. */ return GetDCEx(hwnd, NULL, DCX_DEFAULTCLIP|DCX_EXCLUDEUPDATE);}HDC WINAPIGetWindowDC(HWND hwnd){ /* * Exclude update region for now, since we * don't keep track of non-client update regions yet */ return GetDCEx(hwnd, NULL,DCX_WINDOW|DCX_DEFAULTCLIP|DCX_EXCLUDEUPDATE);}/* free a DC allocated from GetDC*/int WINAPI ReleaseDC(HWND hwnd, HDC hdc){ /* don't delete a memory dc on release*/ if(!hdc || (hdc->psd->flags&PSF_MEMORY)) return 0; if(hdc == cliphdc) cliphdc = NULL; /* handle private DC's*/ if(hdc->hwnd->owndc && !(hdc->flags & DCX_WINDOW)) return 1; DeleteObject((HBRUSH)hdc->brush); DeleteObject((HPEN)hdc->pen);#if 0 /* don't delete font resources on ReleaseDC... use DeleteObject instead*/ DeleteObject((HFONT)hdc->font);#endif DeleteObject((HRGN)hdc->region); /* * We can only select a bitmap in a memory DC, * so bitmaps aren't released except through DeleteDC. */ DeleteObject((HBITMAP)hdc->bitmap); GdItemFree(hdc); return 1;}/* free a dc allocated from CreateCompatibleDC*/BOOL WINAPIDeleteDC(HDC hdc){ /* don't delete a normal dc, only memory dc's*/ if(!hdc || !(hdc->psd->flags&PSF_MEMORY)) return 0; /* free allocated memory screen device*/ hdc->psd->FreeMemGC(hdc->psd); /* make it look like a GetDC dc, and free it*/ hdc->psd = &scrdev; return ReleaseDC(NULL, hdc);}voidMwPaintNCArea(HWND hwnd){ SendMessage(hwnd, WM_NCPAINT, 0, 0L); /* for now, we always paint NC scrollbar areas*/ MwPaintNCScrollbars(hwnd, NULL);}HDC WINAPI BeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint){ HDC hdc; /* first update non-client area*/ if(mwforceNCpaint || hwnd->paintNC != mwpaintNC) { MwPaintNCArea(hwnd); hwnd->paintNC = mwpaintNC; } /* If ERASEMOVE: * Don't allow windows to repaint while user is moving * a window. Instead, just erase backgrounds * and indicate delayed painting required, which * will occur after user completes window move. */ if(mwERASEMOVE && dragwp) { hdc = NULL; lpPaint->fErase = !DefWindowProc(hwnd, WM_ERASEBKGND, 0, 0L); hwnd->gotPaintMsg = PAINT_DELAYPAINT; } else { HideCaret(hwnd); /* FIXME: mdemo requires update excluded or draw errors occur*/ hdc = GetDCEx(hwnd, NULL, DCX_DEFAULTCLIP |DCX_EXCLUDEUPDATE); /* FIXME - bug*/ /* erase client background*/ lpPaint->fErase = !SendMessage(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0L); } lpPaint->hdc = hdc; GetUpdateRect(hwnd, &lpPaint->rcPaint, FALSE); return hdc;}BOOL WINAPI EndPaint(HWND hwnd, CONST PAINTSTRUCT *lpPaint){ ReleaseDC(hwnd, lpPaint->hdc);#if UPDATEREGIONS /* don't clear update region until done dragging*/ if(mwERASEMOVE && !dragwp) GdSetRectRegion(hwnd->update, 0, 0, 0, 0);#endif ShowCaret(hwnd); return TRUE;}COLORREF WINAPISetTextColor(HDC hdc, COLORREF crColor){ COLORREF oldtextcolor; if (!hdc) return CLR_INVALID; oldtextcolor = hdc->textcolor; hdc->textcolor = (MWCOLORVAL)crColor; return oldtextcolor;}COLORREF WINAPISetBkColor(HDC hdc, COLORREF crColor){ COLORREF oldbkcolor; if (!hdc) return CLR_INVALID; oldbkcolor = hdc->bkcolor; hdc->bkcolor = crColor; return oldbkcolor;}int WINAPISetBkMode(HDC hdc, int iBkMode){ int oldbkmode; if(!hdc) return 0; oldbkmode = hdc->bkmode; hdc->bkmode = iBkMode; return oldbkmode;}UINT WINAPISetTextAlign(HDC hdc, UINT fMode){ UINT oldfMode; if(!hdc) return GDI_ERROR; oldfMode = hdc->textalign; hdc->textalign = fMode; return oldfMode;}/* FIXME: releasing a DC does NOT change back the drawing mode!*/int WINAPISetROP2(HDC hdc, int fnDrawMode){ int newmode, oldmode; if(!hdc || (fnDrawMode <= 0 || fnDrawMode > R2_LAST)) return 0; oldmode = hdc->drawmode; newmode = fnDrawMode - 1; /* map to MWMODE_xxx*/ hdc->drawmode = newmode; GdSetMode(newmode); return oldmode;}/* * Setup clip region from device context's associated window or bitmap. * Memory DC's are always associated with the desktop window, and are * always visible. Return the DC's hwnd if window is visible. */HWNDMwPrepareDC(HDC hdc){ HWND hwnd; if(!hdc || !hdc->hwnd) return NULL; hwnd = hdc->hwnd; if (hwnd->unmapcount) return NULL; /* * If the window is not the currently clipped one, then * make it the current one and define its clip rectangles. */ if(hdc != cliphdc) { /* clip memory dc's to the bitmap size*/ if(hdc->psd->flags&PSF_MEMORY) {#if DYNAMICREGIONS GdSetClipRegion(hdc->psd, GdAllocRectRegion(0, 0, hdc->psd->xvirtres, hdc->psd->yvirtres));#else static MWCLIPRECT crc = {0, 0, 0, 0}; crc.width = hdc->psd->xvirtres; crc.height = hdc->psd->yvirtres; GdSetClipRects(hdc->psd, 1, &crc);#endif } else MwSetClipWindow(hdc); cliphdc = hdc; } return hwnd;}/* return RGB value at specified coordinates*/COLORREF WINAPIGetPixel(HDC hdc, int x, int y){ HWND hwnd; POINT pt; MWPIXELVAL pixel; MWPALENTRY rgb; hwnd = MwPrepareDC(hdc); if(!hwnd) return CLR_INVALID; pt.x = x; pt.y = y; if(MwIsClientDC(hdc)) ClientToScreen(hwnd, &pt); /* read pixel value*/ GdReadArea(hdc->psd, pt.x, pt.y, 1, 1, &pixel); switch(hdc->psd->pixtype) { case MWPF_TRUECOLOR0888: case MWPF_TRUECOLOR888: /* create RGB colorval from 8/8/8 pixel*/ return PIXEL888TOCOLORVAL(pixel); case MWPF_TRUECOLOR565: /* create RGB colorval from 5/6/5 pixel*/ return PIXEL565TOCOLORVAL(pixel); case MWPF_TRUECOLOR555: /* create RGB colorval from 5/5/5 pixel*/ return PIXEL555TOCOLORVAL(pixel); case MWPF_TRUECOLOR332: /* create RGB colorval from 3/3/2 pixel*/ return PIXEL332TOCOLORVAL(pixel); case MWPF_PALETTE: if(GdGetPalette(hdc->psd, pixel, 1, &rgb)) return RGB(rgb.r, rgb.g, rgb.b); } return CLR_INVALID;}COLORREF WINAPISetPixel(HDC hdc, int x, int y, COLORREF crColor){ HWND hwnd; POINT pt; hwnd = MwPrepareDC(hdc); if(!hwnd) return 0; /* doesn't return previous color*/ pt.x = x; pt.y = y; if(MwIsClientDC(hdc)) ClientToScreen(hwnd, &pt); /* draw point in passed color*/ GdSetForeground(GdFindColor(crColor)); GdPoint(hdc->psd, pt.x, pt.y); return 0; /* doesn't return previous color*/}BOOL WINAPI MoveToEx(HDC hdc, int x, int y, LPPOINT lpPoint){ if(!hdc) return FALSE; if(lpPoint) *lpPoint = hdc->pt; hdc->pt.x = x; hdc->pt.y = y; return TRUE;}BOOL WINAPILineTo(HDC hdc, int x, int y){ HWND hwnd; POINT beg, end; hwnd = MwPrepareDC(hdc); if(!hwnd) return FALSE; beg.x = hdc->pt.x; beg.y = hdc->pt.y; end.x = x; end.y = y; if(MwIsClientDC(hdc)) { ClientToScreen(hwnd, &beg); ClientToScreen(hwnd, &end); } /* draw line in current pen color*/ if(hdc->pen->style != PS_NULL) { GdSetForeground(GdFindColor(hdc->pen->color)); /* don't draw last point*/ GdLine(hdc->psd, beg.x, beg.y, end.x, end.y, FALSE); } hdc->pt.x = x; hdc->pt.y = y; return TRUE;}/* draw line segments by connecting passed points*/BOOL WINAPIPolyline(HDC hdc, CONST POINT *lppt, int cPoints){ HWND hwnd; POINT beg, end; if(cPoints <= 1) return FALSE; hwnd = MwPrepareDC(hdc); if(!hwnd) return FALSE; if(hdc->pen->style == PS_NULL) return TRUE; /* draw line in current pen color*/ GdSetForeground(GdFindColor(hdc->pen->color)); beg = *lppt++; if(MwIsClientDC(hdc)) ClientToScreen(hwnd, &beg); while(--cPoints > 0) { end = *lppt++; if(MwIsClientDC(hdc)) ClientToScreen(hwnd, &end); /* don't draw last point*/ GdLine(hdc->psd, beg.x, beg.y, end.x, end.y, FALSE); beg = end; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -