Attachment "OSXtkCGdraw.diff" to
ticket [841244ffff]
added by
tigital
2003-11-14 01:16:50.
Index: macosx/tkMacOSXDraw.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/macosx/tkMacOSXDraw.c,v
retrieving revision 1.2
diff -u -B -b -w -r1.2 tkMacOSXDraw.c
--- macosx/tkMacOSXDraw.c 31 Aug 2002 06:12:29 -0000 1.2
+++ macosx/tkMacOSXDraw.c 13 Nov 2003 05:55:36 -0000
@@ -27,9 +27,9 @@
#ifndef PI
# define PI 3.14159265358979323846
#endif
-#define RGBFLOATRED( c ) (float)((float)(c.red) / 65535.0)
-#define RGBFLOATGREEN( c ) (float)((float)(c.green) / 65535.0)
-#define RGBFLOATBLUE( c ) (float)((float)(c.blue) / 65535.0)
+#define RGBFLOATRED( c ) (float)((float)(c.red) / 65535.0f)
+#define RGBFLOATGREEN( c ) (float)((float)(c.green) / 65535.0f)
+#define RGBFLOATBLUE( c ) (float)((float)(c.blue) / 65535.0f)
/*
* Temporary regions that can be reused.
@@ -40,7 +40,7 @@
static PixPatHandle gPenPat = NULL;
-static int useCGDrawing = 0;
+static int useCGDrawing = 1;
/*
* Prototypes for functions used only in this file.
@@ -51,6 +51,8 @@
CGrafPtr destPort, GC gc, CGContextRef *contextPtr);
void TkMacOSXReleaseCGContext(MacDrawable *macWin, CGrafPtr destPort,
CGContextRef *context);
+static inline double radians(double degrees) { return degrees * PI / 180.0f; }
+
/*
*----------------------------------------------------------------------
*
@@ -453,7 +455,7 @@
Drawable d, /* Draw on this. */
GC gc, /* Use this GC. */
XRectangle *rectangles, /* Rectangle array. */
- int n_rectangels) /* Number of rectangles. */
+ int n_rectangles) /* Number of rectangles. */
{
MacDrawable *macWin = (MacDrawable *) d;
CGrafPtr saveWorld;
@@ -469,16 +471,33 @@
SetGWorld(destPort, NULL);
TkMacOSXSetUpClippingRgn(d);
+ if (useCGDrawing) {
+ CGContextRef outContext;
+ CGRect rect;
+ RgnHandle clipRgn;
+
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
+ for (i=0; i < n_rectangles; i++ ){
+ rect = CGRectMake( (float)(macWin->xOff + rectangles[i].x),
+ (float)(macWin->yOff + rectangles[i].y),
+ (float)rectangles[i].width,
+ (float)rectangles[i].height );
+
+ CGContextFillRect( outContext, rect );
+ }
+ TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ } else {
TkMacOSXSetUpGraphicsPort(gc, destPort);
- for (i=0; i<n_rectangels; i++) {
+ for (i=0; i<n_rectangles; 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);
}
@@ -527,17 +546,24 @@
if (useCGDrawing) {
CGContextRef outContext;
+ Rect theRect;
+ RgnHandle clipRgn;
TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
CGContextBeginPath(outContext);
- CGContextMoveToPoint(outContext, (float) points[0].x,
- (float) points[0].y);
- if (mode == CoordModeOrigin) {
+ CGContextMoveToPoint(outContext, (float)(macWin->xOff + points[0].x),
+ (float)(macWin->yOff + points[0].y) );
+
for (i = 1; i < npoints; i++) {
+ if(mode==CoordModeOrigin){
CGContextAddLineToPoint(outContext,
- (float) points[i].x,
- (float) points[i].y);
+ (float)(macWin->xOff + points[i].x),
+ (float)(macWin->yOff + points[i].y) );
+ }else{
+ CGContextAddLineToPoint( outContext,
+ (float)(macWin->xOff + points[i].x),
+ (float)(macWin->yOff + points[i].y) );
}
}
@@ -577,7 +603,7 @@
* None.
*
* Side effects:
- * Renders a series of connected lines.
+ * Renders a series of unconnected lines.
*
*----------------------------------------------------------------------
*/
@@ -609,16 +635,17 @@
TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
- CGContextBeginPath(outContext);
for (i = 0; i < nsegments; i++) {
+ CGContextBeginPath(outContext);
CGContextMoveToPoint(outContext,
- (float) segments[i].x1,
- (float) segments[i].y1);
+ (float)(macWin->xOff + segments[i].x1),
+ (float)(macWin->yOff + segments[i].y1));
CGContextAddLineToPoint (outContext,
- (float) segments[i].x2,
- (float) segments[i].y2);
- }
+ (float)(macWin->xOff + segments[i].x2),
+ (float)(macWin->yOff + segments[i].y2));
CGContextStrokePath(outContext);
+
+ }
TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
} else {
TkMacOSXSetUpGraphicsPort(gc, destPort);
@@ -681,22 +708,24 @@
if (useCGDrawing) {
CGContextRef outContext;
+ Rect theRect;
+ RgnHandle clipRgn;
TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
CGContextBeginPath(outContext);
- CGContextMoveToPoint(outContext, (float) (points[0].x),
- (float) (points[0].y));
+ CGContextMoveToPoint(outContext, (float) (macWin->xOff + points[0].x),
+ (float) (macWin->yOff + points[0].y));
for (i = 1; i < npoints; i++) {
if (mode == CoordModePrevious) {
- CGContextAddLineToPoint(outContext, (float) points[i].x,
- (float) points[i].y);
+ CGContextAddLineToPoint( outContext, (float)points[i].x, (float) points[i].y );
} else {
+ CGContextAddLineToPoint(outContext, (float)(macWin->xOff + points[i].x),
+ (float)(macWin->yOff + points[i].y));
}
}
- //CGContextStrokePath(outContext);
- CGContextFillPath(outContext);
+ CGContextEOFillPath(outContext);
TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
} else {
TkMacOSXSetUpGraphicsPort(gc, destPort);
@@ -764,7 +793,20 @@
SetGWorld(destPort, NULL);
TkMacOSXSetUpClippingRgn(d);
+ if (useCGDrawing) {
+ CGContextRef outContext;
+ CGRect rect;
+ RgnHandle clipRgn;
+
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
+ rect = CGRectMake( (float)((float)macWin->xOff + (float)x),
+ (float)((float)macWin->yOff + (float)y),
+ (float)width,
+ (float)height );
+ CGContextStrokeRect( outContext, rect );
+ TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ } else {
TkMacOSXSetUpGraphicsPort(gc, destPort);
theRect.left = (short) (macWin->xOff + x);
@@ -776,7 +818,7 @@
PenPixPat(gPenPat);
FrameRect(&theRect);
HidePen();
-
+ }
SetGWorld(saveWorld, saveDevice);
}
@@ -815,7 +857,7 @@
int nRects)
{
MacDrawable *macWin = (MacDrawable *) drawable;
- Rect rect;
+ Rect theRect;
CGrafPtr saveWorld;
GDHandle saveDevice;
GWorldPtr destPort;
@@ -830,21 +872,36 @@
TkMacOSXSetUpClippingRgn(drawable);
- TkMacOSXSetUpGraphicsPort(gc, destPort);
+ if (useCGDrawing) {
+ CGContextRef outContext;
+ CGRect rect;
+ RgnHandle clipRgn;
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
+
+ for (i=0, rectPtr = rectArr; i < nRects; i++, rectPtr++ ){
+ rect = CGRectMake( (float)((float)macWin->xOff + (float)rectPtr->x),
+ (float)((float)macWin->yOff + (float)rectPtr->y),
+ (float)rectPtr->width,
+ (float)rectPtr->height );
+ CGContextStrokeRect( outContext, rect );
+ }
+ TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ } else {
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
ShowPen();
PenPixPat(gPenPat);
for (i = 0, rectPtr = rectArr; i < nRects;i++, rectPtr++ ) {
- rect.left = (short) (macWin->xOff + rectPtr->x);
- rect.top = (short) (macWin->yOff + rectPtr->y);
- rect.right = (short) (rect.left + rectPtr->width);
- rect.bottom = (short) (rect.top + rectPtr->height);
- FrameRect(&rect);
+ theRect.left = (short) (macWin->xOff + rectPtr->x);
+ theRect.top = (short) (macWin->yOff + rectPtr->y);
+ theRect.right = (short) (theRect.left + rectPtr->width);
+ theRect.bottom = (short) (theRect.top + rectPtr->height);
+ FrameRect(&theRect);
}
HidePen();
-
+ }
SetGWorld(saveWorld, saveDevice);
}
@@ -902,12 +959,19 @@
if (useCGDrawing) {
CGContextRef outContext;
CGAffineTransform transform;
- int clockwise = angle1 ? 0 : 1;
+ CGRect boundingRect;
+ int clockwise;
+ float a,b;
+ CGPoint center;
+ RgnHandle clipRgn;
+
+ if (angle2 > 0)
+ clockwise = 1;
+ else
+ clockwise = 0;
TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
- CGContextBeginPath(outContext);
-
/*
* If we are drawing an oval, we have to squash the coordinate
* system before drawing, since CGContextAddArcToPoint only draws
@@ -915,17 +979,23 @@
*/
CGContextSaveGState(outContext);
- transform = CGAffineTransformMakeTranslation((float) (x + width/2),
- (float) (y + height/2));
- transform = CGAffineTransformScale(transform, 1.0, fHeight/fWidth);
- CGContextConcatCTM(outContext, transform);
-
- CGContextAddArc(outContext, 0.0, 0.0,
- (float) width/2,
- (float) angle1, (float) angle2, clockwise);
+ boundingRect = CGRectMake( (float)(macWin->xOff + x),
+ (float)(macWin->yOff + y),
+ (float)(width),
+ (float)(height) );
+
+ center = CGPointMake(CGRectGetMidX(boundingRect), CGRectGetMidY(boundingRect) );
+ a= CGRectGetWidth(boundingRect)/2;
+ b= CGRectGetHeight(boundingRect)/2;
- CGContextRestoreGState(outContext);
+ CGContextTranslateCTM(outContext, center.x, center.y);
+ CGContextBeginPath(outContext);
+ CGContextScaleCTM(outContext, a, b );
+ float arc1 = radians( -(angle1/64) );
+ float arc2 = radians( -(angle2/64) ) + arc1;
+ CGContextAddArc( outContext, 0.0, 0.0, 1, arc1, arc2, clockwise );
+ CGContextRestoreGState(outContext);
CGContextStrokePath(outContext);
TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
} else {
@@ -995,9 +1064,51 @@
SetGWorld(destPort, NULL);
TkMacOSXSetUpClippingRgn(d);
+ if (useCGDrawing) {
+ CGContextRef outContext;
+ Rect theRect;
+ RgnHandle clipRgn;
- TkMacOSXSetUpGraphicsPort(gc, destPort);
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
+
+ for (i=0, arcPtr = arcArr; i < nArcs; i++, arcPtr++ ){
+ CGRect boundingRect;
+ int clockwise;// = arcPtr[i].angle1 ? 0 : 1;
+ float a,b;
+ CGPoint center;
+
+ if (arcPtr[i].angle2 > 0)
+ clockwise = 1;
+ else
+ clockwise = 0;
+ /*
+ * If we are drawing an oval, we have to squash the coordinate
+ * system before drawing, since CGContextAddArcToPoint only draws
+ * circles.
+ */
+ CGContextSaveGState(outContext);
+ CGContextBeginPath(outContext);
+ boundingRect = CGRectMake( (float)(macWin->xOff + arcPtr[i].x),
+ (float)(macWin->yOff + arcPtr[i].y),
+ (float)arcPtr[i].width,
+ (float)arcPtr[i].height );
+
+ center = CGPointMake(CGRectGetMidX(boundingRect), CGRectGetMidY(boundingRect) );
+ a = CGRectGetWidth(boundingRect)/2;
+ b = CGRectGetHeight(boundingRect)/2;
+
+ CGContextTranslateCTM(outContext, center.x, center.y);
+ CGContextScaleCTM(outContext, a, b );
+ float arc1 = radians( -(arcPtr[i].angle1/64) );
+ float arc2 = radians( -(arcPtr[i].angle2/64) ) + arc1;
+ CGContextAddArc( outContext, 0.0, 0.0, 1, arc1, arc2, clockwise );
+ CGContextRestoreGState(outContext);
+ CGContextStrokePath(outContext);
+ }
+ TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ } else {
+ TkMacOSXSetUpGraphicsPort(gc, destPort);
ShowPen();
PenPixPat(gPenPat);
@@ -1011,7 +1122,7 @@
FrameArc(&rect, start, extent);
}
HidePen();
-
+ }
SetGWorld(saveWorld, saveDevice);
}
@@ -1062,6 +1173,52 @@
TkMacOSXSetUpClippingRgn(d);
+ if (useCGDrawing) {
+ CGContextRef outContext;
+ CGRect boundingRect;
+ int clockwise;// = angle1 ? 0 : 1;
+ float a,b;
+ CGPoint center;
+ float sy,ty;
+ RgnHandle clipRgn;
+ if (angle2 > 0)
+ clockwise = 1;
+ else
+ clockwise = 0;
+
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
+
+ boundingRect = CGRectMake( (float)(macWin->xOff + x),
+ (float)(macWin->yOff + y),
+ (float)width,
+ (float)height );
+ center = CGPointMake(CGRectGetMidX(boundingRect), CGRectGetMidY(boundingRect) );
+ a= CGRectGetWidth(boundingRect)/2;
+ b= CGRectGetHeight(boundingRect)/2;
+
+ if (gc->arc_mode == ArcChord) {
+
+ CGContextBeginPath( outContext );
+ CGContextTranslateCTM(outContext, center.x, center.y);
+ CGContextScaleCTM(outContext, a, b );
+ float arc1 = radians( -(angle1/64) );
+ float arc2 = radians( -(angle2/64) ) + arc1;
+ CGContextAddArc( outContext, 0.0, 0.0, 1, arc1, arc2, clockwise );
+ CGContextFillPath(outContext);
+ }else if (gc->arc_mode == ArcPieSlice){
+
+ CGContextTranslateCTM(outContext, center.x, center.y);
+ CGContextScaleCTM(outContext,a,b );
+ float arc1 = radians( -(angle1/64) );
+ float arc2 = radians( -(angle2/64) ) + arc1;
+ CGContextAddArc( outContext, 0.0, 0.0, 1, arc1, arc2, clockwise );
+ CGContextAddLineToPoint( outContext, 0.0f, 0.0f );
+ CGContextClosePath( outContext );
+ CGContextFillPath(outContext);
+ }
+
+ TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ } else {
TkMacOSXSetUpGraphicsPort(gc, destPort);
theRect.left = (short) (macWin->xOff + x);
@@ -1106,7 +1263,7 @@
FillCArc(&theRect, start, extent, gPenPat);
HidePen();
}
-
+ }
SetGWorld(saveWorld, saveDevice);
}
@@ -1154,6 +1311,90 @@
TkMacOSXSetUpClippingRgn(d);
+ if (useCGDrawing) {
+ CGContextRef outContext;
+ Rect theRect;
+ RgnHandle clipRgn;
+
+ TkMacOSXSetUpCGContext(macWin, destPort, gc, &outContext);
+ for (i=0, arcPtr = arcArr; i < nArcs; i++, arcPtr++ ){
+ CGRect boundingRect;
+ int clockwise = arcPtr[i].angle1;
+ float a,b;
+ float sy, ty;
+ CGPoint center;
+
+ if (arcPtr[i].angle2 > 0)
+ clockwise = 1;
+ else
+ clockwise = 0;
+
+ /*
+ * If we are drawing an oval, we have to squash the coordinate
+ * system before drawing, since CGContextAddArcToPoint only draws
+ * circles.
+ */
+ if (gc->arc_mode == ArcChord) {
+
+ CGContextBeginPath(outContext);
+ boundingRect = CGRectMake( (float)(macWin->xOff + arcPtr[i].x),
+ (float)(macWin->yOff + arcPtr[i].y),
+ (float)arcPtr[i].width,
+ (float)arcPtr[i].height );
+ center = CGPointMake(CGRectGetMidX(boundingRect), CGRectGetMidY(boundingRect) );
+ a = CGRectGetWidth(boundingRect)/2.0;
+ b = CGRectGetHeight(boundingRect)/2.0;
+
+ angle = -(arcPtr->angle1/64.0)*PI/180.0;
+ sin1 = sin(angle);
+ cos1 = cos(angle);
+ angle -= (arcPtr->angle2/64.0)*PI/180.0;
+ sin2 = sin(angle);
+ cos2 = cos(angle);
+ vertex[0] = (CGRectGetMinX(boundingRect) + CGRectGetMaxX(boundingRect))/2.0;
+ vertex[1] = (CGRectGetMaxY(boundingRect) + CGRectGetMinY(boundingRect))/2.0;
+ center1[0] = vertex[0] + cos1*a;
+ center1[1] = vertex[1] + sin1*b;
+ center2[0] = vertex[0] + cos2*a;
+ center2[1] = vertex[1] + sin2*b;
+
+ CGContextScaleCTM(outContext, a, b );
+
+ CGContextBeginPath(outContext);
+ CGContextMoveToPoint(outContext, (float)vertex[0],
+ (float)vertex[1] );
+ CGContextAddLineToPoint( outContext,
+ (float)(center1[0]+0.5),
+ (float)(center1[1]+0.5) );
+ CGContextAddLineToPoint( outContext,
+ (float)(center2[0]+0.5),
+ (float)(center2[1]+0.5) );
+ CGContextFillPath(outContext);
+ }else if (gc->arc_mode == ArcPieSlice){
+
+ CGContextBeginPath(outContext);
+ boundingRect = CGRectMake( (float)(macWin->xOff + arcPtr[i].x),
+ (float)(macWin->yOff + arcPtr[i].y),
+ (float)arcPtr[i].width,
+ (float)arcPtr[i].height );
+ center = CGPointMake(CGRectGetMidX(boundingRect), CGRectGetMidY(boundingRect) );
+ a = CGRectGetWidth(boundingRect)/2;
+ b = CGRectGetHeight(boundingRect)/2;
+
+ CGContextTranslateCTM(outContext, center.x, center.y);
+ CGContextScaleCTM(outContext, a, b );
+ float arc1 = radians( -(arcPtr[i].angle1/64) );
+ float arc2 = radians( -(arcPtr[i].angle2/64) ) + arc1;
+ CGContextAddArc( outContext, 0.0, 0.0, 1, arc1, arc2, clockwise );
+ CGContextAddLineToPoint( outContext, 0.0f, 0.0f );
+ CGContextClosePath( outContext );
+ CGContextFillPath(outContext);
+ }
+ }
+
+ TkMacOSXReleaseCGContext(macWin, destPort, &outContext);
+ } else {
+
TkMacOSXSetUpGraphicsPort(gc, destPort);
for (i = 0, arcPtr = arcArr;i<nArcs;i++, arcPtr++ ) {
@@ -1200,6 +1441,7 @@
HidePen();
}
}
+ }
SetGWorld(saveWorld, saveDevice);
}
@@ -1442,8 +1684,9 @@
GetPortBounds(destPort, &boundsRect);
- CGContextResetCTM(outContext);
- coordsTransform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0,
+ SyncCGContextOriginWithPort( outContext, destPort );
+
+ coordsTransform = CGAffineTransformMake(1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
(float)(boundsRect.bottom - boundsRect.top));
CGContextConcatCTM(outContext, coordsTransform);
@@ -1452,24 +1695,20 @@
} else {
RgnHandle clipRgn = NewRgn();
GetPortClipRegion(destPort, clipRgn);
- ClipCGContextToRegion(outContext, &boundsRect,
- clipRgn);
+ ClipCGContextToRegion(outContext, &boundsRect, clipRgn);
DisposeRgn(clipRgn);
}
/* Now offset the CTM to the subwindow offset */
-
- CGContextTranslateCTM(outContext, macWin->xOff, macWin->yOff);
+ //CGContextTranslateCTM(outContext, (float)macWin->xOff, (float)macWin->yOff);
if (TkSetMacColor(gc->foreground, &macColor) == true) {
- CGContextSetRGBStrokeColor(outContext, RGBFLOATRED(macColor),
- RGBFLOATGREEN(macColor),
- RGBFLOATBLUE(macColor), 1.0);
- }
- if (TkSetMacColor(gc->background, &macColor) == true) {
CGContextSetRGBFillColor(outContext, RGBFLOATRED(macColor),
RGBFLOATGREEN(macColor),
- RGBFLOATBLUE(macColor), 1.0);
+ RGBFLOATBLUE(macColor), 1.0f );
+ CGContextSetRGBStrokeColor( outContext, RGBFLOATRED(macColor),
+ RGBFLOATGREEN(macColor),
+ RGBFLOATBLUE(macColor), 1.0f );
}
if(gc->function == GXxor) {
@@ -1477,8 +1716,15 @@
CGContextSetLineWidth(outContext, (float) gc->line_width);
- if (gc->line_style != LineSolid) {
- unsigned char *p = (unsigned char *) &(gc->dashes);
+ /* When should we antialias? */
+ if (gc->line_width < 1)
+ CGContextSetShouldAntialias( outContext, 0 );
+ else
+ CGContextSetShouldAntialias( outContext, 1 );
+
+ if (gc->line_style != LineSolid) { // LineSolid = 0, LineOnOffDash = 1, LineDoubleDash = 2
+ float *p = (float *) &(gc->dashes);
+ CGContextSetLineDash( outContext, 0.0f, p, 1 );
/*
* Here the dash pattern should be set in the drawing,
* environment, but I don't know how to do that for the Mac.
@@ -1502,6 +1748,22 @@
* we can use CG to draw our lines instead of QuickDraw.
*/
}
+
+ if (gc->cap_style == CapButt){ // what about CapNotLast, CapProjecting?
+ CGContextSetLineCap( outContext, kCGLineCapButt );
+ }else if (gc->cap_style == CapRound){
+ CGContextSetLineCap( outContext, kCGLineCapRound );
+ } else if (gc->cap_style == CapProjecting){
+ CGContextSetLineCap( outContext, kCGLineCapSquare );
+ }
+
+ if (gc->join_style == JoinMiter){
+ CGContextSetLineJoin( outContext, kCGLineJoinMiter );
+ }else if (gc->join_style == JoinRound){
+ CGContextSetLineJoin( outContext, kCGLineJoinRound );
+ }else if (gc->join_style == JoinBevel){
+ CGContextSetLineJoin( outContext, kCGLineJoinBevel );
+ }
}
void
@@ -1510,8 +1772,9 @@
CGrafPtr destPort,
CGContextRef *outContext)
{
- CGContextResetCTM(*outContext);
+
CGContextRestoreGState(*outContext);
+ CGContextSynchronize( *outContext );
QDEndCGContext(destPort, outContext);
}