Exemplo n.º 1
0
void drawRoundedRect(CGContextRef context, CGRect rrect)
{
    // Drawing with a white stroke color
    CGContextSetRGBStrokeColor(context, 0.3, 0.3, 0.3, 1.0);
    CGContextSetRGBFillColor(context, 0.3, 0.3, 0.3, 1.0);
    
    // Add Rect to the current path, then stroke it
    //            CGContextAddRect(context, CGRectMake(10.0, 190.0, 290.0, 73.0));
    
    
    CGContextSetLineWidth(context, 1);
    CGFloat radius = 10.0;
    
    CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect);
    CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect);
    
    // Next, we will go around the rectangle in the order given by the figure below.
    //       minx    midx    maxx
    // miny    2       3       4
    // midy   1 9              5
    // maxy    8       7       6
    // Which gives us a coincident start and end point, which is incidental to this technique, but still doesn't
    // form a closed path, so we still need to close the path to connect the ends correctly.
    // Thus we start by moving to point 1, then adding arcs through each pair of points that follows.
    // You could use a similar tecgnique to create any shape with rounded corners.
    
    // Start at 1
    CGContextMoveToPoint(context, minx, midy);
    // Add an arc through 2 to 3
    CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
    // Add an arc through 4 to 5
    CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
    // Add an arc through 6 to 7
    CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
    // Add an arc through 8 to 9
    CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
    // Close the path
    CGContextClosePath(context);
    // Fill & stroke the path
    CGContextDrawPath(context, kCGPathFillStroke);
    
    CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 0.0);
    CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
    
    CGContextMoveToPoint(context, minx, midy);
    // Add an arc through 2 to 3
    CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
    // Add an arc through 4 to 5
    CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
    // Add an arc through 6 to 7
    CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
    // Add an arc through 8 to 9
    CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
    // Close the path
    CGContextClosePath(context);
    // Fill & stroke the path
    CGContextDrawPath(context, kCGPathFillStroke);
}
Exemplo n.º 2
0
FX_BOOL CFX_QuartzDeviceDriver::DrawPath(const CFX_PathData*        pathData,
        const CFX_AffineMatrix*       matrix,
        const CFX_GraphStateData*     graphState,
        FX_DWORD                      fillArgb,
        FX_DWORD                      strokeArgb,
        int                           fillMode,
        int                           alpha_flag,
        void*                         pIccTransform,
        int							blend_type
                                        )
{
    SaveState();
    CGBlendMode mode = GetCGBlendMode(blend_type);
    if (mode != kCGBlendModeNormal) {
        CGContextSetBlendMode(_context, mode);
    }
    CGAffineTransform m = CGAffineTransformIdentity;
    if (matrix) {
        m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(), matrix->GetE(), matrix->GetF());
    }
    m = CGAffineTransformConcat(m, _foxitDevice2User);
    CGContextConcatCTM(_context, m);
    int pathMode = 0;
    if (graphState && strokeArgb) {
        CGContextSetMiterLimit(_context, graphState->m_MiterLimit);
        FX_FLOAT lineWidth = getLineWidth(graphState, m);
        setStrokeInfo(graphState, strokeArgb, lineWidth);
        pathMode |= 4;
    }
    if (fillMode && fillArgb) {
        setFillInfo(fillArgb);
        if ((fillMode & 3) == FXFILL_WINDING) {
            pathMode |= 1;
        } else if ((fillMode & 3) == FXFILL_ALTERNATE) {
            pathMode |= 2;
        }
    }
    setPathToContext(pathData);
    if (fillMode & FXFILL_FULLCOVER) {
        CGContextSetShouldAntialias(_context, false);
    }
    if (pathMode == 4) {
        CGContextStrokePath(_context);
    } else if (pathMode == 1) {
        CGContextFillPath(_context);
    } else if (pathMode == 2) {
        CGContextEOFillPath(_context);
    } else if (pathMode == 5) {
        CGContextDrawPath(_context, kCGPathFillStroke);
    } else if (pathMode == 6) {
        CGContextDrawPath(_context, kCGPathEOFillStroke);
    }
    RestoreState(FALSE);
    return TRUE;
}
void doIndexedColorDrawGraphics(CGContextRef context)
{
	CGColorSpaceRef theBaseRGBSpace = getTheCalibratedRGBColorSpace();
	CGColorSpaceRef theIndexedSpace = NULL;
	unsigned char lookupTable[6];
	float opaqueRed[] = { 0, 1 }; // index, alpha
	float aBlue[] = { 1, 1 };   // index, alpha
	
	// Set the first 3 values in the lookup table to a red of
	// 169/255 = 0.663, no green, and blue = 8/255 = 0.031. This makes  
	// the first entry in the lookup table a shade of red.
	lookupTable[0] = 169; lookupTable[1] = 0; lookupTable[2] = 8;
	
	// Set the second 3 values in the lookup table to a red value
	// of 123/255 = 0.482, a green value of 158/255 = 0.62, and
	// a blue value of 222/255 = 0.871. This makes the second entry
	// in the lookup table a shade of blue.
	lookupTable[3] = 123; lookupTable[4] = 158; lookupTable[5] = 222;
	
	// Create the indexed color space with this color lookup table,
	// using the RGB color space as the base color space and a 2 element
	// color lookup table to characterize the indexed color space.
	theIndexedSpace = CGColorSpaceCreateIndexed(theBaseRGBSpace, 1, lookupTable);
	if(theIndexedSpace != NULL){
	    CGContextSetStrokeColorSpace(context, theIndexedSpace);
	    CGContextSetFillColorSpace(context, theIndexedSpace);
	    // Release the color space this code created since it is no
		// longer needed in this routine.
	    CGColorSpaceRelease(theIndexedSpace);

	    // Set the stroke color to an opaque blue.
	    CGContextSetStrokeColor(context, aBlue);
	    // Set the fill color to an opaque red.
	    CGContextSetFillColor(context, opaqueRed);

	    CGContextSetLineWidth(context, 8.);
	 	// Draw the first rectangle.
	    CGContextBeginPath(context);
	    CGContextAddRect(context, CGRectMake(20., 20., 100., 100.));
	    CGContextDrawPath(context, kCGPathFillStroke);

	    // Continue to use the stroke colorspace already set
	    // but change the stroke alpha value to a semitransparent value
	    // while leaving the index value unchanged.
	    aBlue[1] = 0.5;
	    CGContextSetStrokeColor(context, aBlue);
	    // Draw another rectangle to the right of the first one.
	    CGContextBeginPath(context);
	    CGContextAddRect(context, CGRectMake(140., 20., 100., 100.));
	    CGContextDrawPath(context, kCGPathFillStroke);
	}else
	    fprintf(stderr, "Couldn't make the indexed color space!\n");
}
Exemplo n.º 4
0
//-----------------------------------------------------------------------------
void CGDrawContext::drawArc (const CRect &rect, const float _startAngle, const float _endAngle, const CDrawStyle drawStyle) // in degree
{
    CGContextRef context = beginCGContext (true, getDrawMode ().integralMode ());
    if (context)
    {
        CGPathDrawingMode m;
        switch (drawStyle)
        {
        case kDrawFilled :
            m = kCGPathFill;
            break;
        case kDrawFilledAndStroked :
            m = kCGPathFillStroke;
            break;
        default :
            m = kCGPathStroke;
            break;
        }
        applyLineStyle (context);

        CGContextBeginPath (context);
        CGDrawContextInternal::addOvalToPath (context, CPoint (rect.left + rect.getWidth () / 2., rect.top + rect.getHeight () / 2.), static_cast<CGFloat> (rect.getWidth () / 2.), static_cast<CGFloat> (rect.getHeight () / 2.), _startAngle, _endAngle);
        CGContextDrawPath (context, m);
        releaseCGContext (context);
    }
}
Exemplo n.º 5
0
//-----------------------------------------------------------------------------
void CGDrawContext::drawEllipse (const CRect &rect, const CDrawStyle drawStyle)
{
    CGContextRef context = beginCGContext (true, getDrawMode ().integralMode ());
    if (context)
    {
        CGRect r = CGRectMake (static_cast<CGFloat> (rect.left), static_cast<CGFloat> (rect.top + 1), static_cast<CGFloat> (rect.getWidth () - 1), static_cast<CGFloat> (rect.getHeight () - 1));

        CGPathDrawingMode m;
        switch (drawStyle)
        {
        case kDrawFilled :
            m = kCGPathFill;
            break;
        case kDrawFilledAndStroked :
            m = kCGPathFillStroke;
            break;
        default :
            m = kCGPathStroke;
            break;
        }
        applyLineStyle (context);
        if (getDrawMode ().integralMode ())
        {
            r = pixelAlligned (r);
            applyLineWidthCTM (context);
        }

        CGContextAddEllipseInRect (context, r);
        CGContextDrawPath (context, m);

        releaseCGContext (context);
    }
}
DRAW_TEST_P(CGContextFillMode, OverlappedEllipses) {
    CGContextRef context = GetDrawingContext();
    CGRect bounds = GetDrawingBounds();
    bounds = CGRectInset(bounds, 16.f, 16.f);
    CGFloat width = bounds.size.width;
    CGFloat height = bounds.size.height;
    CGFloat xstart = bounds.origin.x;
    CGFloat ystart = bounds.origin.y;

    CGPathDrawingMode fillMode = GetParam();

    CGMutablePathRef leftCircles = CGPathCreateMutable();

    CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .4 * height, ystart + .5 * height);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .4 * height, 0, M_PI, true);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .4 * height, M_PI, 0, true);

    CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .3 * height, ystart + .5 * height);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .3 * height, 0, M_PI, true);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .3 * height, M_PI, 0, true);

    CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .2 * height, ystart + .5 * height);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .2 * height, 0, M_PI, true);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .2 * height, M_PI, 0, true);

    CGPathMoveToPoint(leftCircles, NULL, xstart + .25 * width + .1 * height, ystart + .5 * height);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .1 * height, 0, M_PI, true);
    CGPathAddArc(leftCircles, NULL, xstart + .25 * width, ystart + .5 * height, .1 * height, M_PI, 0, true);

    CGPathCloseSubpath(leftCircles);

    CGMutablePathRef rightCircles = CGPathCreateMutable();

    CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .4 * height, ystart + .5 * height);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .4 * height, 0, M_PI, false);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .4 * height, M_PI, 0, false);

    CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .3 * height, ystart + .5 * height);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .3 * height, 0, M_PI, true);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .3 * height, M_PI, 0, true);

    CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .2 * height, ystart + .5 * height);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .2 * height, 0, M_PI, false);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .2 * height, M_PI, 0, false);

    CGPathMoveToPoint(rightCircles, NULL, xstart + .75 * width + .1 * height, ystart + .5 * height);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .1 * height, 0, M_PI, true);
    CGPathAddArc(rightCircles, NULL, xstart + .75 * width, ystart + .5 * height, .1 * height, M_PI, 0, true);

    CGPathCloseSubpath(rightCircles);

    CGContextAddPath(context, leftCircles);
    CGContextAddPath(context, rightCircles);
    CGContextSetRGBFillColor(context, 0, 0, 1, 1);
    CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
    CGContextDrawPath(context, fillMode);

    CGPathRelease(leftCircles);
    CGPathRelease(rightCircles);
}
Exemplo n.º 7
0
//-----------------------------------------------------------------------------
void CGDrawContext::drawLine (const LinePair& line)
{
    CGContextRef context = beginCGContext (true, getDrawMode ().integralMode ());
    if (context)
    {
        applyLineStyle (context);

        CGContextBeginPath (context);
        CGPoint first = CGPointFromCPoint (line.first);
        CGPoint second = CGPointFromCPoint (line.second);

        if (getDrawMode ().integralMode ())
        {
            first = pixelAlligned (first);
            second = pixelAlligned (second);

            int32_t frameWidth = static_cast<int32_t> (currentState.frameWidth);
            if (frameWidth % 2)
                CGContextTranslateCTM (context, 0.5, 0.5);
        }

        CGContextMoveToPoint (context, first.x, first.y);
        CGContextAddLineToPoint (context, second.x, second.y);

        CGContextDrawPath (context, kCGPathStroke);
        releaseCGContext (context);
    }
}
Exemplo n.º 8
0
void GraphicsContext::drawPath(const Path& path)
{
    if (paintingDisabled())
        return;

    CGContextRef context = platformContext();
    const GraphicsContextState& state = m_state;

    if (state.fillGradient || state.strokeGradient) {
        // We don't have any optimized way to fill & stroke a path using gradients
        // FIXME: Be smarter about this.
        fillPath(path);
        strokePath(path);
        return;
    }

    CGContextBeginPath(context);
    CGContextAddPath(context, path.platformPath());

    if (state.fillPattern)
        applyFillPattern();
    if (state.strokePattern)
        applyStrokePattern();

    CGPathDrawingMode drawingMode;
    if (calculateDrawingMode(state, drawingMode))
        CGContextDrawPath(context, drawingMode);
}
Exemplo n.º 9
0
// This method is only used to draw the little circles used in lists.
void GraphicsContext::drawEllipse(const IntRect& rect)
{
    // FIXME: CG added CGContextAddEllipseinRect in Tiger, so we should be able to quite easily draw an ellipse.
    // This code can only handle circles, not ellipses. But khtml only
    // uses it for circles.
    ASSERT(rect.width() == rect.height());

    if (paintingDisabled())
        return;
        
    CGContextRef context = platformContext();
    CGContextBeginPath(context);
    float r = (float)rect.width() / 2;
    CGContextAddArc(context, rect.x() + r, rect.y() + r, r, 0, 2*M_PI, true);
    CGContextClosePath(context);

    if (fillColor().alpha()) {
        if (strokeStyle() != NoStroke)
            // stroke and fill
            CGContextDrawPath(context, kCGPathFillStroke);
        else
            CGContextFillPath(context);
    } else if (strokeStyle() != NoStroke)
        CGContextStrokePath(context);
}
Exemplo n.º 10
0
static void quartzgen_path(GVJ_t *job, int filled)
{
	CGContextRef context = (CGContextRef)job->context;
	
	/* set up colors */
	if (filled)
		CGContextSetRGBFillColor(context, job->obj->fillcolor.u.RGBA [0], job->obj->fillcolor.u.RGBA [1], job->obj->fillcolor.u.RGBA [2], job->obj->fillcolor.u.RGBA [3]);
	CGContextSetRGBStrokeColor(context, job->obj->pencolor.u.RGBA [0], job->obj->pencolor.u.RGBA [1], job->obj->pencolor.u.RGBA [2], job->obj->pencolor.u.RGBA [3]);
	
	/* set up line style */
	const CGFloat *segments;
	size_t segment_count;
	switch (job->obj->pen) {
	case PEN_DASHED:
		segments = dashed;
		segment_count = sizeof(dashed)/sizeof(CGFloat);
		break;
	case PEN_DOTTED:
		segments = dotted;
		segment_count = sizeof(dotted)/sizeof(CGFloat);
		break;
	default:
		segments = NULL;
		segment_count = 0;
		break;
	}
	CGContextSetLineDash(context, 0.0, segments, segment_count);

	/* set up line width */
	CGContextSetLineWidth(context, job->obj->penwidth); // *job->scale.x);
	
	/* draw the path */
	CGContextDrawPath(context, filled ? kCGPathFillStroke : kCGPathStroke);
}
void doRotatedEllipses(CGContextRef context)
{
	int i, totreps = 144;
	float  tint = 1.0, tintIncrement = 1.0/totreps;
	// Create a new transform consisting of a 45 degrees rotation.
	CGAffineTransform theTransform = CGAffineTransformMakeRotation(M_PI/4);
	// Apply a scale to the transform just created.
	theTransform = CGAffineTransformScale(theTransform, 1, 2);
	// Place the first ellipse at a good location.
	CGContextTranslateCTM(context, 100., 100.);
	
	for(i=0 ; i < totreps ; i++){
		// Make a snapshot the coordinate system.
		CGContextSaveGState(context);
			// Set up the coordinate system for the rotated ellipse.
			CGContextConcatCTM(context, theTransform);
			CGContextBeginPath(context);
			CGContextAddArc(context, 0., 0., 45., 0., 2*M_PI, 0); 
			// Set the fill color for this instance of the ellipse.
			CGContextSetRGBFillColor(context, tint, 0., 0., 1.0);
			CGContextDrawPath(context, kCGPathFill);
		// Restore the coordinate system to that of the snapshot.
		CGContextRestoreGState(context);
		// Compute the next tint color.
		tint -= tintIncrement;
		// Move over by 1 unit in x for the next ellipse.
		CGContextTranslateCTM(context, 1.0, 0.0);
	}
}
Exemplo n.º 12
0
//-----------------------------------------------------------------------------
void CGDrawContext::drawRect (const CRect &rect, const CDrawStyle drawStyle)
{
	CGContextRef context = beginCGContext (true, currentState.drawMode.integralMode ());
	if (context)
	{
		CGPathDrawingMode m;
		switch (drawStyle)
		{
			case kDrawFilled : m = kCGPathFill; break;
			case kDrawFilledAndStroked : m = kCGPathFillStroke; break;
			default : m = kCGPathStroke; break;
		}
		applyLineStyle (context);

		CGRect r;
		if (currentState.drawMode.integralMode ())
		{
			r = CGRectMake (round (rect.left), round (rect.top + 1), round (rect.width () - 1), round (rect.height () - 1));
		}
		else
		{
			r = CGRectMake (rect.left, rect.top + 1, rect.width () - 1, rect.height () - 1);
		}

		if ((((int32_t)currentState.frameWidth) % 2))
			CGContextTranslateCTM (context, 0.5f, -0.5f);

		CGContextBeginPath (context);
		CGContextAddRect (context, r);
		CGContextDrawPath (context, m);

		releaseCGContext (context);
	}
}
Exemplo n.º 13
0
//-----------------------------------------------------------------------------
void CGDrawContext::lineTo (const CPoint& point)
{
	CGContextRef context = beginCGContext (true, currentState.drawMode.integralMode ());
	if (context)
	{
		applyLineStyle (context);

		if ((((int32_t)currentState.frameWidth) % 2))
			CGContextTranslateCTM (context, 0.5f, -0.5f);

		CGContextBeginPath (context);
		if (currentState.drawMode.integralMode ())
		{
			CGContextMoveToPoint (context, round (currentState.penLoc.h), round (currentState.penLoc.v));
			CGContextAddLineToPoint (context, round (point.h), round (point.v));
		}
		else
		{
			CGContextMoveToPoint (context, currentState.penLoc.h, currentState.penLoc.v);
			CGContextAddLineToPoint (context, point.h, point.v);
		}
		CGContextDrawPath (context, kCGPathStroke);
		releaseCGContext (context);
	}
	currentState.penLoc = point;
}
Exemplo n.º 14
0
//-----------------------------------------------------------------------------
void CGDrawContext::drawEllipse (const CRect &rect, const CDrawStyle drawStyle)
{
	CGContextRef context = beginCGContext (true, currentState.drawMode.integralMode ());
	if (context)
	{
		CGPathDrawingMode m;
		switch (drawStyle)
		{
			case kDrawFilled : m = kCGPathFill; break;
			case kDrawFilledAndStroked : m = kCGPathFillStroke; break;
			default : m = kCGPathStroke; break;
		}
		applyLineStyle (context);

		if (rect.width () != rect.height ())
		{
			CGContextSaveGState (context);

			CGContextBeginPath (context);

			CGRect cgRect = CGRectMake (rect.left, rect.top, rect.width (), rect.height ());
			CGPoint center = CGPointMake (CGRectGetMidX (cgRect), CGRectGetMidY (cgRect));
			CGFloat a = CGRectGetWidth (cgRect) / 2.;
			CGFloat b = CGRectGetHeight (cgRect) / 2.;

		    CGContextTranslateCTM (context, center.x, center.y);
		    CGContextScaleCTM (context, a, b);
		    CGContextMoveToPoint (context, 1, 0);
		    CGContextAddArc (context, 0, 0, 1, radians (0), radians (360), 0);

			CGContextClosePath (context);
			CGContextRestoreGState (context);
			CGContextDrawPath (context, m);
		}
		else
		{
			CGFloat radius = rect.width () * 0.5;
			CGContextBeginPath (context);
			CGContextAddArc (context, rect.left + radius, rect.top + radius, radius, radians (0), radians (360), 0);
			CGContextClosePath (context);
			CGContextDrawPath (context, m);
		}
		releaseCGContext (context);
	}
}
void drawWithColorRefs(CGContextRef context)
{
	static CGColorRef opaqueRedColor = NULL, opaqueBlueColor = NULL, transparentBlueColor = NULL;

	// Initialize the CGColorRefs if necessary
	if(opaqueRedColor == NULL){
		// Initialize the color array to an opaque red 
		// in the generic calibrated RGB color space.
		float color[4] = { 0.663, 0.0, 0.031, 1.0 };
		CGColorSpaceRef theColorSpace = getTheCalibratedRGBColorSpace();
		// Create a CGColorRef for opaque red.
		opaqueRedColor = CGColorCreate(theColorSpace, color);
		// Make the color array correspond to an opaque blue color.
		color[0] = 0.482; color[1] = 0.62; color[2] = 0.871;
		// Create another CGColorRef for opaque blue.
		opaqueBlueColor = CGColorCreate(theColorSpace, color);
		// Create a new CGColorRef from the opaqueBlue CGColorRef 
		// but with a different alpha value.
		transparentBlueColor = CGColorCreateCopyWithAlpha(opaqueBlueColor, 0.5);
		if(!(opaqueRedColor && opaqueBlueColor && transparentBlueColor)){
		    fprintf(stderr, "Couldn't create one of the CGColorRefs!!!\n");
		    return;
		}
	}

	// Set the fill color to the opaque red CGColor object.
	CGContextSetFillColorWithColor(context, opaqueRedColor);
	// Set the stroke color to the opaque blue CGColor object.
	CGContextSetStrokeColorWithColor(context, opaqueBlueColor);
	
	CGContextSetLineWidth(context, 8.);
	// Draw the first rectangle.
	CGContextBeginPath(context);
	CGContextAddRect(context, CGRectMake(20., 20., 100., 100.));
	CGContextDrawPath(context, kCGPathFillStroke);
    
	// Set the stroke color to be that of the transparent blue 
	// CGColor object.
	CGContextSetStrokeColorWithColor(context, transparentBlueColor);	
	// Draw a second rectangle to the right of the first one.
	CGContextBeginPath(context);
 	CGContextAddRect(context, CGRectMake(140., 20., 100., 100.));
	CGContextDrawPath(context, kCGPathFillStroke);
}
void doRoundedRects(CGContextRef context)
{
	CGRect rect = {{10., 10.}, {210., 150.}};
	float ovalWidth = 100., ovalHeight = 100.;
	CGContextSetLineWidth(context, 2.);
	CGContextBeginPath(context);
	addRoundedRectToPath(context, rect, ovalWidth, ovalHeight);
	CGContextSetRGBStrokeColor(context, 1., 0., 0., 1.);
	CGContextDrawPath(context, kCGPathStroke);
}
Exemplo n.º 17
0
DRAW_TEST_F(CGContextFlush, FillFlush, WhiteBackgroundTest<>) {
    CGContextRef context = GetDrawingContext();
    CGRect bounds = GetDrawingBounds();
    _CGContextPushBeginDraw(context);

    CGContextSetRGBFillColor(context, 1, 0, 0, 1);
    CGContextFillRect(context, bounds);

    // Flush the red fill rect
    CGContextFlush(context);

    CGContextSetRGBFillColor(context, 0, 0, 1, 1);
    CGContextFillRect(context, CGRectMake(0, 0, 300, 300));

    // We should still have red & blue rectangle should not show up.
    unsigned char* dataPtr = static_cast<unsigned char*>(CGBitmapContextGetData(context));
    ASSERT_NE(dataPtr, nullptr);

    // Validate only the red fill rect is executed.
    EXPECT_EQ(dataPtr[0], 0x00);
    EXPECT_EQ(dataPtr[1], 0x00);
    EXPECT_EQ(dataPtr[2], 0xff);
    EXPECT_EQ(dataPtr[3], 0xff);

    CGContextFlush(context);

    // We should now see the blue fill rect
    EXPECT_EQ(dataPtr[0], 0xff);
    EXPECT_EQ(dataPtr[1], 0x00);
    EXPECT_EQ(dataPtr[2], 0x00);
    EXPECT_EQ(dataPtr[3], 0xff);

    // Add some extra drawings
    CGContextClearRect(context, CGRectMake(100, 100, 200, 300));

    CGPoint center = _CGRectGetCenter(bounds);

    CGMutablePathRef concentricCirclesPath = CGPathCreateMutable();

    CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 50, 50 }, center));
    CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 100, 100 }, center));
    CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 150, 150 }, center));
    CGPathAddEllipseInRect(concentricCirclesPath, nullptr, _CGRectCenteredOnPoint({ 200, 200 }, center));

    CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 0.5);
    CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);

    CGContextAddPath(context, concentricCirclesPath);
    CGContextDrawPath(context, kCGPathFillStroke);

    CGPathRelease(concentricCirclesPath);

    _CGContextPopEndDraw(context);
}
Exemplo n.º 18
0
bool GiCanvasIos::rawEndPath(const GiContext* ctx, bool fill)
{
    bool usepen = m_draw->setPen(ctx);
    bool usebrush = fill && m_draw->setBrush(ctx);
    
    if (usepen || usebrush) {
        CGContextDrawPath(m_draw->getContext(), usepen && usebrush ? kCGPathFillStroke
                          : usepen ? kCGPathStroke : kCGPathFill);
    }

    return usepen || usebrush;
}
Exemplo n.º 19
0
//-----------------------------------------------------------------------------
void CGDrawContext::drawGraphicsPath (CGraphicsPath* _path, PathDrawMode mode, CGraphicsTransform* t)
{
    QuartzGraphicsPath* path = dynamic_cast<QuartzGraphicsPath*> (_path);
    if (path == 0)
        return;

    CGContextRef context = beginCGContext (true, getDrawMode ().integralMode ());
    if (context)
    {
        CGPathDrawingMode cgMode;
        switch (mode)
        {
        case kPathFilledEvenOdd:
        {
            cgMode = kCGPathEOFill;
            break;
        }
        case kPathStroked:
        {
            cgMode = kCGPathStroke;
            applyLineStyle (context);
            break;
        }
        default:
        {
            cgMode = kCGPathFill;
            break;
        }
        }

        if (getDrawMode ().integralMode ())
        {
            applyLineWidthCTM (context);
            path->pixelAlign (this, t);
            CGContextAddPath (context, path->getCGPathRef ());
        }
        else if (t)
        {
            CGContextSaveGState (context);
            CGAffineTransform transform = QuartzGraphicsPath::createCGAffineTransform (*t);
            CGContextConcatCTM (context, transform);
            CGContextAddPath (context, path->getCGPathRef ());
            CGContextRestoreGState (context);
        }
        else
            CGContextAddPath (context, path->getCGPathRef ());

        CGContextDrawPath (context, cgMode);

        releaseCGContext (context);
    }
}
void doColorSpaceFillAndStroke(CGContextRef context)
{
	CGColorSpaceRef theColorSpace = getTheCalibratedRGBColorSpace();
	float opaqueRed[] = { 0.663, 0.0, 0.031, 1.0 }; // red,green,blue,alpha
	float aBlue[] = { 0.482, 0.62, 0.871, 1.0 };	// red,green,blue,alpha
	
	// Set the fill color space to be the generic calibrated RGB color space.
	CGContextSetFillColorSpace(context, theColorSpace);
	// Set the fill color to opaque red. The number of elements in the
	// array passed to this function must be the number of color
	// components in the current fill color space plus 1 for alpha.
	CGContextSetFillColor(context, opaqueRed);
	
	// Set the stroke color space to be the generic calibrated RGB color space.
	CGContextSetStrokeColorSpace(context, theColorSpace);
	// Set the stroke color to opaque blue. The number of elements
	// in the array passed to this function must be the number of color
	// components in the current stroke color space plus 1 for alpha.
	CGContextSetStrokeColor(context, aBlue);
	
	CGContextSetLineWidth(context, 8.);
 	// Rectangle 1.
	CGContextBeginPath(context);
	CGContextAddRect(context, CGRectMake(20., 20., 100., 100.));
	CGContextDrawPath(context, kCGPathFillStroke);
    
	// Continue to use the stroke colorspace already set
	// but change the stroke alpha value to a semitransparent blue.
	aBlue[3] = 0.5;
	CGContextSetStrokeColor(context, aBlue);
 	// Rectangle 2.
	CGContextBeginPath(context);
	CGContextAddRect(context, CGRectMake(140., 20., 100., 100.));
	CGContextDrawPath(context, kCGPathFillStroke);
    
	// Don't release the color space since this routine 
	// didn't create it.
}
void doEgg(CGContextRef context)
{
	CGPoint p0 = {0., 0.}, p1 = {0., 200.};
	CGPoint c1 = {140., 5.}, c2 = {80., 198.};
	CGContextTranslateCTM(context, 100., 5.);
	CGContextBeginPath(context);
	
	CGContextMoveToPoint(context, p0.x, p0.y);
	// Create the BŽzier path segment for the right side of the egg.
	CGContextAddCurveToPoint(context, c1.x, c1.y, c2.x, c2.y, p1.x, p1.y);
	// Create the BŽzier path segment for the left side of the egg.
	CGContextAddCurveToPoint(context, -c2.x, c2.y, -c1.x, c1.y, p0.x, p0.y);
	CGContextClosePath(context);
	CGContextSetLineWidth(context, 2);
	CGContextDrawPath(context, kCGPathStroke);
}
Exemplo n.º 22
0
bool GiCanvasIos::rawPath(const GiContext* ctx, 
                          int count, const Point2d* pxs, const UInt8* types)
{
    CGContextBeginPath(m_draw->getContext());
    
    for (int i = 0; i < count; i++)
    {
        switch (types[i] & ~kGiCloseFigure)
        {
        case kGiMoveTo:
            CGContextMoveToPoint(m_draw->getContext(), pxs[i].x, pxs[i].y);
            break;

        case kGiLineTo:
            CGContextAddLineToPoint(m_draw->getContext(), pxs[i].x, pxs[i].y);
            break;

        case kGiBeziersTo:
            if (i + 2 >= count)
                return false;
            CGContextAddCurveToPoint(m_draw->getContext(), 
                pxs[i+0].x, pxs[i+0].y,
                pxs[i+1].x, pxs[i+1].y,
                pxs[i+2].x, pxs[i+2].y);
            i += 2;
            break;

        default:
            return false;
        }
        if (types[i] & kGiCloseFigure)
            CGContextClosePath(m_draw->getContext());
    }

    bool usepen = m_draw->setPen(ctx);
    bool usebrush = m_draw->setBrush(ctx);
    bool ret = count > 1 && (usepen || usebrush);
    
    if (ret) {
        CGContextDrawPath(m_draw->getContext(), usepen && usebrush ? kCGPathFillStroke
                          : usepen ? kCGPathStroke : kCGPathFill);
    }

    return ret;
}
Exemplo n.º 23
0
bool GiCanvasIos::rawPolygon(const GiContext* ctx, const Point2d* pxs, int count)
{
    bool usepen = m_draw->setPen(ctx);
    bool usebrush = m_draw->setBrush(ctx);
    bool ret = count > 1 && (usepen || usebrush);

    if (ret)
    {
        CGContextMoveToPoint(m_draw->getContext(), pxs[0].x, pxs[0].y);
        for (int i = 1; i < count; i++) {
            CGContextAddLineToPoint(m_draw->getContext(), pxs[i].x, pxs[i].y);
        }
        CGContextClosePath(m_draw->getContext());
        
        CGContextDrawPath(m_draw->getContext(), usepen && usebrush ? kCGPathFillStroke
                          : usepen ? kCGPathStroke : kCGPathFill);
    }

    return ret;
}
Exemplo n.º 24
0
//-----------------------------------------------------------------------------
void CGDrawContext::drawArc (const CRect &rect, const float _startAngle, const float _endAngle, const CDrawStyle drawStyle) // in degree
{
	CGContextRef context = beginCGContext (true, currentState.drawMode.integralMode ());
	if (context)
	{
		CGPathDrawingMode m;
		switch (drawStyle)
		{
			case kDrawFilled : m = kCGPathFill; break;
			case kDrawFilledAndStroked : m = kCGPathFillStroke; break;
			default : m = kCGPathStroke; break;
		}
		applyLineStyle (context);

		CGContextBeginPath (context);
		addOvalToPath (context, CPoint (rect.left + rect.width () / 2, rect.top + rect.height () / 2), rect.width () / 2, rect.height () / 2, -_startAngle, -_endAngle);
		if (drawStyle == kDrawFilled || kDrawFilledAndStroked)
			CGContextAddLineToPoint (context, rect.left + rect.width () / 2, rect.top + rect.height () / 2);
		CGContextDrawPath (context, m);
		releaseCGContext (context);
	}
}
Exemplo n.º 25
0
//-----------------------------------------------------------------------------
void CGDrawContext::drawPolygon (const CPoint* pPoints, int32_t numberOfPoints, const CDrawStyle drawStyle)
{
	CGContextRef context = beginCGContext (true, currentState.drawMode.integralMode ());
	if (context)
	{
		CGPathDrawingMode m;
		switch (drawStyle)
		{
			case kDrawFilled : m = kCGPathFill; break;
			case kDrawFilledAndStroked : m = kCGPathFillStroke; break;
			default : m = kCGPathStroke; break;
		}
		applyLineStyle (context);

		CGContextBeginPath (context);
		CGContextMoveToPoint (context, pPoints[0].h, pPoints[0].v);
		for (int32_t i = 1; i < numberOfPoints; i++)
			CGContextAddLineToPoint (context, pPoints[i].h, pPoints[i].v);
		CGContextDrawPath (context, m);
		releaseCGContext (context);
	}
}
Exemplo n.º 26
0
//-----------------------------------------------------------------------------
void CGDrawContext::drawPolygon (const PointList& polygonPointList, const CDrawStyle drawStyle)
{
    if (polygonPointList.size () == 0)
        return;
    CGContextRef context = beginCGContext (true, getDrawMode ().integralMode ());
    if (context)
    {
        CGPathDrawingMode m;
        switch (drawStyle)
        {
        case kDrawFilled :
            m = kCGPathFill;
            break;
        case kDrawFilledAndStroked :
            m = kCGPathFillStroke;
            break;
        default :
            m = kCGPathStroke;
            break;
        }
        applyLineStyle (context);

        CGContextBeginPath (context);
        CGPoint p = CGPointFromCPoint(polygonPointList[0]);
        if (getDrawMode ().integralMode ())
            p = pixelAlligned (p);
        CGContextMoveToPoint (context, p.x, p.y);
        for (uint32_t i = 1; i < polygonPointList.size (); i++)
        {
            p = CGPointFromCPoint (polygonPointList[i]);
            if (getDrawMode ().integralMode ())
                p = pixelAlligned (p);
            CGContextAddLineToPoint (context, p.x, p.y);
        }
        CGContextDrawPath (context, m);
        releaseCGContext (context);
    }
}
/*****************************************************
*
* 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
Exemplo n.º 28
0
void UIFrameBufferQuartz2D::paintEvent(QPaintEvent *aEvent)
{
    /* If the machine is NOT in 'running' state,
     * the link between framebuffer and video memory
     * is broken, we should go fallback now... */
    if (m_fUsesGuestVRAM &&
        !m_pMachineView->uisession()->isRunning() &&
        !m_pMachineView->uisession()->isPaused() &&
        /* Online snapshotting: */
        m_pMachineView->uisession()->machineState() != KMachineState_Saving)
    {
        /* Simulate fallback through fake resize-event: */
        UIResizeEvent event(FramebufferPixelFormat_Opaque, NULL, 0, 0, 640, 480);
        resizeEvent(&event);
    }

    /* For debugging /Developer/Applications/Performance Tools/Quartz
     * Debug.app is a nice tool to see which parts of the screen are
     * updated.*/
    Assert(m_image);

    QWidget* viewport = m_pMachineView->viewport();
    Assert(VALID_PTR(viewport));
    /* Get the dimensions of the viewport */
    CGRect viewRect = ::darwinToCGRect(viewport->geometry());
    /* Get the context of this window from Qt */
    CGContextRef ctx = ::darwinToCGContextRef(viewport);
    Assert(VALID_PTR(ctx));

    /* Flip the context */
    CGContextTranslateCTM(ctx, 0, viewRect.size.height);
    CGContextScaleCTM(ctx, 1.0, -1.0);

    /* We handle the seamless mode as a special case. */
    if (m_pMachineLogic->visualStateType() == UIVisualStateType_Seamless)
    {
        /* Clear the background (make the rect fully transparent): */
        CGContextClearRect(ctx, viewRect);

#ifdef OVERLAY_CLIPRECTS
        /* Enable overlay above the seamless mask: */
        CGContextSetRGBFillColor(ctx, 0.0, 0.0, 5.0, 0.7);
        CGContextFillRect(ctx, viewRect);
#endif /* OVERLAY_CLIPRECTS */
#ifdef COMP_WITH_SHADOW
        /* Enable shadows: */
        CGContextSetShadow(ctx, CGSizeMake (10, -10), 10);
        CGContextBeginTransparencyLayer(ctx, NULL);
#endif /* COMP_WITH_SHADOW */

        /* Determine current visible region: */
        RegionRects *pRgnRcts = ASMAtomicXchgPtrT(&mRegion, NULL, RegionRects*);
        if (pRgnRcts)
        {
            /* If visible region is determined: */
            if (pRgnRcts->used > 0)
            {
                /* Add the clipping rects all at once (they are defined in SetVisibleRegion): */
                CGContextBeginPath(ctx);
                CGContextAddRects(ctx, pRgnRcts->rcts, pRgnRcts->used);
                /* Now convert the path to a clipping path: */
                CGContextClip(ctx);
            }

            /* Put back the visible region, free if we cannot (2+ SetVisibleRegion calls): */
            if (   !ASMAtomicCmpXchgPtr(&mRegion, pRgnRcts, NULL)
                && !ASMAtomicCmpXchgPtr(&mRegionUnused, pRgnRcts, NULL))
            {
                RTMemFree(pRgnRcts);
                pRgnRcts = NULL;
            }
        }

        /* If visible region is still determined: */
        if (pRgnRcts && pRgnRcts->used > 0)
        {
            /* Create a subimage of the current view.
             * Currently this subimage is the whole screen. */
            CGImageRef subImage;
            if (!m_pMachineView->pauseShot().isNull())
            {
                CGImageRef pauseImg = ::darwinToCGImageRef(&m_pMachineView->pauseShot());
                subImage = CGImageCreateWithImageInRect(pauseImg, CGRectMake(m_pMachineView->contentsX(), m_pMachineView->contentsY(), m_pMachineView->visibleWidth(), m_pMachineView->visibleHeight()));
                CGImageRelease(pauseImg);
            }
            else
            {
#ifdef RT_ARCH_AMD64
                /* Not sure who to blame, but it seems on 64bit there goes
                 * something terrible wrong (on a second monitor) when directly
                 * using CGImageCreateWithImageInRect without making a copy. We saw
                 * something like this already with the scale mode. */
                CGImageRef tmpImage = CGImageCreateWithImageInRect(m_image, CGRectMake(m_pMachineView->contentsX(), m_pMachineView->contentsY(), m_pMachineView->visibleWidth(), m_pMachineView->visibleHeight()));
                subImage = CGImageCreateCopy(tmpImage);
                CGImageRelease(tmpImage);
#else /* RT_ARCH_AMD64 */
                subImage = CGImageCreateWithImageInRect(m_image, CGRectMake(m_pMachineView->contentsX(), m_pMachineView->contentsY(), m_pMachineView->visibleWidth(), m_pMachineView->visibleHeight()));
#endif /* !RT_ARCH_AMD64 */
            }
            Assert(VALID_PTR(subImage));

            /* In any case clip the drawing to the view window: */
            CGContextClipToRect(ctx, viewRect);
            /* At this point draw the real vm image: */
            CGContextDrawImage(ctx, ::darwinFlipCGRect(viewRect, viewRect.size.height), subImage);

            /* Release the subimage: */
            CGImageRelease(subImage);
        }

#ifdef COMP_WITH_SHADOW
        CGContextEndTransparencyLayer(ctx);
#endif /* COMP_WITH_SHADOW */
#ifdef OVERLAY_CLIPRECTS
        if (pRgnRcts && pRgnRcts->used > 0)
        {
            CGContextBeginPath(ctx);
            CGContextAddRects(ctx, pRgnRcts->rcts, pRgnRcts->used);
            CGContextSetRGBStrokeColor(ctx, 1.0, 0.0, 0.0, 0.7);
            CGContextDrawPath(ctx, kCGPathStroke);
        }
        CGContextSetRGBStrokeColor(ctx, 0.0, 1.0, 0.0, 0.7);
        CGContextStrokeRect(ctx, viewRect);
#endif /* OVERLAY_CLIPRECTS */
    }
