/* draw line segments by connecting passed points*/ BOOL WINAPI Polyline(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*/ GdSetForegroundColor(hdc->psd, 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; } return TRUE; }
BOOL WINAPI Ellipse(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) { HWND hwnd; int rx, ry; RECT rc; hwnd = MwPrepareDC(hdc); if(!hwnd) return FALSE; SetRect(&rc, nLeftRect, nTopRect, nRightRect, nBottomRect); if(MwIsClientDC(hdc)) MapWindowPoints(hwnd, NULL, (LPPOINT)&rc, 2); rx = (rc.right - rc.left)/2 - 1; ry = (rc.bottom - rc.top)/2 - 1; rc.left += rx; rc.top += ry; /* fill ellipse in current brush color*/ if(hdc->brush->style != BS_NULL) { InflateRect(&rc, -1, -1); GdSetForegroundColor(hdc->psd, hdc->brush->color); GdEllipse(hdc->psd, rc.left, rc.top, rx, ry, TRUE); } /* draw ellipse outline in current pen color*/ if(hdc->pen->style != PS_NULL) { GdSetForegroundColor(hdc->psd, hdc->pen->color); GdEllipse(hdc->psd, rc.left, rc.top, rx, ry, FALSE); } return TRUE; }
BOOL WINAPI Rectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom) { HWND hwnd; RECT rc; hwnd = MwPrepareDC(hdc); if(!hwnd) return FALSE; SetRect(&rc, nLeft, nTop, nRight, nBottom); if(MwIsClientDC(hdc)) MapWindowPoints(hwnd, NULL, (LPPOINT)&rc, 2); /* draw rectangle in current pen color*/ if(hdc->pen->style != PS_NULL) { GdSetForegroundColor(hdc->psd, hdc->pen->color); GdRect(hdc->psd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); } /* fill rectangle in current brush color*/ if(hdc->brush->style != BS_NULL) { InflateRect(&rc, -1, -1); GdSetForegroundColor(hdc->psd, hdc->brush->color); GdFillRect(hdc->psd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); } return TRUE; }
BOOL WINAPI LineTo(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) { GdSetForegroundColor(hdc->psd, 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; }
BOOL WINAPI StretchBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, DWORD dwRop) { HWND hwnd; POINT dst, src; if(!hdcDest || !hdcSrc) return FALSE; dst.x = nXOriginDest; dst.y = nYOriginDest; src.x = nXOriginSrc; src.y = nYOriginSrc; /* if src screen DC, convert coords*/ /* FIXME: src clipping isn't checked, only one set of cliprects also*/ if(!MwIsMemDC(hdcSrc) && MwIsClientDC(hdcSrc)) { if(!(hwnd = MwPrepareDC(hdcSrc))) return FALSE; ClientToScreen(hwnd, &src); } /* if dst screen DC, convert coords and set clipping*/ /* FIXME: if dest is also screen, src clipping will be overwritten*/ if(!MwIsMemDC(hdcDest) && MwIsClientDC(hdcDest)) { if(!(hwnd = MwPrepareDC(hdcDest))) return FALSE; ClientToScreen(hwnd, &dst); } if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc) { GdBlit(hdcDest->psd, dst.x, dst.y, nWidthDest, nHeightDest, hdcSrc->psd, src.x, src.y, dwRop); } else { GdStretchBlit(hdcDest->psd, dst.x, dst.y, nWidthDest, nHeightDest, hdcSrc->psd, src.x, src.y, nWidthSrc, nHeightSrc, dwRop); } return TRUE; }
int WINAPI FillRect(HDC hdc, CONST RECT *lprc, HBRUSH hbr) { HWND hwnd; RECT rc; MWBRUSHOBJ * obr = (MWBRUSHOBJ *)hbr; COLORREF crFill; hwnd = MwPrepareDC(hdc); if(!hwnd || !obr) return FALSE; if(!lprc) { if(MwIsClientDC(hdc)) GetClientRect(hwnd, &rc); else GetWindowRect(hwnd, &rc); lprc = &rc; } else rc = *lprc; if(MwIsClientDC(hdc)) MapWindowPoints(hwnd, NULL, (LPPOINT)&rc, 2); /* handle COLOR_xxx + 1 passed as HBRUSH*/ if((intptr_t)obr <= MAXSYSCOLORS) crFill = GetSysColor((intptr_t)obr-1); else { /* get color from passed HBRUSH*/ if(obr->style == BS_NULL) return TRUE; crFill = obr->color; } /* fill rectangle in passed brush color*/ GdSetForegroundColor(hdc->psd, crFill); GdFillRect(hdc->psd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); return TRUE; }
/* return RGB value at specified coordinates*/ COLORREF WINAPI GetPixel(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_TRUECOLOR233: /* create RGB colorval from 2/3/3 pixel*/ return PIXEL233TOCOLORVAL(pixel); case MWPF_PALETTE: if(GdGetPalette(hdc->psd, pixel, 1, &rgb)) return RGB(rgb.r, rgb.g, rgb.b); } return CLR_INVALID; }
/* Microwindows only*/ BOOL WINAPI DrawDIB(HDC hdc,int x,int y,PMWIMAGEHDR pimage) { HWND hwnd; POINT pt; hwnd = MwPrepareDC(hdc); if(!hwnd || !pimage) return FALSE; pt.x = x; pt.y = y; if(MwIsClientDC(hdc)) ClientToScreen(hwnd, &pt); GdDrawImage(hdc->psd, pt.x, pt.y, pimage); return TRUE; }
COLORREF WINAPI SetPixel(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*/ GdSetForegroundColor(hdc->psd, crColor); GdPoint(hdc->psd, pt.x, pt.y); return 0; /* doesn't return previous color*/ }
/* return RGB value at specified coordinates*/ COLORREF WINAPI GetPixel(HDC hdc, int x, int y) { HWND hwnd; POINT pt; MWPIXELVALHW pixel; 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); return GdGetColorRGB(hdc->psd, pixel); }
static void dopiearc(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int ax, int ay, int bx, int by, int type) { HWND hwnd; int rx, ry; RECT rc, rc2; hwnd = MwPrepareDC(hdc); if(!hwnd) return; SetRect(&rc, nLeftRect, nTopRect, nRightRect, nBottomRect); SetRect(&rc2, ax, ay, bx, by); if(MwIsClientDC(hdc)) { MapWindowPoints(hwnd, NULL, (LPPOINT)&rc, 2); MapWindowPoints(hwnd, NULL, (LPPOINT)&rc2, 2); } rx = (rc.right - rc.left)/2 - 1; ry = (rc.bottom - rc.top)/2 - 1; rc.left += rx; rc.top += ry; /* fill ellipse in current brush color*/ if(hdc->brush->style != BS_NULL && type == MWPIE) { GdSetForegroundColor(hdc->psd, hdc->brush->color); GdArc(hdc->psd, rc.left, rc.top, rx, ry, rc2.left, rc2.top, rc2.right, rc2.bottom, MWPIE); } /* draw ellipse outline in current pen color*/ if(hdc->pen->style != PS_NULL) { GdSetForegroundColor(hdc->psd, hdc->pen->color); if(type == MWPIE) type = MWARC; /* MWARCOUTLINE?*/ GdArc(hdc->psd, rc.left, rc.top, rx, ry, rc2.left, rc2.top, rc2.right, rc2.bottom, type); } }
BOOL WINAPI Polygon(HDC hdc, CONST POINT *lpPoints, int nCount) { HWND hwnd; int i; LPPOINT pp, ppAlloc = NULL; hwnd = MwPrepareDC(hdc); if(!hwnd) return FALSE; if(MwIsClientDC(hdc)) { /* convert points to client coords*/ ppAlloc = (LPPOINT)malloc(nCount * sizeof(POINT)); if(!ppAlloc) return FALSE; memcpy(ppAlloc, lpPoints, nCount*sizeof(POINT)); pp = ppAlloc; for(i=0; i<nCount; ++i) ClientToScreen(hwnd, pp++); pp = ppAlloc; } else pp = (LPPOINT)lpPoints; /* fill polygon in current brush color*/ if(hdc->brush->style != BS_NULL) { GdSetForegroundColor(hdc->psd, hdc->brush->color); GdFillPoly(hdc->psd, nCount, pp); } /* draw polygon outline in current pen color*/ if(hdc->pen->style != PS_NULL) { GdSetForegroundColor(hdc->psd, hdc->pen->color); GdPoly(hdc->psd, nCount, pp); } if(ppAlloc) free(ppAlloc); return TRUE; }
/* * Set the clip rectangles for a window taking into account other * windows that may be obscuring it. The windows that may be obscuring * this one are the siblings of each direct ancestor which are higher * in priority than those ancestors. Also, each parent limits the visible * area of the window. */ void MwSetClipWindow(HDC hdc) { HWND wp = hdc->hwnd; HWND pwp; /* parent window */ HWND sibwp; /* sibling windows */ MWCOORD diff; /* difference in coordinates */ PRECT prc; /* client or window rectangle*/ MWCLIPREGION *vis, *r; MWCOORD x, y, width, height; /* * Start with the rectangle for the complete window. * We will then cut pieces out of it as needed. */ prc = MwIsClientDC(hdc)? &wp->clirect: &wp->winrect; x = prc->left; y = prc->top; width = prc->right - prc->left; height = prc->bottom - prc->top; /* * First walk upwards through all parent windows, * and restrict the visible part of this window to the part * that shows through all of those parent windows client areas. */ pwp = wp; while (pwp != rootwp) { pwp = pwp->parent; diff = pwp->clirect.left - x; if (diff > 0) { width -= diff; x = pwp->clirect.left; } diff = pwp->clirect.right - (x + width); if (diff < 0) width += diff; diff = pwp->clirect.top - y; if (diff > 0) { height -= diff; y = pwp->clirect.top; } diff = pwp->clirect.bottom - (y + height); if (diff < 0) height += diff; } /* * If the window is completely clipped out of view, then * set the clipping region to indicate that. */ if (width <= 0 || height <= 0) { GdSetClipRegion(hdc->psd, NULL); return; } /* * Allocate initial vis region to parent-clipped size of window */ vis = GdAllocRectRegion(x, y, x+width, y+height); /* * Allocate temp region */ r = GdAllocRegion(); /* * Now examine all windows that obscure this window, and * for each obscuration, break up the clip rectangles into * the smaller pieces that are still visible. The windows * that can obscure us are the earlier siblings of all of * our parents. When clipping the root window, search all children. */ pwp = wp; while (pwp != NULL) { wp = pwp; pwp = wp->parent; if(!pwp) { /* We're clipping the root window*/ if(hdc->flags & DCX_CLIPCHILDREN) /* start with root's children*/ sibwp = rootwp->children; else sibwp = NULL; /* no search*/ wp = NULL; /* search all root's children*/ } else { if(hdc->flags & DCX_CLIPSIBLINGS) sibwp = pwp->children; else sibwp = wp; /* no search*/ } for (; sibwp != wp; sibwp = sibwp->siblings) { if (sibwp->unmapcount) continue; GdSetRectRegionIndirect(r, &sibwp->winrect); GdSubtractRegion(vis, vis, r); } /* if not clipping the root window, stop when you reach it*/ if(pwp == rootwp) break; } /* * If not the root window and we're going to be drawing * in the client area, clip all children. This is * required for non-special paint handling for child windows. * Non-client dc's don't clip children in order to get * proper border clipping in the case of border-clipped children. */ wp = hdc->hwnd; if(wp != rootwp && MwIsClientDC(hdc)) { for (sibwp=wp->children; sibwp; sibwp = sibwp->siblings) { if (sibwp->unmapcount) continue; GdSetRectRegionIndirect(r, &sibwp->winrect); GdSubtractRegion(vis, vis, r); } } #if UPDATEREGIONS /* * Intersect with update region, unless requested not to. */ if(!(hdc->flags & DCX_EXCLUDEUPDATE)) GdIntersectRegion(vis, vis, wp->update); #endif /* * Intersect with user region, if set. */ if (hdc->region) GdIntersectRegion(vis, vis, hdc->region->rgn); /* * Set the clip region (later destroy handled by GdSetClipRegion) */ GdSetClipRegion(hdc->psd, vis); /* * Destroy temp region */ GdDestroyRegion(r); }
/* internal version of ExtTextOut, passed flags for text data type*/ static BOOL MwExtTextOut(HDC hdc, int x, int y, UINT fuOptions, CONST RECT *lprc, LPCVOID lpszString, UINT cbCount, CONST INT *lpDx, int flags) { HWND hwnd; POINT pt; RECT rc; hwnd = MwPrepareDC(hdc); if(!hwnd) return FALSE; pt.x = x; pt.y = y; if(MwIsClientDC(hdc)) ClientToScreen(hwnd, &pt); /* optionally fill passed rectangle*/ if(lprc && (fuOptions&ETO_OPAQUE)) { rc = *lprc; if(MwIsClientDC(hdc)) MapWindowPoints(hwnd, NULL, (LPPOINT)&rc, 2); /* fill rectangle with current background color*/ GdSetForegroundColor(hdc->psd, hdc->bkcolor); GdFillRect(hdc->psd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); GdSetUseBackground(FALSE); } else { /* use current background mode for text background draw*/ GdSetUseBackground(hdc->bkmode == OPAQUE? TRUE: FALSE); /* always set background color in case GdArea is * used to draw, which compares gr_foreground != gr_background * if gr_usebg is false... */ /*if(hdc->bkmode == OPAQUE)*/ GdSetBackgroundColor(hdc->psd, hdc->bkcolor); } if (cbCount == 0) { /* Special case - no text. Used to fill rectangle. */ return TRUE; } /* nyi: lpDx*/ /* draw text in current text foreground and background color*/ GdSetForegroundColor(hdc->psd, hdc->textcolor); //GdSetFont(hdc->font->pfont); /* this whole text alignment thing needs rewriting*/ if((hdc->textalign & TA_BASELINE) == TA_BASELINE) { /* this is not right... changed for kaffe port flags |= MWTF_TOP; */ flags |= MWTF_BASELINE; } else if(hdc->textalign & TA_BOTTOM) { MWCOORD ph, pw, pb; if(lprc) pt.y += lprc->bottom - lprc->top; else { GdGetTextSize(hdc->font->pfont, lpszString, cbCount, &pw, &ph, &pb, flags); pt.y += ph; } flags |= MWTF_BOTTOM; } else flags |= MWTF_TOP; if((hdc->textalign & TA_CENTER) == TA_CENTER) { MWCOORD ph, pw, pb; GdGetTextSize(hdc->font->pfont, lpszString, cbCount, &pw, &ph, &pb, flags); pt.x -= pw/2; } else if(hdc->textalign & TA_RIGHT) { MWCOORD ph, pw, pb; GdGetTextSize(hdc->font->pfont, lpszString, cbCount, &pw, &ph, &pb, flags); pt.x -= pw; } GdText(hdc->psd, hdc->font->pfont, pt.x, pt.y, lpszString, cbCount, flags); return TRUE; }