static void
gdk_quartz_draw_arc (GdkDrawable *drawable,
		     GdkGC       *gc,
		     gboolean     filled,
		     gint         x,
		     gint         y,
		     gint         width,
		     gint         height,
		     gint         angle1,
		     gint         angle2)
{
  CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE);
  float start_angle, end_angle;
  gboolean clockwise = FALSE;

  if (!context)
    return;

  if (!_gdk_quartz_gc_update_cg_context (gc, drawable, context,
					 filled ?
					 GDK_QUARTZ_CONTEXT_FILL :
					 GDK_QUARTZ_CONTEXT_STROKE))
    {
      gdk_quartz_drawable_release_context (drawable, context);
      return;
    }
  start_angle = angle1 * 2.0 * G_PI / 360.0 / 64.0;
  end_angle = start_angle + angle2 * 2.0 * G_PI / 360.0 / 64.0;

  /*  angle2 is relative to angle1 and can be negative, which switches
   *  the drawing direction
   */
  if (angle2 < 0)
    clockwise = TRUE;

  /*  below, flip the coordinate system back to its original y-diretion
   *  so the angles passed to CGContextAddArc() are interpreted as
   *  expected
   *
   *  FIXME: the implementation below works only for perfect circles
   *  (width == height). Any other aspect ratio either scales the
   *  line width unevenly or scales away the path entirely for very
   *  small line widths (esp. for line_width == 0, which is a hair
   *  line on X11 but must be approximated with the thinnest possible
   *  line on quartz).
   */

  if (filled)
    {
      CGContextTranslateCTM (context,
                             x + width / 2.0,
                             y + height / 2.0);
      CGContextScaleCTM (context, 1.0, - (double)height / (double)width);

      CGContextMoveToPoint (context, 0, 0);
      CGContextAddArc (context, 0, 0, width / 2.0,
		       start_angle, end_angle,
		       clockwise);
      CGContextClosePath (context);
      CGContextFillPath (context);
    }
  else
    {
      CGContextTranslateCTM (context,
                             x + width / 2.0 + 0.5,
                             y + height / 2.0 + 0.5);
      CGContextScaleCTM (context, 1.0, - (double)height / (double)width);

      CGContextAddArc (context, 0, 0, width / 2.0,
		       start_angle, end_angle,
		       clockwise);
      CGContextStrokePath (context);
    }

  gdk_quartz_drawable_release_context (drawable, context);
}
void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
{
    if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f)
        return;

    CGContextRef context = platformContext();
    CGContextSaveGState(context);
    CGContextBeginPath(context);
    CGContextSetShouldAntialias(context, false);

    int x = rect.x();
    int y = rect.y();
    float w = (float)rect.width();
    float h = (float)rect.height();
    float scaleFactor = h / w;
    float reverseScaleFactor = w / h;

    if (w != h)
        scale(FloatSize(1, scaleFactor));

    float hRadius = w / 2;
    float vRadius = h / 2;
    float fa = startAngle;
    float falen =  fa + angleSpan;
    float start = -fa * piFloat / 180.0f;
    float end = -falen * piFloat / 180.0f;
    CGContextAddArc(context, x + hRadius, (y + vRadius) * reverseScaleFactor, hRadius, start, end, true);

    if (w != h)
        scale(FloatSize(1, reverseScaleFactor));

    float width = strokeThickness();
    int patWidth = 0;

    switch (strokeStyle()) {
    case DottedStroke:
        patWidth = (int)(width / 2);
        break;
    case DashedStroke:
        patWidth = 3 * (int)(width / 2);
        break;
    default:
        break;
    }

    if (patWidth) {
        // Example: 80 pixels with a width of 30 pixels.
        // Remainder is 20.  The maximum pixels of line we could paint
        // will be 50 pixels.
        int distance;
        if (hRadius == vRadius)
            distance = static_cast<int>((piFloat * hRadius) / 2.0f);
        else // We are elliptical and will have to estimate the distance
            distance = static_cast<int>((piFloat * sqrtf((hRadius * hRadius + vRadius * vRadius) / 2.0f)) / 2.0f);

        int remainder = distance % patWidth;
        int coverage = distance - remainder;
        int numSegments = coverage / patWidth;

        float patternOffset = 0.0f;
        // Special case 1px dotted borders for speed.
        if (patWidth == 1)
            patternOffset = 1.0f;
        else {
            bool evenNumberOfSegments = !(numSegments % 2);
            if (remainder)
                evenNumberOfSegments = !evenNumberOfSegments;
            if (evenNumberOfSegments) {
                if (remainder) {
                    patternOffset += patWidth - remainder;
                    patternOffset += remainder / 2.0f;
                } else
                    patternOffset = patWidth / 2.0f;
            } else {
                if (remainder)
                    patternOffset = (patWidth - remainder) / 2.0f;
            }
        }

        const CGFloat dottedLine[2] = { patWidth, patWidth };
        CGContextSetLineDash(context, patternOffset, dottedLine, 2);
    }

    CGContextStrokePath(context);

    CGContextRestoreGState(context);
}
Exemple #3
0
static void initNeedle(unsigned w, unsigned h, unsigned max)
{
    CGColorSpaceRef colorspace;
    CGContextRef  gc;
    unsigned char *data;
    float cx, cy;
    float angle, radius, needle;

    data = (unsigned char *)malloc(w * h * 4);

    colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
    gc         = CGBitmapContextCreate(data, w, h, 8, w * 4, colorspace,
                                   kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);


    cx    = CENTERX * w;
    cy    = CENTERY * h;
    radius = 0.5 * (w > h ? w : h);
    needle = radius * 0.85;

    CGContextTranslateCTM(gc, 0.0, h);
    CGContextScaleCTM(gc, 1.0, -1.0);
    CGContextClearRect(gc, CGRectMake(0, 0, w, h));
    angle = 0;//angleForValue(0, max);

    {
        // draw glow reflecting on inner bevel
        float    dx, dy;
        dx         = -cos(angle) + 1;
        dy         = -sin(angle) + 1;

        CGGradientRef gradient;
        size_t num_locations = 2;
        CGFloat locations[2] = { 0.0, 1.0 };
        CGFloat components[8] = { 0.7, 0.7, 1.0, 0.7,  // Start color
                                  0.0, 0.0, 0.0, 0.0
                                }; // End color

        gradient = CGGradientCreateWithColorComponents (colorspace, components,
                   locations, num_locations);
        CGContextSaveGState(gc);
        CGContextAddArc(gc, cx, cy, needle*1.05, 0, 2*M_PI, false);
        CGContextAddArc(gc, cx, cy, needle*0.96, 0, 2*M_PI, false);
        CGContextEOClip(gc);
        CGContextDrawRadialGradient (gc, gradient,
                                     CGPointMake(cx*dx, cy*dy), radius*0.1,
                                     CGPointMake(cx*1.0, cy*1.0), radius*1.0, 0);
        CGContextRestoreGState(gc);
    }

    CGContextSetRGBFillColor(gc, 0.9, 0.9, 1.0, 1.0);

    // draw several glow passes, with the content offscreen
    CGContextTranslateCTM(gc, 0, OFFSCREEN - 10);
    CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7));
    drawNeedle(gc, w, h, angle);
    CGContextTranslateCTM(gc, 0, 20);
    CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7));
    drawNeedle(gc, w, h, angle);
    CGContextTranslateCTM(gc, -10, -10);
    CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7));
    drawNeedle(gc, w, h, angle);
    CGContextTranslateCTM(gc, 20, 0);
    CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7));
    drawNeedle(gc, w, h, angle);
    CGContextTranslateCTM(gc, -10, -OFFSCREEN);

    // draw real content
    CGContextSetShadowWithColor(gc, CGSizeMake(0, 1), 6.0, CGColorCreateGenericRGB(0.0, 0.0, 0.5, 0.7));
    drawNeedle(gc, w, h, angle);

    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);

    CGContextRelease(gc);
    CGColorSpaceRelease(colorspace);
    free(data);
}
Exemple #4
0
static void initBackground(unsigned w, unsigned h, unsigned max)
{
    CGColorSpaceRef colorspace;
    CGContextRef  gc;
    unsigned char *data;
    float cx, cy;
    float radius, needle;

    data = (unsigned char *)malloc(w * h * 4);

    colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
    gc         = CGBitmapContextCreate(data, w, h, 8, w * 4, colorspace,
                                   kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);

    cx    = CENTERX * w;
    cy    = CENTERY * h;
    radius = 0.5 * (w > h ? w : h);
    needle = radius * 0.85;

    // background
    CGContextTranslateCTM(gc, 0.0, h);
    CGContextScaleCTM(gc, 1.0, -1.0);
    CGContextClearRect(gc, CGRectMake(0, 0, w, h));
    CGContextSetRGBFillColor(gc, 0.0, 0.0, 0.0, 0.7);
    CGContextAddArc(gc, cx, cy, radius, 0, 2*M_PI, false);
    CGContextFillPath(gc);

    CGGradientRef gradient;
    size_t num_locations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };
    CGFloat components[8] = { 1.0, 1.0, 1.0, 0.5,  // Start color
                              0.0, 0.0, 0.0, 0.0
                            }; // End color

    gradient = CGGradientCreateWithColorComponents (colorspace, components,
               locations, num_locations);
    // top rim light
    CGContextSaveGState(gc);
    CGContextAddArc(gc, cx, cy, radius, 0, 2*M_PI, false);
    CGContextAddArc(gc, cx, cy, needle*1.05, 0, 2*M_PI, false);
    CGContextEOClip(gc);
    CGContextDrawRadialGradient (gc, gradient,
                                 CGPointMake(cx, cy*1.00), radius*1.01,
                                 CGPointMake(cx, cy*0.96), radius*0.98, 0);
    // bottom rim light
    CGContextDrawRadialGradient (gc, gradient,
                                 CGPointMake(cx, cy*1.00), radius*1.01,
                                 CGPointMake(cx, cy*1.04), radius*0.98, 0);
    // top bevel
    CGContextDrawRadialGradient (gc, gradient,
                                 CGPointMake(cx, cy*2.2), radius*0.2,
                                 CGPointMake(cx, cy*1.0), radius*1.0, 0);
    // bottom bevel
    CGContextRestoreGState(gc);
    CGContextSaveGState(gc);
    CGContextAddArc(gc, cx, cy, needle*1.05, 0, 2*M_PI, false);
    CGContextAddArc(gc, cx, cy, needle*0.96, 0, 2*M_PI, false);
    CGContextEOClip(gc);
    CGContextDrawRadialGradient (gc, gradient,
                                 CGPointMake(cx, cy* -.5), radius*0.2,
                                 CGPointMake(cx, cy*1.0), radius*1.0, 0);

    CGGradientRelease(gradient);
    CGContextRestoreGState(gc);

    CGContextSetRGBFillColor(gc, 0.9, 0.9, 1.0, 1.0);
    CGContextSetRGBStrokeColor(gc, 0.9, 0.9, 1.0, 1.0);
    CGContextSetLineCap(gc, kCGLineCapRound);

    // draw several glow passes, with the content offscreen
    CGContextTranslateCTM(gc, 0, OFFSCREEN - 10);
    CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7));
    drawMarks(gc, w, h, max);
    CGContextTranslateCTM(gc, 0, 20);
    CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7));
    drawMarks(gc, w, h, max);
    CGContextTranslateCTM(gc, -10, -10);
    CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7));
    drawMarks(gc, w, h, max);
    CGContextTranslateCTM(gc, 20, 0);
    CGContextSetShadowWithColor(gc, CGSizeMake(0, OFFSCREEN), 48.0, CGColorCreateGenericRGB(0.5, 0.5, 1.0, 0.7));
    drawMarks(gc, w, h, max);
    CGContextTranslateCTM(gc, -10, -OFFSCREEN);

    // draw real content
    CGContextSetShadowWithColor(gc, CGSizeMake(0, 1), 6.0, CGColorCreateGenericRGB(0.7, 0.7, 1.0, 0.9));
    drawMarks(gc, w, h, max);

    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);

    CGContextRelease(gc);
    CGColorSpaceRelease(colorspace);
    free(data);
}
//-----------------------------------------------------------------------------
void MadShiftaNumberCircle::draw(DGGraphicsContext * inContext)
{
	// draw the outer edge of the background circle
	CGContextRef cgContext = inContext->getPlatformGraphicsContext();
	CGRect backgroundBounds = getBounds()->convertToCGRect( inContext->getPortHeight() );
	CGContextAddEllipseInRect(cgContext, backgroundBounds);
	inContext->setFillColor(kControlFillColor_alt);
	inContext->endPath();
	inContext->fillPath();

	// draw the inner filling of the background circle
	inContext->beginPath();
	inContext->setFillColor(kControlBackgroundColor);
	const CGFloat backgroundFrameWidth = 1.0f;
	CGRect fillBounds = CGRectInset(backgroundBounds, backgroundFrameWidth, backgroundFrameWidth);
	CGContextAddEllipseInRect(cgContext, fillBounds);
	inContext->endPath();
	inContext->fillPath();

	// draw the pie portion filling
	inContext->beginPath();
	inContext->setFillColor(kControlFillColor);
	CGFloat centerX = fillBounds.origin.x + (fillBounds.size.width * 0.5);
	CGFloat centerY = fillBounds.origin.y + (fillBounds.size.height * 0.5);
	SInt32 min = GetControl32BitMinimum( getCarbonControl() );
	SInt32 max = GetControl32BitMaximum( getCarbonControl() );
	SInt32 val = GetControl32BitValue( getCarbonControl() );
	if (val <= min)
	{
		inContext->setStrokeColor(kControlFillColor_alt);
		float linePosX = floorf(centerX) + 0.5f;	// CoreGraphics lines are positioned between pixels rather than on them
		float lineStartY = fillBounds.origin.y;
		float lineEndY = roundf(centerY);
		inContext->drawLine(linePosX, lineStartY, linePosX, lineEndY, 1.0f);
	}
	else if (val >= max)
	{
		CGContextAddEllipseInRect(cgContext, fillBounds);
		inContext->fillPath();
	}
	else
	{
		double paramValue_gen = getDfxGuiEditor()->getparameter_f( getParameterID() );
		const CAAUParameter auParam = getAUVP();
		paramValue_gen = AUParameterValueToLinear(paramValue_gen, &auParam);
		CGFloat radius = fillBounds.size.width * 0.5;
		CGFloat startAngle = 0.0;
		CGFloat angle = paramValue_gen * (kDFX_PI_d * 2.0);
startAngle = kDFX_PI_d * 0.5;
angle = kDFX_PI_d;
		CGContextAddArc(cgContext, centerX, centerY, radius, startAngle, angle + startAngle, 0);
		inContext->endPath();
		inContext->fillPath();
		inContext->beginPath();
		if (paramValue_gen >= 0.5)
		{
			startAngle -= (paramValue_gen - 0.5) * (kDFX_PI_d * 2.0);
			CGContextAddArc(cgContext, centerX, centerY, radius, startAngle, angle + startAngle, 0);
		}
		else
		{
			inContext->setFillColor(kControlBackgroundColor);
			radius += backgroundFrameWidth;
			startAngle -= paramValue_gen * (kDFX_PI_d * 2.0);
			CGContextAddArc(cgContext, centerX, centerY, radius, startAngle, angle + startAngle, 0);
		}
		inContext->endPath();
		inContext->fillPath();
	}

	DGTextDisplay::draw(inContext);
}
/*****************************************************
*
* Internal_HICustomViewHandler(inHandlerCallRef, inEvent, inUserData) 
*
* Purpose:  Event handler that implements our HICustomView custom view
*
* Inputs:   inHandlerCallRef    - reference to the current handler call chain
*           inEvent             - the event
*           inUserData          - app-specified data you passed in the call to InstallEventHandler
*
* Returns:  OSStatus            - error code (0 == no error) 
*/
static pascal OSStatus Internal_HICustomViewHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void * inUserData)
	{
	OSStatus status = eventNotHandledErr;
	HICustomViewData * myData = (HICustomViewData *)inUserData;

	switch (GetEventClass(inEvent))
		{
		case kEventClassHIObject:
			switch (GetEventKind(inEvent))
				{
				case kEventHIObjectConstruct:
					{
					// allocate some instance data
					myData = (HICustomViewData *) calloc(1, sizeof(HICustomViewData));
					require_action(myData != NULL, ConstructExit, status = memFullErr);
					
					// get our superclass instance
					HIViewRef epView;
					status = GetEventParameter(inEvent, kEventParamHIObjectInstance, typeHIObjectRef, NULL, sizeof(epView), NULL, &epView);
					require_noerr(status, ConstructExit);
					
					// remember our superclass in our instance data
					myData->view = epView;
					
					// store our instance data into the event
					status = SetEventParameter(inEvent, kEventParamHIObjectInstance, typeVoidPtr, sizeof(myData), &myData);
					require_noerr(status, ConstructExit);

ConstructExit:
					break;
					}
					
#pragma mark *   kEventHIObjectInitialize
				case kEventHIObjectInitialize:
					{
					// always begin kEventHIObjectInitialize by calling through to the previous handler
					status = CallNextEventHandler(inHandlerCallRef, inEvent);
					require_noerr(status, InitializeExit);
					
					// if that succeeded, do our own initialization

					// in this sample code, there is nothing to do

InitializeExit:
					break;
					}
					
				case kEventHIObjectDestruct:
					{
					// freeing our storage
					if (myData != NULL) free(myData);
					status = noErr;
					break;
					}
				
				default:
					break;
				}
			break;

		case kEventClassControl:
			switch (GetEventKind(inEvent))
				{
#pragma mark *   kEventControlDraw
				case kEventControlDraw:
					{
					CGContextRef context;
					status = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(context), NULL, &context);
					require_noerr(status, ControlDrawExit);

					HIRect bounds, viewBounds;
					HIViewGetBounds(myData->view, &viewBounds);

					// setting our colors according to state: IsControlEnabled, IsControlActive, IsControlHilited
					if (!IsControlEnabled(myData->view))
						{
						CGContextSetRGBFillColor(context, 0.3, 0.3, 0.3, 0.8);
						CGContextSetRGBStrokeColor(context, 0.5, 0.5, 0.5, 0.8);
						}
					else if (!IsControlActive(myData->view))
						{
						CGContextSetRGBFillColor(context, 0.7, 0.7, 0.7, 0.8);
						CGContextSetRGBStrokeColor(context, 0.8, 0.8, 0.8, 0.8);
						}
					else if (!IsControlHilited(myData->view))
						{
						CGContextSetRGBFillColor(context, 1, 0, 0, 0.8);
						CGContextSetRGBStrokeColor(context, 0, 0, 1, 0.8);
						}
					else
						{
						CGContextSetRGBFillColor(context, 0.7, 0, 0, 0.8);
						CGContextSetRGBStrokeColor(context, 0, 0, 0.7, 0.8);
						}

					// using a line thickness of 3
					CGContextSetLineWidth(context, 3);
					bounds = CGRectInset(viewBounds, 3, 3);
					float minDim = (bounds.size.height < bounds.size.width) ? bounds.size.height / 2 : bounds.size.width / 2;
					float cx = bounds.origin.x + minDim, cy = bounds.origin.y + minDim;
					UInt32 i, n = GetControl32BitValue(myData->view);

					// having some fun with geometric shapes based on the value of the custom view
					CGContextBeginPath(context);
					switch (n)
						{
						case 0: CGContextAddArc(context, cx, cy, minDim, 0, 2 * pi, true); break;
						case 1: CGContextAddEllipseInRect(context, CGRectInset(bounds, bounds.size.width * 0.4, 0)); break;
						default:
							{
							float deltangle = pi / n, angle = 0, r = minDim / 2;
							CGContextMoveToPoint(context, cx + minDim, cy);
							for (i = 0; i < n; i++)
								{
								angle += deltangle;
								CGContextAddLineToPoint(context, cx + r * cos(angle), cy + r * sin(angle));
								angle += deltangle;
								CGContextAddLineToPoint(context, cx + minDim * cos(angle), cy + minDim * sin(angle));
								}
							CGContextAddLineToPoint(context, cx + minDim, cy);
							}
						}
					CGContextClosePath(context);
					CGContextDrawPath(context, kCGPathFillStroke);

					status = noErr;
ControlDrawExit:
					break;
					}					

#pragma mark *   kEventControl___Changed
				case kEventControlValueFieldChanged:
				case kEventControlHiliteChanged:
					{
					// just asking for a refresh
					HIViewSetNeedsDisplay(myData->view, true);
					break;
					}

				default:
					break;
				}
			break;
			
		default:
			break;
		}
	
	return status;
	}   // Internal_HICustomViewHandler