Exemplo n.º 29
0
void drawPlugin(NPP instance, NPCocoaEvent* event)
{
  if (!browserUAString)
    return;

  PluginInstance* currentInstance = (PluginInstance*)(instance->pdata);
  CGContextRef cgContext = event->data.draw.context;
  if (!cgContext)
    return;

  float windowWidth = currentInstance->window.width;
  float windowHeight = currentInstance->window.height;
  
  // save the cgcontext gstate
  CGContextSaveGState(cgContext);
  
  // we get a flipped context
  CGContextTranslateCTM(cgContext, 0.0, windowHeight);
  CGContextScaleCTM(cgContext, 1.0, -1.0);
  
  // draw a gray background for the plugin
  CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight));
  CGContextSetGrayFillColor(cgContext, 0.5, 1.0);
  CGContextDrawPath(cgContext, kCGPathFill);
  
  // draw a black frame around the plugin
  CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight));
  CGContextSetGrayStrokeColor(cgContext, 0.0, 1.0);
  CGContextSetLineWidth(cgContext, 6.0);
  CGContextStrokePath(cgContext);
  
  // draw the UA string using ATSUI
  CGContextSetGrayFillColor(cgContext, 0.0, 1.0);
  ATSUStyle atsuStyle;
  ATSUCreateStyle(&atsuStyle);
  CFIndex stringLength = CFStringGetLength(browserUAString);
  UniChar* unicharBuffer = (UniChar*)malloc((stringLength + 1) * sizeof(UniChar));
  CFStringGetCharacters(browserUAString, CFRangeMake(0, stringLength), unicharBuffer);
  UniCharCount runLengths = kATSUToTextEnd;
  ATSUTextLayout atsuLayout;
  ATSUCreateTextLayoutWithTextPtr(unicharBuffer,
                                  kATSUFromTextBeginning,
                                  kATSUToTextEnd,
                                  stringLength,
                                  1,
                                  &runLengths,
                                  &atsuStyle,
                                  &atsuLayout);
  ATSUAttributeTag contextTag = kATSUCGContextTag;
  ByteCount byteSize = sizeof(CGContextRef);
  ATSUAttributeValuePtr contextATSUPtr = &cgContext;
  ATSUSetLayoutControls(atsuLayout, 1, &contextTag, &byteSize, &contextATSUPtr);
  ATSUTextMeasurement lineAscent, lineDescent;
  ATSUGetLineControl(atsuLayout,
                    kATSUFromTextBeginning,
                    kATSULineAscentTag,
                    sizeof(ATSUTextMeasurement),
                    &lineAscent,
                    &byteSize);
  ATSUGetLineControl(atsuLayout,
                    kATSUFromTextBeginning,
                    kATSULineDescentTag,
                    sizeof(ATSUTextMeasurement),
                    &lineDescent,
                    &byteSize);
  float lineHeight = FixedToFloat(lineAscent) + FixedToFloat(lineDescent);  
  ItemCount softBreakCount;
  ATSUBatchBreakLines(atsuLayout,
                      kATSUFromTextBeginning,
                      stringLength,
                      FloatToFixed(windowWidth - 10.0),
                      &softBreakCount);
  ATSUGetSoftLineBreaks(atsuLayout,
                        kATSUFromTextBeginning,
                        kATSUToTextEnd,
                        0, NULL, &softBreakCount);
  UniCharArrayOffset* softBreaks = (UniCharArrayOffset*)malloc(softBreakCount * sizeof(UniCharArrayOffset));
  ATSUGetSoftLineBreaks(atsuLayout,
                        kATSUFromTextBeginning,
                        kATSUToTextEnd,
                        softBreakCount, softBreaks, &softBreakCount);
  UniCharArrayOffset currentDrawOffset = kATSUFromTextBeginning;
  int i = 0;
  while (i < softBreakCount) {
    ATSUDrawText(atsuLayout, currentDrawOffset, softBreaks[i], FloatToFixed(5.0), FloatToFixed(windowHeight - 5.0 - (lineHeight * (i + 1.0))));
    currentDrawOffset = softBreaks[i];
    i++;
  }
  ATSUDrawText(atsuLayout, currentDrawOffset, kATSUToTextEnd, FloatToFixed(5.0), FloatToFixed(windowHeight - 5.0 - (lineHeight * (i + 1.0))));
  free(unicharBuffer);
  free(softBreaks);
  
  // restore the cgcontext gstate
  CGContextRestoreGState(cgContext);
}
Exemplo n.º 30
0
void RSTileRendererDrawTile(
                 CGContextRef c,
                 CGRect bounds,
                 uint8_t *data,
                 uint32_t dataSize,
                 uint32_t zoom,
                 RSTileRendererGraphicsSpace graphicsSpace)
{
    CGFloat width = (CGFloat)bounds.size.width;
    CGFloat height = (CGFloat)bounds.size.height;
    
    const CGFloat backgroundColor[4] = {0.5, 0.5, 0.5, 1};
    const CGFloat fillColors[8][4] = {
        {0, 0, 0, 0},
        {(210 / 255.0), (173 / 255.0), (104 / 255.0), 1}, // Building = 1,
        {(66 / 255.0), (66 / 255.0), (255 / 255.0), 1}, // HighwayMotorway = 2,
        {(255 / 255.0), (66 / 255.0), (66 / 255.0), 1}, // HighwayPrimary = 3,
        {(255 / 255.0), (155 / 255.0), (66 / 255.0), 1}, // HighwaySecondary = 4,
        {(255 / 255.0), (255 / 255.0), (66 / 255.0), 1}, // HighwayTertiary = 5,
        {(255 / 255.0), (255 / 255.0), (255 / 255.0), 1}, // HighwayResidential = 6,
        {(255 / 255.0), (255 / 255.0), (255 / 255.0), 1} // HighwayService = 7,
    };
    const CGFloat strokeColors[8][4] = {
        {0, 0, 0, 0},
        {(140 / 255.0), (93 / 255.0), (33 / 255.0), 1}, // Building = 1,
        {(44 / 255.0), (44 / 255.0), (200 / 255.0), 1}, // HighwayMotorway = 2,
        {(200 / 255.0), (44 / 255.0), (44 / 255.0), 1}, // HighwayPrimary = 3,
        {(200 / 255.0), (100 / 255.0), (44 / 255.0), 1}, // HighwaySecondary = 4,
        {(200 / 255.0), (200 / 255.0), (44 / 255.0), 1}, // HighwayTertiary = 5,
        {(200 / 255.0), (200 / 255.0), (200 / 255.0), 1}, // HighwayResidential = 6,
        {(200 / 255.0), (200 / 255.0), (200 / 255.0), 1} // HighwayService = 7,
    };
    
    CGContextSetFillColor(c, backgroundColor);
    CGContextFillRect(c, bounds);
    
    uint32_t pos = 0;
    
    uint32_t resolutionBits = 8;
    double intToFloat = width / (1 << resolutionBits);
    
    int32_t ix, iy;
    double x, y, firstX, firstY;
    
    while (pos < dataSize) {
        ix = 0;
        iy = 0;
        RSTiledataThingType thingType = (RSTiledataThingType)RSVarintRead(data, &pos);
        uint32_t numNodes = RSVarintRead(data, &pos);
        for (uint32_t i = 0; i < numNodes; i++) {
            ix += RSVarintSignedRead(data, &pos);
            iy += RSVarintSignedRead(data, &pos);
            x = intToFloat * ix;
            y = intToFloat * iy;
            if (graphicsSpace == RSTileRendererGraphicsSpaceQuadrantOne) {
                y = height - y;
            }
            if (i == 0) {
                firstX = x;
                firstY = y;
                CGContextMoveToPoint(c, x, y);
            } else {
                CGContextAddLineToPoint(c, x, y);
            }
        }
        CGContextSetFillColor(c, fillColors[thingType]);
        CGContextSetStrokeColor(c, strokeColors[thingType]);
        switch (thingType) {
            case RSTiledataBuilding:
                CGContextSetLineWidth(c, 4);
                break;
            case RSTiledataHighwayMotorway:
            case RSTiledataHighwayPrimary:
            case RSTiledataHighwaySecondary:
            case RSTiledataHighwayTertiary:
            case RSTiledataHighwayResidential:
            case RSTiledataHighwayService:
                CGContextSetLineWidth(c, 12);
                break;
        }
        if (RSTiledataThingTypeIsClosedWay(thingType)) {
            CGContextAddLineToPoint(c, firstX, firstY);
            CGContextDrawPath(c, kCGPathFillStroke);
        } else {
            CGContextStrokePath(c);
        }
    }
}