📄 tkwindraw.c
字号:
* * Results: * None. * * Side effects: * Renders a series of connected lines. * *---------------------------------------------------------------------- */voidXDrawLines(display, d, gc, points, npoints, mode) Display* display; Drawable d; GC gc; XPoint* points; int npoints; int mode;{ HPEN pen; TkWinDCState state; HDC dc; if (d == None) { return; } GTRACE(("begin XDrawLines\n");) dc = TkWinGetDrawableDC(display, d, &state); if (!tkpIsWin32s && (gc->line_width > 1)) { LOGBRUSH lb; DWORD style; lb.lbStyle = BS_SOLID; lb.lbColor = gc->foreground; lb.lbHatch = 0; style = PS_GEOMETRIC|PS_COSMETIC; switch (gc->cap_style) { case CapNotLast: case CapButt: style |= PS_ENDCAP_FLAT; break; case CapRound: style |= PS_ENDCAP_ROUND; break; default: style |= PS_ENDCAP_SQUARE; break; } switch (gc->join_style) { case JoinMiter: style |= PS_JOIN_MITER; break; case JoinRound: style |= PS_JOIN_ROUND; break; default: style |= PS_JOIN_BEVEL; break; } pen = TkWinExtCreatePen(gc,style, gc->line_width, &lb, 0, NULL); } else { pen = TkWinCreatePen(gc,PS_SOLID, gc->line_width, gc->foreground); } RenderObject(dc, gc, points, npoints, mode, pen, F_POLYLINE); TkWinDeletePen(gc,pen); TkWinReleaseDrawableDC(d, dc, &state); GTRACE(("end XDrawLines\n");)}/* *---------------------------------------------------------------------- * * XFillPolygon -- * * Draws a filled polygon. * * Results: * None. * * Side effects: * Draws a filled polygon on the specified drawable. * *---------------------------------------------------------------------- */voidXFillPolygon(display, d, gc, points, npoints, shape, mode) Display* display; Drawable d; GC gc; XPoint* points; int npoints; int shape; int mode;{ HPEN pen; TkWinDCState state; HDC dc; if (d == None) { return; } GTRACE(("begin XFillPoly\n");) dc = TkWinGetDrawableDC(display, d, &state); pen = CkGetStockObject(NULL_PEN); RenderObject(dc, gc, points, npoints, mode, pen, F_POLYGON); TkWinReleaseDrawableDC(d, dc, &state); GTRACE(("end XFillPoly\n");)}/* *---------------------------------------------------------------------- * * XDrawRectangle -- * * Draws a rectangle. * * Results: * None. * * Side effects: * Draws a rectangle on the specified drawable. * *---------------------------------------------------------------------- */voidXDrawRectangle(display, d, gc, x, y, width, height) Display* display; Drawable d; GC gc; int x; int y; unsigned int width; unsigned int height;{ HPEN pen;//#define USE_POLY_FOR_RECT#ifdef USE_POLY_FOR_RECT POINT tp[4];#endif#ifndef USE_CKGRAPH_IMP HPEN oldPen;#endif TkWinDCState state; HDC dc; if (d == None) { return; } GTRACE(("begin XDrawRectangle\n");) dc = TkWinGetDrawableDC(display, d, &state); pen = TkWinCreatePen(gc,PS_SOLID, gc->line_width, gc->foreground); CkSetROP2(dc, tkpWinRopModes[gc->function]);#ifdef USE_CKGRAPH_IMP CkSelectPen(dc, pen);#else oldPen = CkSelectPen(dc, pen);#endif#ifdef USE_POLY_FOR_RECT tp[0].x=x;tp[0].y=y; tp[1].x=x+width;tp[1].y=y; tp[2].x=x+width;tp[2].y=y+height; tp[3].x=x;tp[3].y=y+height; CkPolyline(dc,tp,3);#else CkSelectBrush(dc, CkGetStockObject(NULL_BRUSH)); CkRectangle(dc, x, y, x+width+1, y+height+1);#endif#ifdef USE_CKGRAPH_IMP TkWinDeletePen(gc,pen);#else TkWinDeletePen(gc,CkSelectPen(dc, oldPen));#endif TkWinReleaseDrawableDC(d, dc, &state); GTRACE(("end XDrawRectangle\n");)}/* *---------------------------------------------------------------------- * * XDrawArc -- * * Draw an arc. * * Results: * None. * * Side effects: * Draws an arc on the specified drawable. * *---------------------------------------------------------------------- */voidXDrawArc(display, d, gc, x, y, width, height, start, extent) Display* display; Drawable d; GC gc; int x; int y; unsigned int width; unsigned int height; int start; int extent;{ display->request++; GTRACE(("begin XDrawArc\n");) DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, 0); GTRACE(("end XDrawArc\n");)}/* *---------------------------------------------------------------------- * * XFillArc -- * * Draw a filled arc. * * Results: * None. * * Side effects: * Draws a filled arc on the specified drawable. * *---------------------------------------------------------------------- */voidXFillArc(display, d, gc, x, y, width, height, start, extent) Display* display; Drawable d; GC gc; int x; int y; unsigned int width; unsigned int height; int start; int extent;{ display->request++; GTRACE(("begin XFillArc\n");) DrawOrFillArc(display, d, gc, x, y, width, height, start, extent, 1); GTRACE(("end XFillArc\n");)}/* *---------------------------------------------------------------------- * * DrawOrFillArc -- * * This procedure handles the rendering of drawn or filled * arcs and chords. * * Results: * None. * * Side effects: * Renders the requested arc. * *---------------------------------------------------------------------- *//* * Implements the "pixeling" of small arcs, because GDI-performance * for this is awful * was made especially for BLT, graph4 demo now runs 4x faster * * //* O-outer , I-inner, B-both */#define _ 0#define O 1#define I 2#define B (O|I)#define MINIARCS 5static int arcus0[1]={B};static int arcus1[4]={B,B, B,B};static int arcus2[9]={_,O,_, O,I,O, _,O,_};static int arcus3[16]={_,O,O,_, O,I,I,O, O,I,I,O, _,O,O,_};static int arcus4[25]={_,O,O,O,_, O,I,I,I,O, O,I,I,I,O, O,I,I,I,O, _,O,O,O,_};/* ... someone could add some more here if wanted :-) ... */static int* arcis[MINIARCS]={arcus0,arcus1,arcus2,arcus3,arcus4};static void DrawMiniArc(HDC dc,int width,int x,int y, int mask,COLORREF inner,COLORREF outer) { int *arc; int i,j; if(width>MINIARCS) return; arc=arcis[width]; for(i=0;i<=width;i++){ for(j=0;j<=width;j++){ if(mask&(arc[i*(width+1)+j])&O) SetPixel(dc,x+i,y+j,outer); if(mask&(arc[i*(width+1)+j])&I) SetPixel(dc,x+i,y+j,inner); } }}static voidDrawOrFillArc(display, d, gc, x, y, width, height, start, extent, fill) Display *display; Drawable d; GC gc; int x, y; /* left top */ unsigned int width, height; int start; /* start: three-o'clock (deg*64) */ int extent; /* extent: relative (deg*64) */ int fill; /* ==0 draw, !=0 fill */{ HDC dc; HBRUSH brush;#ifndef USE_CKGRAPH_IMP HBRUSH oldBrush; HPEN oldPen;#endif HPEN pen; TkWinDCState state; int full=0; int clockwise = (extent < 0); /* non-zero if clockwise */ int xstart, ystart, xend, yend; double radian_start, radian_end, xr, yr; if (d == None) { return; } dc = TkWinGetDrawableDC(display, d, &state); CkSetROP2(dc, tkpWinRopModes[gc->function]); /* * Compute the absolute starting and ending angles in normalized radians. * Swap the start and end if drawing clockwise. */ if (start == 0 && extent == 64*360 && width==height ) { full=1; xend= xstart = x + width; yend = ystart = y + (int)(((double)height/2.0)+0.5); goto sel; } start = start % (64*360); if (start < 0) { start += (64*360); } extent = (start+extent) % (64*360); if (extent < 0) { extent += (64*360); } if (clockwise) { int tmp = start; start = extent; extent = tmp; } radian_start = XAngleToRadians(start); radian_end = XAngleToRadians(extent); /* * Now compute points on the radial lines that define the starting and * ending angles. Be sure to take into account that the y-coordinate * system is inverted. */ xr = x + width / 2.0; yr = y + height / 2.0; xstart = (int)((xr + mycos(radian_start)*width/2.0) + 0.5); ystart = (int)((yr + mysin(-radian_start)*height/2.0) + 0.5); xend = (int)((xr + mycos(radian_end)*width/2.0) + 0.5); yend = (int)((yr + mysin(-radian_end)*height/2.0) + 0.5); /* * Now draw a filled or open figure. Note that we have to * increase the size of the bounding box by one to account for the * difference in pixel definitions between X and Windows. */sel: if(full && width==height && width<MINIARCS){ if(!fill) DrawMiniArc(dc,width, x, y,O,0,gc->foreground); else DrawMiniArc(dc,width, x, y,I,gc->foreground,0); goto dcfree; } pen = TkWinCreatePen(gc,PS_SOLID, gc->line_width, gc->foreground);#ifdef USE_CKGRAPH_IMP CkSelectPen(dc, pen);#else oldPen = CkSelectPen(dc, pen);#endif if (!fill) { /* * Note that this call will leave a gap of one pixel at the * end of the arc for thin arcs. We can't use ArcTo because * it's only supported under Windows NT. */ CkArc(dc, x, y, x+width+1, y+height+1, xstart, ystart, xend, yend); } else { brush = TkWinCreateSolidBrush(gc,gc->foreground);#ifdef USE_CKGRAPH_IMP CkSelectBrush(dc, brush);#else oldBrush = CkSelectBrush(dc, brush);#endif if (gc->arc_mode == ArcChord) { CkChord(dc, x, y, x+width+1, y+height+1, xstart, ystart, xend, yend); } else if ( gc->arc_mode == ArcPieSlice ) { CkPie(dc, x, y, x+width+1, y+height+1, xstart, ystart, xend, yend); }#ifdef USE_CKGRAPH_IMP TkWinDeleteBrush(gc,brush);#else TkWinDeleteBrush(gc,CkSelectBrush(dc, oldBrush));#endif }#ifdef USE_CKGRAPH_IMP TkWinDeletePen(gc,pen);#else TkWinDeletePen(gc,CkSelectPen(dc, oldPen));#endifdcfree: TkWinReleaseDrawableDC(d, dc, &state);}/* *---------------------------------------------------------------------- * * TkScrollWindow -- * * Scroll a rectangle of the specified window and accumulate * a damage region. * * Results: * Returns 0 if the scroll genereated no additional damage. * Otherwise, sets the region that needs to be repainted after * scrolling and returns 1. * * Side effects: * Scrolls the bits in the window. * *---------------------------------------------------------------------- */intTkScrollWindow(tkwin, gc, x, y, width, height, dx, dy, damageRgn) Tk_Window tkwin; /* The window to be scrolled. */ GC gc; /* GC for window to be scrolled. */ int x, y, width, height; /* Position rectangle to be scrolled. */ int dx, dy; /* Distance rectangle should be moved. */ TkRegion damageRgn; /* Region to accumulate damage in. */{ HWND hwnd = TkWinGetHWND(Tk_WindowId(tkwin)); RECT scrollRect; scrollRect.left = x; scrollRect.top = y; scrollRect.right = x + width; scrollRect.bottom = y + height; return (ScrollWindowEx(hwnd, dx, dy, &scrollRect, NULL, (HRGN) damageRgn, NULL, 0) == NULLREGION) ? 0 : 1;}/* *---------------------------------------------------------------------- * * TkWinFillRect -- * * This routine fills a rectangle with the foreground color * from the specified GC ignoring all other GC values. This * is the fastest way to fill a drawable with a solid color. * * Results: * None. * * Side effects: * Modifies the contents of the DC drawing surface. * *---------------------------------------------------------------------- */#ifdef FILLRECTGCvoidTkWinFillRectGC(dc, x, y, width, height, pixel,gc) HDC dc; int x, y, width, height; int pixel; GC gc;{ HBRUSH hbr; RECT rect; rect.left = x; rect.top = y; rect.right = x + width; rect.bottom = y + height; GTRACE(("begin TkWinFillRectGC\n");) FillRect(dc,&rect,hbr=TkWinCreateSolidBrush(gc,pixel)); TkWinDeleteBrush(gc,hbr); GTRACE(("end TkWinFillRectGC\n");)}#endifvoidTkWinFillRect(dc, x, y, width, height, pixel) HDC dc; int x, y, width, height; int pixel;{ RECT rect; rect.left = x; rect.top = y; rect.right = x + width; rect.bottom = y + height; GTRACE(("begin TkWinFillRect\n");) CkSetBkColor(dc, (COLORREF)pixel); CkSetBkMode(dc, OPAQUE); CkExtTextOut(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); GTRACE(("end TkWinFillRect\n");)}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -