📄 tkwindraw.c
字号:
fgBrush = TkWinCreateSolidBrush(gc,gc->foreground);#ifdef USE_CKGRAPH_IMP //Oops,the Tcl/Tk appeared brown in the bitmap ... //so reset the DC correctly CkGraph_ClearDC(destDC); CkGraph_ClearDC(srcDC); CkSelectBrush(destDC, fgBrush);#else oldBrush = CkSelectBrush(destDC, fgBrush);#endif CkBitBlt(destDC, dest_x, dest_y, width, height, srcDC, src_x, src_y, MASKPAT);#ifndef USE_CKGRAPH_IMP CkSelectBrush(destDC, oldBrush);#endif TkWinDeleteBrush(gc,fgBrush); } else { /* * Case 3: two arbitrary bitmaps. Copy the source rectangle * into a color pixmap. Use the result as a brush when * copying the clip mask into the destination. */ HDC memDC, maskDC; HBITMAP bitmap; TkWinDCState maskState; fgBrush = TkWinCreateSolidBrush(gc,gc->foreground); bgBrush = TkWinCreateSolidBrush(gc,gc->background); maskDC = TkWinGetDrawableDC(display, clipPtr->value.pixmap, &maskState); memDC = CkCreateCompatibleDC(destDC); bitmap = CkCreateBitmap(width, height, 1, 1, NULL); CkSelectBitmap(memDC, bitmap); /* * Set foreground bits. We create a new bitmap containing * (source AND mask), then use it to set the foreground color * into the destination. */ CkBitBlt(memDC, 0, 0, width, height, srcDC, src_x, src_y, SRCCOPY); CkBitBlt(memDC, 0, 0, width, height, maskDC, dest_x - gc->clip_x_origin, dest_y - gc->clip_y_origin, SRCAND);#ifdef USE_CKGRAPH_IMP CkSelectBrush(destDC, fgBrush);#else oldBrush = CkSelectBrush(destDC, fgBrush);#endif CkBitBlt(destDC, dest_x, dest_y, width, height, memDC, 0, 0, MASKPAT); /* * Set background bits. Same as foreground, except we use * ((NOT source) AND mask) and the background brush. */ CkBitBlt(memDC, 0, 0, width, height, srcDC, src_x, src_y, NOTSRCCOPY); CkBitBlt(memDC, 0, 0, width, height, maskDC, dest_x - gc->clip_x_origin, dest_y - gc->clip_y_origin, SRCAND); CkSelectBrush(destDC, bgBrush); CkBitBlt(destDC, dest_x, dest_y, width, height, memDC, 0, 0, MASKPAT); TkWinReleaseDrawableDC(clipPtr->value.pixmap, maskDC, &maskState);#ifndef USE_CKGRAPH_IMP CkSelectBrush(destDC, oldBrush);#endif CkDeleteDC(memDC); CkDeleteBitmap(bitmap); TkWinDeleteBrush(gc,fgBrush); TkWinDeleteBrush(gc,bgBrush); } } if (src != dest) { TkWinReleaseDrawableDC(dest, destDC, &destState); } TkWinReleaseDrawableDC(src, srcDC, &srcState); GTRACE(("end XCopyPlane\n");)}/* *---------------------------------------------------------------------- * * TkPutImage -- * * Copies a subimage from an in-memory image to a rectangle of * of the specified drawable. * * Results: * None. * * Side effects: * Draws the image on the specified drawable. * *---------------------------------------------------------------------- */voidTkPutImage(colors, ncolors, display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height) unsigned long *colors; /* Array of pixel values used by this * image. May be NULL. */ int ncolors; /* Number of colors used, or 0. */ Display* display; Drawable d; /* Destination drawable. */ GC gc; XImage* image; /* Source image. */ int src_x, src_y; /* Offset of subimage. */ int dest_x, dest_y; /* Position of subimage origin in * drawable. */ unsigned int width, height; /* Dimensions of subimage. */{ HDC dc, dcMem; TkWinDCState state; BITMAPINFO *infoPtr; HBITMAP bitmap; char *data; display->request++; GTRACE(("begin TkPutImage\n");) dc = TkWinGetDrawableDC(display, d, &state); CkSetROP2(dc, tkpWinRopModes[gc->function]); dcMem = CkCreateCompatibleDC(dc); if (image->bits_per_pixel == 1) { /* * If the image isn't in the right format, we have to copy * it into a new buffer in MSBFirst and word-aligned format. */ if ((image->bitmap_bit_order != MSBFirst) || (image->bitmap_pad != sizeof(WORD))) { data = TkAlignImageData(image, sizeof(WORD), MSBFirst); bitmap = CkCreateBitmap(image->width, image->height, 1, 1, data); ckfree(data); } else { bitmap = CkCreateBitmap(image->width, image->height, 1, 1, image->data); } CkSetTextColor(dc, gc->foreground); CkSetBkColor(dc, gc->background); } else { int i, usePalette; /* * Do not use a palette for TrueColor images. */ usePalette = (image->bits_per_pixel < 16); if (usePalette) { infoPtr = (BITMAPINFO*) ckalloc(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*ncolors); } else { infoPtr = (BITMAPINFO*) ckalloc(sizeof(BITMAPINFOHEADER)); } infoPtr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); infoPtr->bmiHeader.biWidth = image->width; /* * The following code works around a bug in Win32s. CreateDIBitmap * fails under Win32s for top-down images. So we have to reverse the * order of the scanlines. If we are not running under Win32s, we can * just declare the image to be top-down. */ if (tkpIsWin32s) { int y; char *srcPtr, *dstPtr, *temp; temp = ckalloc((unsigned) image->bytes_per_line); srcPtr = image->data; dstPtr = image->data+(image->bytes_per_line * (image->height - 1)); for (y = 0; y < (image->height/2); y++) { memcpy(temp, srcPtr, image->bytes_per_line); memcpy(srcPtr, dstPtr, image->bytes_per_line); memcpy(dstPtr, temp, image->bytes_per_line); srcPtr += image->bytes_per_line; dstPtr -= image->bytes_per_line; } ckfree(temp); infoPtr->bmiHeader.biHeight = image->height; /* Bottom-up order */ } else { infoPtr->bmiHeader.biHeight = -image->height; /* Top-down order */ } infoPtr->bmiHeader.biPlanes = 1; infoPtr->bmiHeader.biBitCount = image->bits_per_pixel; infoPtr->bmiHeader.biCompression = BI_RGB; infoPtr->bmiHeader.biSizeImage = 0; infoPtr->bmiHeader.biXPelsPerMeter = 0; infoPtr->bmiHeader.biYPelsPerMeter = 0; infoPtr->bmiHeader.biClrImportant = 0; if (usePalette) { infoPtr->bmiHeader.biClrUsed = ncolors; for (i = 0; i < ncolors; i++) { infoPtr->bmiColors[i].rgbBlue = GetBValue(colors[i]); infoPtr->bmiColors[i].rgbGreen = GetGValue(colors[i]); infoPtr->bmiColors[i].rgbRed = GetRValue(colors[i]); infoPtr->bmiColors[i].rgbReserved = 0; } } else { infoPtr->bmiHeader.biClrUsed = 0; } bitmap = CkCreateDIBitmap(dc, &infoPtr->bmiHeader, CBM_INIT, image->data, infoPtr, DIB_RGB_COLORS); ckfree((char *) infoPtr); }#ifdef USE_CKGRAPH_IMP CkSelectBitmap(dcMem, bitmap);#else bitmap = CkSelectBitmap(dcMem, bitmap);#endif CkBitBlt(dc, dest_x, dest_y, width, height, dcMem, src_x, src_y, SRCCOPY); CkDeleteDC(dcMem);#ifdef USE_CKGRAPH_IMP CkDeleteBitmap(bitmap);#else CkDeleteBitmap(CkSelectBitmap(dcMem, bitmap));#endif TkWinReleaseDrawableDC(d, dc, &state); GTRACE(("end TkPutImage\n");)}/* *---------------------------------------------------------------------- * * XFillRectangles -- * * Fill multiple rectangular areas in the given drawable. * * Results: * None. * * Side effects: * Draws onto the specified drawable. * *---------------------------------------------------------------------- */voidXFillRectangles(display, d, gc, rectangles, nrectangles) Display* display; Drawable d; GC gc; XRectangle* rectangles; int nrectangles;{ HDC dc; int i; RECT rect; TkWinDCState state; if (d == None) { return; } GTRACE(("begin XFillRectangles(..%d)\n",nrectangles);) dc = TkWinGetDrawableDC(display, d, &state); CkSetROP2(dc, tkpWinRopModes[gc->function]); if ((gc->fill_style == FillStippled || gc->fill_style == FillOpaqueStippled) && gc->stipple != None) { TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple; POINT brushOrg;#ifndef USE_CKGRAPH_IMP HBRUSH oldBrush; HBITMAP oldBitmap;#endif HBRUSH stipple; HBITMAP bitmap; HDC dcMem; HBRUSH brush = TkWinCreateSolidBrush(gc,gc->foreground); HBRUSH bgBrush = TkWinCreateSolidBrush(gc,gc->background); if (twdPtr->type != TWD_BITMAP) { panic("unexpected drawable type in stipple"); } /* * Select stipple pattern into destination dc. */ stipple = CkCreatePatternBrush(twdPtr->bitmap.handle); SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, &brushOrg);#ifdef USE_CKGRAPH_IMP CkGraph_ClearDC(dc); CkSelectBrush(dc, stipple);#else oldBrush = CkSelectBrush(dc, stipple);#endif dcMem = CkCreateCompatibleDC(dc); /* * For each rectangle, create a drawing surface which is the size of * the rectangle and fill it with the background color. Then merge the * result with the stipple pattern. */ for (i = 0; i < nrectangles; i++) { bitmap = CkCreateCompatibleBitmap(dc, rectangles[i].width, rectangles[i].height);#ifdef USE_CKGRAPH_IMP CkSelectBitmap(dcMem, bitmap);#else oldBitmap = CkSelectBitmap(dcMem, bitmap);#endif rect.left = 0; rect.top = 0; rect.right = rectangles[i].width; rect.bottom = rectangles[i].height; CkFillRect(dcMem, &rect, brush); CkBitBlt(dc, rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height, dcMem, 0, 0, COPYFG); if (gc->fill_style == FillOpaqueStippled) { CkFillRect(dcMem, &rect, bgBrush); CkBitBlt(dc, rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height, dcMem, 0, 0, COPYBG); }#ifndef USE_CKGRAPH_IMP CkSelectBitmap(dcMem, oldBitmap);#endif CkDeleteBitmap(bitmap); } CkDeleteDC(dcMem);#ifndef USE_CKGRAPH_IMP CkSelectBrush(dc, oldBrush);#endif CkDeleteBrush(stipple); TkWinDeleteBrush(gc,bgBrush); TkWinDeleteBrush(gc,brush); SetBrushOrgEx(dc, brushOrg.x, brushOrg.y, NULL); } else { for (i = 0; i < nrectangles; i++) {#ifdef FILLRECTGC TkWinFillRectGC(dc, rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height, gc->foreground,gc);#else TkWinFillRect(dc, rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height, gc->foreground);#endif } } TkWinReleaseDrawableDC(d, dc, &state); GTRACE(("end XFillRectangles(..%d)\n",nrectangles);)}/* *---------------------------------------------------------------------- * * RenderObject -- * * This function draws a shape using a list of points, a * stipple pattern, and the specified drawing function type. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */static voidRenderObject(dc, gc, points, npoints, mode, pen, functype) HDC dc; GC gc; XPoint* points; int npoints; int mode; HPEN pen; int functype;{ RECT rect;#ifndef USE_CKGRAPH_IMP HPEN oldPen; HBRUSH oldBrush;#endif POINT *winPoints = ConvertPoints(points, npoints, mode, &rect); GTRACE(("begin RenderObject\n");) if ((gc->fill_style == FillStippled || gc->fill_style == FillOpaqueStippled) && gc->stipple != None) { TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple; HDC dcMem; LONG width, height; int i; POINT brushOrg;#ifdef USE_CKGRAPH_IMP HBRUSH fgBrush; HBRUSH bgBrush=(HBRUSH)NULL; HBRUSH patBrush; HBITMAP bitmap; CkGraph_ClearDC(dc);#else HBITMAP oldBitmap; HBRUSH oldMemBrush;#endif if (twdPtr->type != TWD_BITMAP) { panic("unexpected drawable type in stipple"); } /* * Grow the bounding box enough to account for wide lines. */ if (gc->line_width > 1) { rect.left -= gc->line_width; rect.top -= gc->line_width; rect.right += gc->line_width; rect.bottom += gc->line_width; } width = rect.right - rect.left; height = rect.bottom - rect.top; /* * Select stipple pattern into destination dc. */ SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, &brushOrg);#ifdef USE_CKGRAPH_IMP CkSelectBrush(dc,patBrush=CkCreatePatternBrush(twdPtr->bitmap.handle));#else oldBrush = CkSelectBrush(dc, CkCreatePatternBrush(twdPtr->bitmap.handle));#endif /* * Create temporary drawing surface containing a copy of the * destination equal in size to the bounding box of the object. */ dcMem = CkCreateCompatibleDC(dc);#ifdef USE_CKGRAPH_IMP CkSelectPen(dcMem, pen); CkSelectBitmap(dcMem, bitmap=CkCreateCompatibleBitmap(dc, width, height));#else oldBitmap = CkSelectBitmap(dcMem, CkCreateCompatibleBitmap(dc, width, height)); oldPen = CkSelectPen(dcMem, pen);#endif CkBitBlt(dcMem, 0, 0, width, height, dc, rect.left, rect.top, SRCCOPY); /* * Translate the object for rendering in the temporary drawing * surface. */ for (i = 0; i < npoints; i++) { winPoints[i].x -= rect.left; winPoints[i].y -= rect.top; } /* * Draw the object in the foreground color and copy it to the * destination wherever the pattern is set. */ SetPolyFillMode(dcMem, (gc->fill_rule == EvenOddRule) ? ALTERNATE : WINDING);#ifdef USE_CKGRAPH_IMP CkSelectBrush(dcMem, fgBrush=TkWinCreateSolidBrush(gc,gc->foreground));#else oldMemBrush = CkSelectBrush(dcMem, TkWinCreateSolidBrush(gc,gc->foreground));#endif POLYFUNC(functype, dcMem, winPoints, npoints); CkBitBlt(dc, rect.left, rect.top, width, height, dcMem, 0, 0, COPYFG); /* * If we are rendering an opaque stipple, then draw the polygon in the * background color and copy it to the destination wherever the pattern * is clear. */ if (gc->fill_style == FillOpaqueStippled) {#ifdef USE_CKGRAPH_IMP CkSelectBrush(dcMem,bgBrush=TkWinCreateSolidBrush(gc,gc->background));#else TkWinDeleteBrush(gc,CkSelectBrush(dcMem, TkWinCreateSolidBrush(gc,gc->background)));#endif POLYFUNC(functype, dcMem, winPoints, npoints); CkBitBlt(dc, rect.left, rect.top, width, height, dcMem, 0, 0, COPYBG); }#ifdef USE_CKGRAPH_IMP CkDeleteDC(dcMem); CkDeleteBrush(patBrush); TkWinDeleteBrush(gc,fgBrush); if(bgBrush!=NULL) TkWinDeleteBrush(gc,bgBrush); CkDeleteBitmap(bitmap);#else CkSelectPen(dcMem, oldPen); TkWinDeleteBrush(gc,CkSelectBrush(dcMem, oldMemBrush)); CkDeleteBitmap(CkSelectBitmap(dcMem, oldBitmap)); CkDeleteDC(dcMem);#endif SetBrushOrgEx(dc, brushOrg.x, brushOrg.y, NULL); } else {#ifdef USE_CKGRAPH_IMP HBRUSH hBrush; CkSelectPen(dc, pen); CkSelectBrush(dc,hBrush=TkWinCreateSolidBrush(gc,gc->foreground));#else oldPen = CkSelectPen(dc, pen); oldBrush = CkSelectBrush(dc, TkWinCreateSolidBrush(gc,gc->foreground));#endif CkSetROP2(dc, tkpWinRopModes[gc->function]); CkSetPolyFillMode(dc, (gc->fill_rule == EvenOddRule) ? ALTERNATE : WINDING); POLYFUNC(functype, dc, winPoints, npoints);#ifdef USE_CKGRAPH_IMP TkWinDeleteBrush(gc,hBrush);#else CkSelectPen(dc, oldPen);#endif }#ifndef USE_CKGRAPH_IMP TkWinDeleteBrush(gc,CkSelectBrush(dc, oldBrush));#endif GTRACE(("end RenderObject\n");)}/* *---------------------------------------------------------------------- * * XDrawLines -- * * Draw connected lines.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -