📄 tkwindraw.c
字号:
*/ HDC memDC, maskDC; HBITMAP bitmap; TkWinDCState maskState; fgBrush = CreateSolidBrush(gc->foreground); bgBrush = CreateSolidBrush(gc->background); maskDC = TkWinGetDrawableDC(display, clipPtr->value.pixmap, &maskState); memDC = CreateCompatibleDC(destDC); bitmap = CreateBitmap(width, height, 1, 1, NULL); SelectObject(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. */ BitBlt(memDC, 0, 0, width, height, srcDC, src_x, src_y, SRCCOPY); BitBlt(memDC, 0, 0, width, height, maskDC, dest_x - gc->clip_x_origin, dest_y - gc->clip_y_origin, SRCAND); oldBrush = SelectObject(destDC, fgBrush); BitBlt(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. */ BitBlt(memDC, 0, 0, width, height, srcDC, src_x, src_y, NOTSRCCOPY); BitBlt(memDC, 0, 0, width, height, maskDC, dest_x - gc->clip_x_origin, dest_y - gc->clip_y_origin, SRCAND); SelectObject(destDC, bgBrush); BitBlt(destDC, dest_x, dest_y, width, height, memDC, 0, 0, MASKPAT); TkWinReleaseDrawableDC(clipPtr->value.pixmap, maskDC, &maskState); SelectObject(destDC, oldBrush); DeleteDC(memDC); DeleteObject(bitmap); DeleteObject(fgBrush); DeleteObject(bgBrush); } } if (src != dest) { TkWinReleaseDrawableDC(dest, destDC, &destState); } TkWinReleaseDrawableDC(src, srcDC, &srcState);}/* *---------------------------------------------------------------------- * * 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++; dc = TkWinGetDrawableDC(display, d, &state); SetROP2(dc, tkpWinRopModes[gc->function]); dcMem = CreateCompatibleDC(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 = CreateBitmap(image->width, image->height, 1, 1, data); ckfree(data); } else { bitmap = CreateBitmap(image->width, image->height, 1, 1, image->data); } SetTextColor(dc, gc->foreground); SetBkColor(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 = CreateDIBitmap(dc, &infoPtr->bmiHeader, CBM_INIT, image->data, infoPtr, DIB_RGB_COLORS); ckfree((char *) infoPtr); } bitmap = SelectObject(dcMem, bitmap); BitBlt(dc, dest_x, dest_y, width, height, dcMem, src_x, src_y, SRCCOPY); DeleteObject(SelectObject(dcMem, bitmap)); DeleteDC(dcMem); TkWinReleaseDrawableDC(d, dc, &state);}/* *---------------------------------------------------------------------- * * 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; HBRUSH brush; if (d == None) { return; } dc = TkWinGetDrawableDC(display, d, &state); SetROP2(dc, tkpWinRopModes[gc->function]); brush = CreateSolidBrush(gc->foreground); if ((gc->fill_style == FillStippled || gc->fill_style == FillOpaqueStippled) && gc->stipple != None) { TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple; HBRUSH oldBrush, stipple; HBITMAP oldBitmap, bitmap; HDC dcMem; HBRUSH bgBrush = CreateSolidBrush(gc->background); if (twdPtr->type != TWD_BITMAP) { panic("unexpected drawable type in stipple"); } /* * Select stipple pattern into destination dc. */ stipple = CreatePatternBrush(twdPtr->bitmap.handle); SetBrushOrgEx(dc, gc->ts_x_origin, gc->ts_y_origin, NULL); oldBrush = SelectObject(dc, stipple); dcMem = CreateCompatibleDC(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 = CreateCompatibleBitmap(dc, rectangles[i].width, rectangles[i].height); oldBitmap = SelectObject(dcMem, bitmap); rect.left = 0; rect.top = 0; rect.right = rectangles[i].width; rect.bottom = rectangles[i].height; FillRect(dcMem, &rect, brush); BitBlt(dc, rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height, dcMem, 0, 0, COPYFG); if (gc->fill_style == FillOpaqueStippled) { FillRect(dcMem, &rect, bgBrush); BitBlt(dc, rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height, dcMem, 0, 0, COPYBG); } SelectObject(dcMem, oldBitmap); DeleteObject(bitmap); } DeleteDC(dcMem); SelectObject(dc, oldBrush); DeleteObject(stipple); DeleteObject(bgBrush); } else { for (i = 0; i < nrectangles; i++) { TkWinFillRect(dc, rectangles[i].x, rectangles[i].y, rectangles[i].width, rectangles[i].height, gc->foreground); } } DeleteObject(brush); TkWinReleaseDrawableDC(d, dc, &state);}/* *---------------------------------------------------------------------- * * RenderObject -- * * This function draws a shape using a list of points, a * stipple pattern, and the specified drawing function. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */static voidRenderObject(dc, gc, points, npoints, mode, pen, func) HDC dc; GC gc; XPoint* points; int npoints; int mode; HPEN pen; WinDrawFunc func;{ RECT rect; HPEN oldPen; HBRUSH oldBrush; POINT *winPoints = ConvertPoints(points, npoints, mode, &rect); if ((gc->fill_style == FillStippled || gc->fill_style == FillOpaqueStippled) && gc->stipple != None) { TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple; HDC dcMem; LONG width, height; HBITMAP oldBitmap; int i; HBRUSH oldMemBrush; 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, NULL); oldBrush = SelectObject(dc, CreatePatternBrush(twdPtr->bitmap.handle)); /* * Create temporary drawing surface containing a copy of the * destination equal in size to the bounding box of the object. */ dcMem = CreateCompatibleDC(dc); oldBitmap = SelectObject(dcMem, CreateCompatibleBitmap(dc, width, height)); oldPen = SelectObject(dcMem, pen); BitBlt(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); oldMemBrush = SelectObject(dcMem, CreateSolidBrush(gc->foreground)); (*func)(dcMem, winPoints, npoints); BitBlt(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) { DeleteObject(SelectObject(dcMem, CreateSolidBrush(gc->background))); (*func)(dcMem, winPoints, npoints); BitBlt(dc, rect.left, rect.top, width, height, dcMem, 0, 0, COPYBG); } SelectObject(dcMem, oldPen); DeleteObject(SelectObject(dcMem, oldMemBrush)); DeleteObject(SelectObject(dcMem, oldBitmap)); DeleteDC(dcMem); } else { oldPen = SelectObject(dc, pen); oldBrush = SelectObject(dc, CreateSolidBrush(gc->foreground)); SetROP2(dc, tkpWinRopModes[gc->function]); SetPolyFillMode(dc, (gc->fill_rule == EvenOddRule) ? ALTERNATE : WINDING); (*func)(dc, winPoints, npoints); SelectObject(dc, oldPen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -