Files
cpython-source-deps/win/tixWinDraw.c
2017-05-22 16:16:49 -05:00

414 lines
11 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* tixWinDraw.c --
*
* Implement the Windows specific function calls for drawing.
*
* Copyright (c) 1993-1999 Ioi Kim Lam.
* Copyright (c) 2000 Tix Project Group.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: tixWinDraw.c,v 1.5 2004/03/28 02:44:57 hobbs Exp $
*/
#include <tkWinInt.h>
#include <tixInt.h>
#include <tixPort.h>
/*----------------------------------------------------------------------
*
* TixpDrawTmpLine --
*
* Draws a "temporarily" line on the desktop window with XOR
* drawing mode. This function is used by the PanedWindow and
* ResizeHandler to draw the rubberband lines. Calling the
* function again with the same parameters cancels the temporary
* lines without affecting what was originally on the screen.
*
* Results:
* None.
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
void
TixpDrawTmpLine(x1, y1, x2, y2, tkwin)
int x1;
int y1;
int x2;
int y2;
Tk_Window tkwin;
{
HWND desktop;
HDC hdc;
HPEN hpen;
HGDIOBJ old;
desktop = GetDesktopWindow();
hdc = GetWindowDC(desktop);
hpen = CreatePen(PS_SOLID, 0, RGB(255,255,255));
old = SelectObject(hdc, hpen);
SetROP2(hdc, R2_XORPEN);
MoveToEx(hdc, x1, y1, NULL);
LineTo(hdc, x2, y2);
SelectObject(hdc, old);
DeleteObject(hpen);
ReleaseDC(desktop, hdc);
}
/*
*----------------------------------------------------------------------
*
* TixpDrawAnchorLines --
*
* See comments near Tix_DrawAnchorLines in tixUtils.c.
*
* Results:
* None.
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
void
TixpDrawAnchorLines(display, drawable, gc, x, y, w, h)
Display *display;
Drawable drawable;
GC gc;
int x;
int y;
int w;
int h;
{
HDC hdc;
TkWinDCState state;
RECT rect;
if (w < 2 || h < 2) {
/*
* Area too small to show effect. Don't bother
*/
return;
}
hdc = TkWinGetDrawableDC(display, drawable, &state);
rect.left = x;
rect.top = y;
rect.right = x+w;
rect.bottom = y+h;
DrawFocusRect(hdc, &rect);
TkWinReleaseDrawableDC(drawable, hdc, &state);
}
/*
*----------------------------------------------------------------------
*
* TixpStartSubRegionDraw --
*
* This function is used by the Tix DItem code to implement
* clipped rendering -- if a DItem is larger than the region
* where the DItem is displayed (with the Tix_DItemDisplay
* function), we clip the DItem so that all the rendering
* happens inside the region.
*
* This Win32 implementation is tricky (which explains why the
* TixpSubRegDrawXXX API looks so arcane.) Tk does not support
* a portable API for setting the clip region of a GC. We could
* hack into Tk's Win32 implementation of GC to get the clipping
* to work, but that may run into future incompatibilities.
*
* For a clean and (almost) portable, albeit a bit slow,
* implemetation of clipping, we allocate a pixmap when clipping
* is required. All subsequent drawing goes into this
* pixmap. When TixpEndSubRegionDraw is called we then copy from
* the pixmap back to the destination drawable.
*
* Results:
* None.
*
* Side effects:
* A Tk pixmap may be created and saved into subRegPtr->pixmap in
* for the clipped drawing operations.
*
*----------------------------------------------------------------------
*/
void
TixpStartSubRegionDraw(display, drawable, gc, subRegPtr, origX, origY,
x, y, width, height, needWidth, needHeight)
Display *display;
Drawable drawable;
GC gc;
TixpSubRegion * subRegPtr;
int origX;
int origY;
int x;
int y;
int width;
int height;
int needWidth;
int needHeight;
{
TkWinDrawable * wdrPtr;
int depth;
if ((width < needWidth) || (height < needHeight)) {
subRegPtr->origX = origX;
subRegPtr->origY = origY;
subRegPtr->x = x;
subRegPtr->y = y;
subRegPtr->width = width;
subRegPtr->height = height;
/*
* Find out the depth of the drawable and create a pixmap of
* the same depth.
*/
wdrPtr = (TkWinDrawable *)drawable;
if (wdrPtr->type == TWD_BITMAP) {
depth = wdrPtr->bitmap.depth;
} else {
depth = wdrPtr->window.winPtr->depth;
}
subRegPtr->pixmap = Tk_GetPixmap(display, drawable, width, height,
depth);
if (subRegPtr->pixmap != None) {
/*
* It could be None if we have somehow exhausted the Windows
* GDI resources.
*/
XCopyArea(display, drawable, subRegPtr->pixmap, gc, x, y,
(unsigned) width, (unsigned) height, 0, 0);
}
} else {
subRegPtr->pixmap = None;
}
}
/*----------------------------------------------------------------------
* TixpEndSubRegionDraw --
*
*
*----------------------------------------------------------------------
*/
void
TixpEndSubRegionDraw(display, drawable, gc, subRegPtr)
Display *display;
Drawable drawable;
GC gc;
TixpSubRegion * subRegPtr;
{
if (subRegPtr->pixmap != None) {
XCopyArea(display, subRegPtr->pixmap, drawable, gc, 0, 0,
(unsigned) subRegPtr->width, (unsigned) subRegPtr->height,
subRegPtr->x, subRegPtr->y);
Tk_FreePixmap(display, subRegPtr->pixmap);
subRegPtr->pixmap = None;
}
}
void
TixpSubRegSetClip(display, subRegPtr, gc)
Display *display;
TixpSubRegion * subRegPtr;
GC gc;
{
/* Do nothing */
}
void
TixpSubRegUnsetClip(display, subRegPtr, gc)
Display *display;
TixpSubRegion * subRegPtr;
GC gc;
{
/* Do nothing */
}
/*
*----------------------------------------------------------------------
*
* TixpSubRegDisplayText --
*
* Display a text string on one or more lines in a sub region.
*
* Results:
* See TkDisplayText
*
* Side effects:
* See TkDisplayText
*
*----------------------------------------------------------------------
*/
void
TixpSubRegDisplayText(display, drawable, gc, subRegPtr, font, string,
numChars, x, y, length, justify, underline)
Display *display; /* X display to use for drawing text. */
Drawable drawable; /* Window or pixmap in which to draw the
* text. */
GC gc; /* Graphics context to use for drawing text. */
TixpSubRegion * subRegPtr; /* Information about the subregion */
TixFont font; /* Font that determines geometry of text
* (should be same as font in gc). */
CONST84 char *string; /* String to display; may contain embedded
* newlines. */
int numChars; /* Number of characters to use from string. */
int x, y; /* Pixel coordinates within drawable of
* upper left corner of display area. */
int length; /* Line length in pixels; used to compute
* word wrap points and also for
* justification. Must be > 0. */
Tk_Justify justify; /* How to justify lines. */
int underline; /* Index of character to underline, or < 0
* for no underlining. */
{
if (subRegPtr->pixmap != None) {
TixDisplayText(display, subRegPtr->pixmap, font, string,
numChars, x - subRegPtr->x, y - subRegPtr->y,
length, justify, underline, gc);
} else {
TixDisplayText(display, drawable, font, string,
numChars, x, y, length, justify, underline, gc);
}
}
/*----------------------------------------------------------------------
* TixpSubRegFillRectangle --
*
*
*----------------------------------------------------------------------
*/
void
TixpSubRegFillRectangle(display, drawable, gc, subRegPtr, x, y, width, height)
Display *display; /* X display to use for drawing rectangle. */
Drawable drawable; /* Window or pixmap in which to draw the
* rectangle. */
GC gc; /* Graphics context to use for drawing. */
TixpSubRegion * subRegPtr; /* Information about the subregion */
int x, y; /* Pixel coordinates within drawable of
* upper left corner of display area. */
int width, height; /* Size of the rectangle. */
{
if (subRegPtr->pixmap != None) {
XFillRectangle(display, subRegPtr->pixmap, gc,
x - subRegPtr->x, y - subRegPtr->y, width, height);
} else {
XFillRectangle(display, drawable, gc, x, y, width, height);
}
}
/*----------------------------------------------------------------------
* TixpSubRegDrawImage --
*
* Draws a Tk image in a subregion.
*----------------------------------------------------------------------
*/
void
TixpSubRegDrawImage(subRegPtr, image, imageX, imageY, width, height,
drawable, drawableX, drawableY)
TixpSubRegion * subRegPtr;
Tk_Image image;
int imageX;
int imageY;
int width;
int height;
Drawable drawable;
int drawableX;
int drawableY;
{
Drawable dest;
if (subRegPtr->pixmap != None) {
dest = subRegPtr->pixmap;
drawableX -= subRegPtr->x;
drawableY -= subRegPtr->y;
} else {
dest = drawable;
}
Tk_RedrawImage(image, imageX, imageY, width, height, dest,
drawableX, drawableY);
}
void
TixpSubRegDrawBitmap(display, drawable, gc, subRegPtr, bitmap, src_x, src_y,
width, height, dest_x, dest_y, plane)
Display *display;
Drawable drawable;
GC gc;
TixpSubRegion * subRegPtr;
Pixmap bitmap;
int src_x, src_y;
int width, height;
int dest_x, dest_y;
unsigned long plane;
{
XSetClipOrigin(display, gc, dest_x, dest_y);
if (subRegPtr->pixmap != None) {
XCopyPlane(display, bitmap, subRegPtr->pixmap, gc, src_x, src_y,
width, height, dest_x - subRegPtr->x, dest_y - subRegPtr->y,
plane);
} else {
XCopyPlane(display, bitmap, drawable, gc, src_x, src_y, width, height,
dest_x, dest_y, plane);
}
XSetClipOrigin(display, gc, 0, 0);
}
/*
*----------------------------------------------------------------------
*
* TixpSubRegDrawAnchorLines --
*
* Draw anchor lines inside the given sub region.
*
* Results:
* None.
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
void
TixpSubRegDrawAnchorLines(display, drawable, gc, subRegPtr, x, y, w, h)
Display *display; /* Display to draw on. */
Drawable drawable; /* Drawable to draw on. */
GC gc; /* Use the foreground color of this GC. */
TixpSubRegion * subRegPtr; /* Describes the subregion. */
int x; /* x pos of top-left corner of anchor rect */
int y; /* y pos of top-left corner of anchor rect */
int w; /* width of anchor rect */
int h; /* height of anchor rect */
{
Drawable dest;
if (subRegPtr->pixmap != None) {
dest = subRegPtr->pixmap;
x -= subRegPtr->x;
y -= subRegPtr->y;
} else {
dest = drawable;
}
TixpDrawAnchorLines(display, dest, gc, x, y, w, h);
}