archie/tk4.2/mac/tkMacDraw.c
2024-05-27 16:40:40 +02:00

1067 lines
25 KiB
C
Raw 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.

/*
* tkMacDraw.c --
*
* This file contains functions that preform drawing to
* Xlib windows. Most of the functions simple emulate
* Xlib functions.
*
* Copyright (c) 1995-1996 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* SCCS: @(#) tkMacDraw.c 1.43 96/09/05 13:38:18
*/
#include "tkInt.h"
#include "X.h"
#include "Xlib.h"
#include <stdio.h>
#include <tcl.h>
#include <Windows.h>
#include <Fonts.h>
#include <QDOffscreen.h>
#include "tkMacInt.h"
#ifndef PI
# define PI 3.14159265358979323846
#endif
/*
* Temporary region that can be reused.
*/
static RgnHandle tmpRgn = NULL;
static PixPatHandle gPenPat = NULL;
/*
* Prototypes for functions used only in this file.
*/
static BitMapPtr MakeStippleMap _ANSI_ARGS_((Drawable drawable,
Drawable stipple));
static unsigned char InvertByte _ANSI_ARGS_((unsigned char data));
/*
*----------------------------------------------------------------------
*
* XCopyArea --
*
* Copies data from one drawable to another using block transfer
* routines.
*
* Results:
* None.
*
* Side effects:
* Data is moved from a window or bitmap to a second window or
* bitmap.
*
*----------------------------------------------------------------------
*/
void
XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y)
Display* display;
Drawable src;
Drawable dest;
GC gc;
int src_x;
int src_y;
unsigned int width;
unsigned int height;
int dest_x;
int dest_y;
{
Rect srcRect, destRect;
BitMapPtr srcBit, destBit;
MacDrawable *srcDraw = (MacDrawable *) src;
MacDrawable *destDraw = (MacDrawable *) dest;
GWorldPtr srcPort, destPort;
CGrafPtr saveWorld;
GDHandle saveDevice;
short tmode;
destPort = TkMacGetDrawablePort(dest);
srcPort = TkMacGetDrawablePort(src);
display->request++;
GetGWorld(&saveWorld, &saveDevice);
SetGWorld(destPort, NULL);
TkMacSetUpClippingRgn(dest);
srcBit = &((GrafPtr) srcPort)->portBits;
destBit = &((GrafPtr) destPort)->portBits;
SetRect(&srcRect, (short) (srcDraw->xOff + src_x),
(short) (srcDraw->yOff + src_y),
(short) (srcDraw->xOff + src_x + width),
(short) (srcDraw->yOff + src_y + height));
SetRect(&destRect, (short) (destDraw->xOff + dest_x),
(short) (destDraw->yOff + dest_y),
(short) (destDraw->xOff + dest_x + width),
(short) (destDraw->yOff + dest_y + height));
tmode = srcCopy;
CopyBits(srcBit, destBit, &srcRect, &destRect, tmode, NULL);
SetGWorld(saveWorld, saveDevice);
}
/*
*----------------------------------------------------------------------
*
* XCopyPlane --
*
* Copies a bitmap from a source drawable to a destination
* drawable. The plane argument specifies which bit plane of
* the source contains the bitmap. Note that this implementation
* ignores the gc->function.
*
* Results:
* None.
*
* Side effects:
* Changes the destination drawable.
*
*----------------------------------------------------------------------
*/
void
XCopyPlane(display, src, dest, gc, src_x, src_y,
width, height, dest_x, dest_y, plane)
Display* display;
Drawable src;
Drawable dest;
GC gc;
int src_x;
int src_y;
unsigned int width;
unsigned int height;
int dest_x;
int dest_y;
unsigned long plane;
{
Rect srcRect, destRect;
BitMapPtr srcBit, destBit;
MacDrawable *srcDraw = (MacDrawable *) src;
MacDrawable *destDraw = (MacDrawable *) dest;
GWorldPtr srcPort, destPort;
CGrafPtr saveWorld;
GDHandle saveDevice;
RGBColor macColor;
short tmode;
destPort = TkMacGetDrawablePort(dest);
srcPort = TkMacGetDrawablePort(src);
display->request++;
GetGWorld(&saveWorld, &saveDevice);
SetGWorld(destPort, NULL);
TkMacSetUpClippingRgn(dest);
srcBit = &((GrafPtr) srcPort)->portBits;
destBit = &((GrafPtr) destPort)->portBits;
SetRect(&srcRect, (short) (srcDraw->xOff + src_x),
(short) (srcDraw->yOff + src_y),
(short) (srcDraw->xOff + src_x + width),
(short) (srcDraw->yOff + src_y + height));
SetRect(&destRect, (short) (destDraw->xOff + dest_x),
(short) (destDraw->yOff + dest_y),
(short) (destDraw->xOff + dest_x + width),
(short) (destDraw->yOff + dest_y + height));
tmode = srcOr;
if (TkSetMacColor(gc->foreground, &macColor) == true) {
RGBForeColor(&macColor);
}
if (TkSetMacColor(gc->background, &macColor) == true) {
RGBBackColor(&macColor);
tmode = srcCopy;
}
CopyBits(srcBit, destBit, &srcRect, &destRect, tmode, NULL);
SetGWorld(saveWorld, saveDevice);
}
/*
*----------------------------------------------------------------------
*
* 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.
*
*----------------------------------------------------------------------
*/
void
TkPutImage(colors, ncolors, display, d, gc, image, src_x, src_y,
dest_x, dest_y, width, height)
unsigned long *colors;
int ncolors;
Display* display;
Drawable d;
GC gc;
XImage* image;
int src_x;
int src_y;
int dest_x;
int dest_y;
unsigned int width;
unsigned int height;
{
MacDrawable *destDraw = (MacDrawable *) d;
CGrafPtr saveWorld;
GDHandle saveDevice;
GWorldPtr destPort;
int i, j;
BitMap bitmap;
char *newData = NULL;
Rect destRect, srcRect;
destPort = TkMacGetDrawablePort(d);
SetRect(&destRect, dest_x, dest_y, dest_x + width, dest_y + height);
SetRect(&srcRect, src_x, src_y, src_x + width, src_y + height);
display->request++;
GetGWorld(&saveWorld, &saveDevice);
SetGWorld(destPort, NULL);
TkMacSetUpClippingRgn(d);
if (image->depth == 1) {
/*
* This code assumes a pixel depth of 1
*/
bitmap.bounds.top = bitmap.bounds.left = 0;
bitmap.bounds.right = (short) image->width;
bitmap.bounds.bottom = (short) image->height;
if ((image->bytes_per_line % 2) == 1) {
char *newPtr, *oldPtr;
newData = (char *) ckalloc(image->height *
(image->bytes_per_line + 1));
newPtr = newData;
oldPtr = image->data;
for (i = 0; i < image->height; i++) {
for (j = 0; j < image->bytes_per_line; j++) {
*newPtr = InvertByte((unsigned char) *oldPtr);
newPtr++, oldPtr++;
}
*newPtr = 0;
newPtr++;
}
bitmap.baseAddr = newData;
bitmap.rowBytes = image->bytes_per_line + 1;
} else {
newData = (char *) ckalloc(image->height * image->bytes_per_line);
for (i = 0; i < image->height * image->bytes_per_line; i++) {
newData[i] = InvertByte((unsigned char) image->data[i]);
}
bitmap.baseAddr = newData;
bitmap.rowBytes = image->bytes_per_line;
}
CopyBits(&bitmap, &((GrafPtr) destPort)->portBits,
&srcRect, &destRect, srcCopy, NULL);
} else {
/* Color image */
PixMap pixmap;
pixmap.bounds.left = 0;
pixmap.bounds.top = 0;
pixmap.bounds.right = (short) image->width;
pixmap.bounds.bottom = (short) image->height;
pixmap.pixelType = RGBDirect;
pixmap.pmVersion = 4; /* 32bit clean */
pixmap.packType = 0;
pixmap.packSize = 0;
pixmap.hRes = 0x00480000;
pixmap.vRes = 0x00480000;
pixmap.pixelSize = 32;
pixmap.cmpCount = 3;
pixmap.cmpSize = 8;
pixmap.planeBytes = 0;
pixmap.pmTable = NULL;
pixmap.pmReserved = 0;
pixmap.baseAddr = image->data;
pixmap.rowBytes = image->bytes_per_line | 0x8000;
CopyBits((BitMap *) &pixmap, &((GrafPtr) destPort)->portBits,
&srcRect, &destRect, srcCopy, NULL);
}
if (newData != NULL) {
ckfree(newData);
}
SetGWorld(saveWorld, saveDevice);
}
/*
*----------------------------------------------------------------------
*
* XDrawString --
*
* Draw a single string in the current font.
*
* Results:
* None.
*
* Side effects:
* Renders the specified string in the drawable.
*
*----------------------------------------------------------------------
*/
void
XDrawString(display, d, gc, x, y, string, length)
Display* display;
Drawable d;
GC gc;
int x;
int y;
const char* string;
int length;
{
MacDrawable *macWin = (MacDrawable *) d;
CGrafPtr saveWorld;
GWorldPtr destPort;
BitMapPtr stippleMap;
GDHandle saveDevice;
RGBColor macColor;
short txFont, txFace, txSize;
short family, style, size;
destPort = TkMacGetDrawablePort(d);
display->request++;
GetGWorld(&saveWorld, &saveDevice);
SetGWorld(destPort, NULL);
TkMacSetUpClippingRgn(d);
TkMacSetUpGraphicsPort(gc);
TkMacFontInfo(gc->font, &family, &style, &size);
txFont = qd.thePort->txFont;
txFace = qd.thePort->txFace;
txSize = qd.thePort->txSize;
if ((gc->fill_style == FillStippled
|| gc->fill_style == FillOpaqueStippled)
&& gc->stipple != None) {
Pixmap pixmap;
GWorldPtr bufferPort;
stippleMap = MakeStippleMap(d, gc->stipple);
pixmap = Tk_GetPixmap(display, d,
stippleMap->bounds.right, stippleMap->bounds.bottom, 0);
bufferPort = TkMacGetDrawablePort(pixmap);
SetGWorld(bufferPort, NULL);
TextFont(family);
TextSize(size);
TextFace(style);
if (TkSetMacColor(gc->foreground, &macColor) == true) {
RGBForeColor(&macColor);
}
ShowPen();
MoveTo((short) 0, (short) 0);
FillRect(&stippleMap->bounds, &qd.white);
MoveTo((short) x, (short) y);
DrawText(string, 0, (short) length);
destPort = TkMacGetDrawablePort(d);
SetGWorld(destPort, NULL);
CopyDeepMask(&((GrafPtr) bufferPort)->portBits, stippleMap,
&((GrafPtr) destPort)->portBits, &stippleMap->bounds, &stippleMap->bounds,
&((GrafPtr) destPort)->portRect /* Is this right? */, srcOr, NULL);
/* TODO: this doesn't work quite right - it does a blend. you can't draw white
text when you have a stipple.
*/
Tk_FreePixmap(display, pixmap);
ckfree(stippleMap->baseAddr);
ckfree((char *)stippleMap);
} else {
TextFont(family);
TextSize(size);
TextFace(style);
if (TkSetMacColor(gc->foreground, &macColor) == true) {
RGBForeColor(&macColor);
}
ShowPen();
MoveTo((short) (macWin->xOff + x), (short) (macWin->yOff + y));
DrawText(string, 0, (short) length);
}
TextFont(txFont);
TextSize(txSize);
TextFace(txFace);
SetGWorld(saveWorld, saveDevice);
}
/*
*----------------------------------------------------------------------
*
* XFillRectangles --
*
* Fill multiple rectangular areas in the given drawable.
*
* Results:
* None.
*
* Side effects:
* Draws onto the specified drawable.
*
*----------------------------------------------------------------------
*/
void
XFillRectangles(display, d, gc, rectangles, n_rectangels)
Display* display;
Drawable d;
GC gc;
XRectangle *rectangles;
int n_rectangels;
{
MacDrawable *macWin = (MacDrawable *) d;
CGrafPtr saveWorld;
GDHandle saveDevice;
GWorldPtr destPort;
Rect theRect;
int i;
destPort = TkMacGetDrawablePort(d);
display->request++;
GetGWorld(&saveWorld, &saveDevice);
SetGWorld(destPort, NULL);
TkMacSetUpClippingRgn(d);
TkMacSetUpGraphicsPort(gc);
for (i=0; i<n_rectangels; i++) {
theRect.left = (short) (macWin->xOff + rectangles[i].x);
theRect.top = (short) (macWin->yOff + rectangles[i].y);
theRect.right = (short) (theRect.left + rectangles[i].width);
theRect.bottom = (short) (theRect.top + rectangles[i].height);
FillCRect(&theRect, gPenPat);
}
SetGWorld(saveWorld, saveDevice);
}
/*
*----------------------------------------------------------------------
*
* XDrawLines --
*
* Draw connected lines.
*
* Results:
* None.
*
* Side effects:
* Renders a series of connected lines.
*
*----------------------------------------------------------------------
*/
void
XDrawLines(display, d, gc, points, npoints, mode)
Display* display;
Drawable d;
GC gc;
XPoint* points;
int npoints;
int mode;
{
MacDrawable *macWin = (MacDrawable *) d;
CGrafPtr saveWorld;
GWorldPtr destPort;
GDHandle saveDevice;
int i;
destPort = TkMacGetDrawablePort(d);
display->request++;
if (npoints < 2) {
return; /* TODO: generate BadValue error. */
}
GetGWorld(&saveWorld, &saveDevice);
SetGWorld(destPort, NULL);
TkMacSetUpClippingRgn(d);
TkMacSetUpGraphicsPort(gc);
ShowPen();
PenPixPat(gPenPat);
MoveTo((short) (macWin->xOff + points[0].x),
(short) (macWin->yOff + points[0].y));
for (i = 1; i < npoints; i++) {
if (mode == CoordModeOrigin) {
LineTo((short) (macWin->xOff + points[i].x),
(short) (macWin->yOff + points[i].y));
} else {
Line((short) (macWin->xOff + points[i].x),
(short) (macWin->yOff + points[i].y));
}
}
SetGWorld(saveWorld, saveDevice);
}
/*
*----------------------------------------------------------------------
*
* XFillPolygon --
*
* Draws a filled polygon.
*
* Results:
* None.
*
* Side effects:
* Draws a filled polygon on the specified drawable.
*
*----------------------------------------------------------------------
*/
void
XFillPolygon(display, d, gc, points, npoints, shape, mode)
Display* display;
Drawable d;
GC gc;
XPoint* points;
int npoints;
int shape;
int mode;
{
MacDrawable *macWin = (MacDrawable *) d;
PolyHandle polygon;
CGrafPtr saveWorld;
GDHandle saveDevice;
GWorldPtr destPort;
int i;
destPort = TkMacGetDrawablePort(d);
display->request++;
GetGWorld(&saveWorld, &saveDevice);
SetGWorld(destPort, NULL);
TkMacSetUpClippingRgn(d);
TkMacSetUpGraphicsPort(gc);
PenNormal();
polygon = OpenPoly();
MoveTo((short) (macWin->xOff + points[0].x),
(short) (macWin->yOff + points[0].y));
for (i = 1; i < npoints; i++) {
if (mode == CoordModePrevious) {
Line((short) (macWin->xOff + points[i].x),
(short) (macWin->yOff + points[i].y));
} else {
LineTo((short) (macWin->xOff + points[i].x),
(short) (macWin->yOff + points[i].y));
}
}
ClosePoly();
FillCPoly(polygon, gPenPat);
KillPoly(polygon);
SetGWorld(saveWorld, saveDevice);
}
/*
*----------------------------------------------------------------------
*
* XDrawRectangle --
*
* Draws a rectangle.
*
* Results:
* None.
*
* Side effects:
* Draws a rectangle on the specified drawable.
*
*----------------------------------------------------------------------
*/
void
XDrawRectangle(display, d, gc, x, y, width, height)
Display* display;
Drawable d;
GC gc;
int x;
int y;
unsigned int width;
unsigned int height;
{
MacDrawable *macWin = (MacDrawable *) d;
Rect theRect;
CGrafPtr saveWorld;
GDHandle saveDevice;
GWorldPtr destPort;
destPort = TkMacGetDrawablePort(d);
display->request++;
GetGWorld(&saveWorld, &saveDevice);
SetGWorld(destPort, NULL);
TkMacSetUpClippingRgn(d);
TkMacSetUpGraphicsPort(gc);
theRect.left = (short) (macWin->xOff + x);
theRect.top = (short) (macWin->yOff + y);
theRect.right = (short) (theRect.left + width);
theRect.bottom = (short) (theRect.top + height);
ShowPen();
PenPixPat(gPenPat);
FrameRect(&theRect);
SetGWorld(saveWorld, saveDevice);
}
/*
*----------------------------------------------------------------------
*
* XDrawArc --
*
* Draw an arc.
*
* Results:
* None.
*
* Side effects:
* Draws an arc on the specified drawable.
*
*----------------------------------------------------------------------
*/
void
XDrawArc(display, d, gc, x, y, width, height, angle1, angle2)
Display* display;
Drawable d;
GC gc;
int x;
int y;
unsigned int width;
unsigned int height;
int angle1;
int angle2;
{
MacDrawable *macWin = (MacDrawable *) d;
Rect theRect;
short start, extent;
CGrafPtr saveWorld;
GDHandle saveDevice;
GWorldPtr destPort;
destPort = TkMacGetDrawablePort(d);
display->request++;
GetGWorld(&saveWorld, &saveDevice);
SetGWorld(destPort, NULL);
TkMacSetUpClippingRgn(d);
TkMacSetUpGraphicsPort(gc);
theRect.left = (short) (macWin->xOff + x);
theRect.top = (short) (macWin->yOff + y);
theRect.right = (short) (theRect.left + width);
theRect.bottom = (short) (theRect.top + height);
start = (short) (90 - (angle1 / 64));
extent = (short) (-(angle2 / 64));
ShowPen();
PenPixPat(gPenPat);
FrameArc(&theRect, start, extent);
SetGWorld(saveWorld, saveDevice);
}
/*
*----------------------------------------------------------------------
*
* XFillArc --
*
* Draw a filled arc.
*
* Results:
* None.
*
* Side effects:
* Draws a filled arc on the specified drawable.
*
*----------------------------------------------------------------------
*/
void
XFillArc(display, d, gc, x, y, width, height, angle1, angle2)
Display* display;
Drawable d;
GC gc;
int x;
int y;
unsigned int width;
unsigned int height;
int angle1;
int angle2;
{
MacDrawable *macWin = (MacDrawable *) d;
Rect theRect;
short start, extent;
PolyHandle polygon;
double sin1, cos1, sin2, cos2, angle;
double boxWidth, boxHeight;
double vertex[2], center1[2], center2[2];
CGrafPtr saveWorld;
GDHandle saveDevice;
GWorldPtr destPort;
destPort = TkMacGetDrawablePort(d);
display->request++;
GetGWorld(&saveWorld, &saveDevice);
SetGWorld(destPort, NULL);
TkMacSetUpClippingRgn(d);
TkMacSetUpGraphicsPort(gc);
theRect.left = (short) (macWin->xOff + x);
theRect.top = (short) (macWin->yOff + y);
theRect.right = (short) (theRect.left + width);
theRect.bottom = (short) (theRect.top + height);
start = (short) (90 - (angle1 / 64));
extent = (short) (- (angle2 / 64));
if (gc->arc_mode == ArcChord) {
boxWidth = theRect.right - theRect.left;
boxHeight = theRect.bottom - theRect.top;
angle = -(angle1/64.0)*PI/180.0;
sin1 = sin(angle);
cos1 = cos(angle);
angle -= (angle2/64.0)*PI/180.0;
sin2 = sin(angle);
cos2 = cos(angle);
vertex[0] = (theRect.left + theRect.right)/2.0;
vertex[1] = (theRect.top + theRect.bottom)/2.0;
center1[0] = vertex[0] + cos1*boxWidth/2.0;
center1[1] = vertex[1] + sin1*boxHeight/2.0;
center2[0] = vertex[0] + cos2*boxWidth/2.0;
center2[1] = vertex[1] + sin2*boxHeight/2.0;
polygon = OpenPoly();
MoveTo((short) ((theRect.left + theRect.right)/2),
(short) ((theRect.top + theRect.bottom)/2));
LineTo((short) (center1[0] + 0.5), (short) (center1[1] + 0.5));
LineTo((short) (center2[0] + 0.5), (short) (center2[1] + 0.5));
ClosePoly();
ShowPen();
FillCArc(&theRect, start, extent, gPenPat);
FillCPoly(polygon, gPenPat);
KillPoly(polygon);
} else {
ShowPen();
FillCArc(&theRect, start, extent, gPenPat);
}
SetGWorld(saveWorld, saveDevice);
}
/*
*----------------------------------------------------------------------
*
* 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.
*
*----------------------------------------------------------------------
*/
int
TkScrollWindow(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. */
{
MacDrawable *destDraw = (MacDrawable *) Tk_WindowId(tkwin);
RgnHandle rgn = (RgnHandle) damageRgn;
CGrafPtr saveWorld;
GDHandle saveDevice;
GWorldPtr destPort;
Rect srcRect, scrollRect;
destPort = TkMacGetDrawablePort(Tk_WindowId(tkwin));
GetGWorld(&saveWorld, &saveDevice);
SetGWorld(destPort, NULL);
TkMacSetUpClippingRgn(Tk_WindowId(tkwin));
/*
* Due to the implementation below the behavior may be differnt
* than X in certain cases that should never occur in Tk. The
* scrollRect is the source rect extended by the offset (the union
* of the source rect and the offset rect). Everything
* in the extended scrollRect is scrolled. On X, it's possible
* to "skip" over an area if the offset makes the source and
* destination rects disjoint and non-aligned.
*/
SetRect(&srcRect, (short) (destDraw->xOff + x),
(short) (destDraw->yOff + y),
(short) (destDraw->xOff + x + width),
(short) (destDraw->yOff + y + height));
scrollRect = srcRect;
if (dx < 0) {
scrollRect.left += dx;
} else {
scrollRect.right += dx;
}
if (dy < 0) {
scrollRect.top += dy;
} else {
scrollRect.bottom += dy;
}
/*
* Adjust clip region so that we don't copy any windows
* that may overlap us.
*/
RectRgn(rgn, &srcRect);
DiffRgn(rgn, destPort->visRgn, rgn);
OffsetRgn(rgn, dx, dy);
DiffRgn(destPort->clipRgn, rgn, destPort->clipRgn);
SetEmptyRgn(rgn);
ScrollRect(&scrollRect, dx, dy, rgn);
SetGWorld(saveWorld, saveDevice);
/*
* Fortunantly, the region returned by ScrollRect is symanticlly
* the same as what we need to return in this function. If the
* region is empty we return zero to denote that no damage was
* created.
*/
if (EmptyRgn(rgn)) {
return 0;
} else {
return 1;
}
}
/*
*----------------------------------------------------------------------
*
* TkMacSetUpGraphicsPort --
*
* Set up the graphics port from the given GC.
*
* Results:
* None.
*
* Side effects:
* The current port is adjusted.
*
*----------------------------------------------------------------------
*/
static void
TkMacSetUpGraphicsPort(gc)
GC gc;
{
RGBColor macColor;
if (gPenPat == NULL) {
gPenPat = NewPixPat();
}
if (TkSetMacColor(gc->foreground, &macColor) == true) {
/* TODO: cache RGBPats for preformace - measure gains... */
MakeRGBPat(gPenPat, &macColor);
}
PenNormal();
if(gc->function == GXxor) {
PenMode(patXor);
}
if (gc->line_width > 1) {
PenSize(gc->line_width, gc->line_width);
}
}
/*
*----------------------------------------------------------------------
*
* TkMacSetUpClippingRgn --
*
* Set up the clipping region so that drawing only occurs on the
* specified X subwindow.
*
* Results:
* None.
*
* Side effects:
* The clipping region in the current port is changed.
*
*----------------------------------------------------------------------
*/
void
TkMacSetUpClippingRgn(drawable)
Drawable drawable;
{
MacDrawable *macDraw = (MacDrawable *) drawable;
if (macDraw->winPtr != NULL) {
if (macDraw->flags & TK_CLIP_INVALID) {
TkMacUpdateClipRgn(macDraw->winPtr);
}
if (macDraw->clipRgn != NULL) {
SetClip(macDraw->clipRgn);
}
}
}
/*
*----------------------------------------------------------------------
*
* MakeStippleMap --
*
* Given a drawable and a stipple pattern this function draws the
* pattern repeatedly over the drawable. The drawable can then
* be used as a mask for bit-bliting a stipple pattern over an
* object.
*
* Results:
* A BitMap data structure.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static BitMapPtr
MakeStippleMap(drawable, stipple)
Drawable drawable;
Drawable stipple;
{
MacDrawable *destDraw = (MacDrawable *) drawable;
GWorldPtr destPort;
BitMapPtr bitmapPtr;
int width, height, stippleHeight, stippleWidth;
int i, j;
char * data;
Rect bounds;
destPort = TkMacGetDrawablePort(drawable);
width = destPort->portRect.right - destPort->portRect.left;
height = destPort->portRect.bottom - destPort->portRect.top;
bitmapPtr = (BitMap *) ckalloc(sizeof(BitMap));
data = (char *) ckalloc(height * ((width / 8) + 1));
bitmapPtr->bounds.top = bitmapPtr->bounds.left = 0;
bitmapPtr->bounds.right = (short) width;
bitmapPtr->bounds.bottom = (short) height;
bitmapPtr->baseAddr = data;
bitmapPtr->rowBytes = (width / 8) + 1;
destPort = TkMacGetDrawablePort(stipple);
stippleWidth = destPort->portRect.right - destPort->portRect.left;
stippleHeight = destPort->portRect.bottom - destPort->portRect.top;
for (i = 0; i < height; i += stippleHeight) {
for (j = 0; j < width; j += stippleWidth) {
bounds.left = j;
bounds.top = i;
bounds.right = j + stippleWidth;
bounds.bottom = i + stippleHeight;
CopyBits(&((GrafPtr) destPort)->portBits, bitmapPtr,
&((GrafPtr) destPort)->portRect, &bounds, srcCopy, NULL);
}
}
return bitmapPtr;
}
/*
*----------------------------------------------------------------------
*
* InvertByte --
*
* This function reverses the bits in the passed in Byte of data.
*
* Results:
* The incoming byte in reverse bit order.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static unsigned char
InvertByte(unsigned char data)
{
unsigned char i;
unsigned char mask = 1, result = 0;
for (i = (1 << 7); i != 0; i /= 2) {
if (data & mask) {
result |= i;
}
mask = mask << 1;
}
return result;
}