void doStrokeWithCTM(CGContextRef context) { CGContextTranslateCTM(context, 150., 180.); CGContextSetLineWidth(context, 10); // Draw ellipse 1 with a uniform stroke. CGContextSaveGState(context); // Scale the CTM so the circular arc will be elliptical. CGContextScaleCTM(context, 2, 1); CGContextBeginPath(context); // Create an arc that is a circle. CGContextAddArc(context, 0., 0., 45., 0., 2*M_PI, 0); // Restore the context parameters prior to stroking the path. // CGContextRestoreGState does not affect the path in the context. CGContextRestoreGState(context); CGContextStrokePath(context); // *** was 0, -120 CGContextTranslateCTM(context, 220., 0.); // Draw ellipse 2 with non-uniform stroke. CGContextSaveGState(context); // Scale the CTM so the circular arc will be elliptical. CGContextScaleCTM(context, 2, 1); CGContextBeginPath(context); // Create an arc that is a circle. CGContextAddArc(context, 0., 0., 45., 0., 2*M_PI, 0); // Stroke the path with the scaled coordinate system in effect. CGContextStrokePath(context); CGContextRestoreGState(context); }
void MacDock::overlay(const QString& text) { if (text.isEmpty()) { overlayed = false; RestoreApplicationDockTileImage(); return; } // Create the context CGContextRef context = BeginCGContextForApplicationDockTile(); if (!overlayed) { overlayed = true; // Add some subtle drop down shadow // FIXME: Disabled because 10.2 doesn't support it //CGSize s = { 2.0, -4.0 }; //CGContextSetShadow(context,s,5.0); } // Draw a circle CGContextBeginPath(context); CGContextAddArc(context, 95.0, 95.0, 25.0, 0.0, 2 * M_PI, true); CGContextClosePath(context); CGContextSetRGBFillColor(context, 1, 0.0, 0.0, 1); CGContextFillPath(context); // Set the clipping path to the same circle CGContextBeginPath(context); CGContextAddArc(context, 95.0, 95.0, 25.0, 0.0, 2 * M_PI, true); CGContextClip(context); // Remove drop shadow // FIXME: Disabled because 10.2 doesn't support it //CGSize s = { 0.0, -0.0 }; //CGContextSetShadowWithColor(context, s, 0, NULL); // Select the appropriate font CGContextSelectFont(context,DOCK_FONT_NAME, DOCK_FONT_SIZE, kCGEncodingMacRoman); CGContextSetRGBFillColor(context, 1, 1, 1, 1); // Draw the text invisible CGPoint begin = CGContextGetTextPosition(context); CGContextSetTextDrawingMode(context, kCGTextInvisible); CGContextShowTextAtPoint(context, begin.x, begin.y, text.toStdString().c_str(), text.length()); CGPoint end = CGContextGetTextPosition(context); // Draw the text CGContextSetTextDrawingMode(context, kCGTextFill); CGContextShowTextAtPoint(context, 95 - (end.x - begin.x)/2, 95 - 8, text.toStdString().c_str(), text.length()); // Cleanup CGContextFlush(context); EndCGContextForApplicationDockTile(context); }
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"); }
static void Quartz_Circle(double x, double y, double r, R_GE_gcontext *gc, NewDevDesc *dd) { QuartzDesc *xd = (QuartzDesc*)dd->deviceSpecific; CGContextSaveGState( GetContext(xd) ); CGContextBeginPath( GetContext(xd) ); Quartz_SetLineProperties(gc, dd); CGContextAddArc( GetContext(xd), (float)x , (float)y, (float)r, 3.141592654 * 2.0, 0.0, 0); Quartz_SetFill( gc->fill, gc->gamma, dd); CGContextFillPath( GetContext(xd) ); Quartz_SetStroke( gc->col, gc->gamma, dd); CGContextAddArc( GetContext(xd), (float)x , (float)y, (float)r, 3.141592654 * 2.0, 0.0, 0); CGContextStrokePath( GetContext(xd) ); CGContextRestoreGState( GetContext(xd) ); }
bool PathCG::StrokeContainsPoint(const StrokeOptions &aStrokeOptions, const Point &aPoint, const Matrix &aTransform) const { Matrix inverse = aTransform; inverse.Invert(); Point transformedPoint = inverse*aPoint; // We could probably drop the input transform and just transform the point at the caller? CGPoint point = {transformedPoint.x, transformedPoint.y}; CGContextRef cg = ScratchContext(); CGContextSaveGState(cg); CGContextBeginPath(cg); CGContextAddPath(cg, mPath); SetStrokeOptions(cg, aStrokeOptions); CGContextReplacePathWithStrokedPath(cg); CGContextRestoreGState(cg); CGPathRef sPath = CGContextCopyPath(cg); bool inStroke = CGPathContainsPoint(sPath, nullptr, point, false); CGPathRelease(sPath); return inStroke; }
//----------------------------------------------------------------------------- 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); } }
//----------------------------------------------------------------------------- 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; }
void CFX_QuartzDeviceDriver::setPathToContext(const CFX_PathData* pathData) { FX_INT32 count = pathData->GetPointCount(); FX_PATHPOINT* points = pathData->GetPoints(); CGContextBeginPath(_context); for (FX_INT32 i = 0; i < count; i ++) { switch (points[i].m_Flag & FXPT_TYPE) { case FXPT_MOVETO: CGContextMoveToPoint(_context, points[i].m_PointX, points[i].m_PointY); break; case FXPT_LINETO: CGContextAddLineToPoint(_context, points[i].m_PointX, points[i].m_PointY); break; case FXPT_BEZIERTO: { CGContextAddCurveToPoint(_context, points[i].m_PointX, points[i].m_PointY, points[i + 1].m_PointX, points[i + 1].m_PointY, points[i + 2].m_PointX, points[i + 2].m_PointY); i += 2; } } if (points[i].m_Flag & FXPT_CLOSEFIGURE) { CGContextClosePath(_context); } } }
//----------------------------------------------------------------------------- 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); } }
//----------------------------------------------------------------------------- void CGDrawContext::drawRect (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); } CGContextBeginPath (context); CGContextAddRect (context, r); CGContextDrawPath (context, m); releaseCGContext (context); } }
//----------------------------------------------------------------------------- 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); } }
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); } }
void structGraphicsScreen :: v_fillArea (long numberOfPoints, double *xyDC) { #if cairo if (our d_cairoGraphicsContext == NULL) return; // cairo_new_path (our d_cairoGraphicsContext); // move_to() automatically creates a new path cairo_move_to (our d_cairoGraphicsContext, xyDC [0], xyDC [1]); for (long i = 1; i < numberOfPoints; i ++) cairo_line_to (our d_cairoGraphicsContext, xyDC [i + i], xyDC [i + i + 1]); cairo_close_path (our d_cairoGraphicsContext); cairo_fill (our d_cairoGraphicsContext); #elif win MY_BRUSH BeginPath (our d_gdiGraphicsContext); MoveToEx (our d_gdiGraphicsContext, xyDC [0], xyDC [1], NULL); for (long i = 1; i < numberOfPoints; i ++) LineTo (our d_gdiGraphicsContext, xyDC [i + i], xyDC [i + i + 1]); EndPath (our d_gdiGraphicsContext); FillPath (our d_gdiGraphicsContext); DEFAULT #elif mac GraphicsQuartz_initDraw (this); quartzPrepareFill (this); CGContextBeginPath (our d_macGraphicsContext); CGContextMoveToPoint (our d_macGraphicsContext, xyDC [0], xyDC [1]); for (long i = 1; i < numberOfPoints; i ++) { CGContextAddLineToPoint (our d_macGraphicsContext, xyDC [i + i], xyDC [i + i + 1]); } CGContextFillPath (our d_macGraphicsContext); GraphicsQuartz_exitDraw (this); #endif }
static void Quartz_Polyline(int n, double *x, double *y, R_GE_gcontext *gc, NewDevDesc *dd) { CGPoint *lines; int i; CGrafPtr savedPort, port; QuartzDesc *xd = (QuartzDesc*)dd->deviceSpecific; lines = (CGPoint *)malloc(sizeof(CGPoint)*n); if(lines == NULL) return; for (i = 0; i < n; i++) { lines[i].x = (float)x[i]; lines[i].y = (float)y[i]; } CGContextSaveGState( GetContext(xd) ); CGContextBeginPath( GetContext(xd) ); Quartz_SetLineProperties(gc, dd); CGContextAddLines( GetContext(xd), &lines[0], n ); Quartz_SetStroke( gc->col, gc->gamma, dd); CGContextStrokePath( GetContext(xd) ); CGContextRestoreGState( GetContext(xd) ); }
static void Quartz_Line(double x1, double y1, double x2, double y2, R_GE_gcontext *gc, NewDevDesc *dd) { QuartzDesc *xd = (QuartzDesc*)dd->deviceSpecific; CGPoint lines[ 2 ]; Rect rect; CGContextSaveGState( GetContext(xd) ); CGContextBeginPath( GetContext(xd) ); lines[0].x = (float)x1; lines[0].y = (float)y1; lines[1].x = (float)x2; lines[1].y = (float)y2; Quartz_SetLineProperties(gc, dd); CGContextAddLines( GetContext(xd), &lines[0], 2 ); Quartz_SetStroke( gc->col, gc->gamma, dd); CGContextStrokePath( GetContext(xd) ); CGContextRestoreGState( GetContext(xd) ); }
Rect PathCG::GetStrokedBounds(const StrokeOptions &aStrokeOptions, const Matrix &aTransform) const { // 10.7 has CGPathCreateCopyByStrokingPath which we could use // instead of this scratch context business CGContextRef cg = ScratchContext(); CGContextSaveGState(cg); CGContextBeginPath(cg); CGContextAddPath(cg, mPath); SetStrokeOptions(cg, aStrokeOptions); CGContextReplacePathWithStrokedPath(cg); Rect bounds = CGRectToRect(CGContextGetPathBoundingBox(cg)); CGContextRestoreGState(cg); if (!bounds.IsFinite()) { return Rect(); } return aTransform.TransformBounds(bounds); }
void addOvalToPath(CGContextRef context, CGRect r) { CGAffineTransform matrix; // Save the context's state because we are going to transform and scale it CGContextSaveGState(context); // Create a transform to scale the context so that a radius of 1 // is equal to the bounds of the rectangle, and transform the origin // of the context to the center of the bounding rectangle. The // center of the bounding rectangle will now be the center of // the oval. matrix = CGAffineTransformMake((r.size.width)/2, 0, 0, (r.size.height)/2, r.origin.x + (r.size.width)/2, r.origin.y + (r.size.height)/2); // Apply the transform to the context CGContextConcatCTM(context, matrix); // Signal the start of a path CGContextBeginPath(context); // Add a circle to the path. After the circle is transformed by the // context's transformation matrix, it will become an oval lying // just inside the bounding rectangle. CGContextAddArc(context, 0, 0, 1, 0, 2*pi, true); // Restore the context's state. This removes the translation and scaling but leaves // the path, since the path is not part of the graphics state. CGContextRestoreGState(context); }
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); }
void GraphicsContext::fillPath(const Path& path) { if (paintingDisabled()) return; CGContextRef context = platformContext(); CGContextBeginPath(context); CGContextAddPath(context, path.platformPath()); if (m_state.fillGradient) { CGContextSaveGState(context); if (fillRule() == RULE_EVENODD) CGContextEOClip(context); else CGContextClip(context); CGContextConcatCTM(context, m_state.fillGradient->gradientSpaceTransform()); m_state.fillGradient->paint(this); CGContextRestoreGState(context); return; } if (m_state.fillPattern) applyFillPattern(); fillPathWithFillRule(context, fillRule()); }
void GraphicsContext::drawFocusRing(const Color& color) { if (paintingDisabled()) return; float radius = (focusRingWidth() - 1) / 2.0f; int offset = radius + focusRingOffset(); CGColorRef colorRef = color.isValid() ? cgColor(color) : 0; CGMutablePathRef focusRingPath = CGPathCreateMutable(); const Vector<IntRect>& rects = focusRingRects(); unsigned rectCount = rects.size(); for (unsigned i = 0; i < rectCount; i++) CGPathAddRect(focusRingPath, 0, CGRectInset(rects[i], -offset, -offset)); CGContextRef context = platformContext(); CGContextSaveGState(context); CGContextBeginPath(context); CGContextAddPath(context, focusRingPath); wkDrawFocusRing(context, colorRef, radius); CGColorRelease(colorRef); CGPathRelease(focusRingPath); CGContextRestoreGState(context); }
void drawRoundedRect(CGContextRef context, int x, int y){ struct CGRect cgRect; struct CGPoint cgPoint; cgRect.size.width = 640; cgRect.size.height = y+30; cgPoint.x = 0; cgPoint.y = 5; cgRect.origin = cgPoint; //printf("Drawing %f, %f, %f, %f", cgPoint.x, cgPoint.y, cgRect.size.width, cgRect.size.height); CGContextBeginPath(context); float ovalWidth = 10; float ovalHeight = 10; float fw, fh; // If the width or height of the corner oval is zero, then it reduces to a right angle, // so instead of a rounded rectangle we have an ordinary one. if (ovalWidth == 0 || ovalHeight == 0) { CGContextAddRect(context, cgRect); return; } // Save the context's state so that the translate and scale can be undone with a call // to CGContextRestoreGState. CGContextSaveGState(context); // Translate the origin of the contex to the lower left corner of the rectangle. CGContextTranslateCTM(context, CGRectGetMinX(cgRect), CGRectGetMinY(cgRect)); //Normalize the scale of the context so that the width and height of the arcs are 1.0 CGContextScaleCTM(context, ovalWidth, ovalHeight); // Calculate the width and height of the rectangle in the new coordinate system. fw = CGRectGetWidth(cgRect) / ovalWidth; fh = CGRectGetHeight(cgRect) / ovalHeight; // CGContextAddArcToPoint adds an arc of a circle to the context's path (creating the rounded // corners). It also adds a line from the path's last point to the begining of the arc, making // the sides of the rectangle. CGContextMoveToPoint(context, fw, fh/2); // Start at lower right corner CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); // Top right corner CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); // Top left corner CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); // Lower left corner CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); // Back to lower right // Close the path CGContextClosePath(context); CGContextSetRGBFillColor (context, 1, 1, 1, 0.7); CGContextFillPath(context); CGContextRestoreGState(context); }
void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool shouldAntialias) { if (paintingDisabled()) return; if (npoints <= 1) return; CGContextRef context = platformContext(); CGContextSaveGState(context); CGContextSetShouldAntialias(context, shouldAntialias); CGContextBeginPath(context); CGContextMoveToPoint(context, points[0].x(), points[0].y()); for (size_t i = 1; i < npoints; i++) CGContextAddLineToPoint(context, points[i].x(), points[i].y()); CGContextClosePath(context); if (fillColor().alpha()) CGContextEOFillPath(context); if (strokeStyle() != NoStroke) CGContextStrokePath(context); CGContextRestoreGState(context); }
// 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); }
FloatRect strokeBoundingBox(const Path& path, RenderStyle* style, const RenderObject* object) { // the bbox might grow if the path is stroked. // and CGPathGetBoundingBox doesn't support that, so we'll have // to make an alternative call... // FIXME: since this is mainly used to decide what to repaint, // perhaps it would be sufficient to just outset the fill bbox by // the stroke width - that should be way cheaper and simpler than // what we do here. CGPathRef cgPath = path.platformPath(); CGContextRef context = scratchContext(); CGContextSaveGState(context); CGContextBeginPath(context); CGContextAddPath(context, cgPath); GraphicsContext gc(context); applyStrokeStyleToContext(&gc, style, object); CGContextReplacePathWithStrokedPath(context); if (CGContextIsPathEmpty(context)) { // CGContextReplacePathWithStrokedPath seems to fail to create a path sometimes, this is not well understood. // returning here prevents CG from logging to the console from CGContextGetPathBoundingBox CGContextRestoreGState(context); return FloatRect(); } CGRect box = CGContextGetPathBoundingBox(context); CGContextRestoreGState(context); return FloatRect(box); }
void doPixelAlignedFillAndStroke(CGContextRef context) { CGPoint p1 = CGPointMake(16.7, 17.8); CGPoint p2 = CGPointMake(116.7, 17.8); CGRect r = CGRectMake(16.7, 20.8, 100.6, 100.6); CGSize s; CGContextSetLineWidth(context, 2); CGContextSetRGBFillColor(context, 1., 0., 0., 1.); CGContextSetRGBStrokeColor(context, 1., 0., 0., 1.); // Unaligned drawing. CGContextBeginPath(context); CGContextMoveToPoint(context, p1.x, p1.y); CGContextAddLineToPoint(context, p2.x, p2.y); CGContextStrokePath(context); CGContextFillRect(context, r); // Translate to the right before drawing along // aligned coordinates. CGContextTranslateCTM(context, 106, 0); // Aligned drawing. // Compute the length of the line in user space. s = CGSizeMake(p2.x - p1.x, p2.y - p1.y); CGContextBeginPath(context); // Align the starting point to a device // pixel boundary. p1 = alignPointToUserSpace(context, p1); // Establish the starting point of the line. CGContextMoveToPoint(context, p1.x, p1.y); // Compute the line length as an integer // number of device pixels. s = alignSizeToUserSpace(context, s); CGContextAddLineToPoint(context, p1.x + s.width, p1.y + s.height); CGContextStrokePath(context); // Compute a rect that is aligned to device // space with a width that is an integer // number of device pixels. r = alignRectToUserSpace(context, r); CGContextFillRect(context, r); }
//----------------------------------------------------------------------------- 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 JBGFillTriangle(CGContextRef ctx, CGPoint point_a, CGPoint point_b, CGPoint point_c, CGColorRef color) { CGContextBeginPath(ctx); CGPoint points[] = {point_a, point_b, point_c}; CGContextAddLines(ctx, points, sizeof(points) / sizeof(points[0])); CGContextClosePath(ctx); CGContextSetFillColorWithColor(ctx, color); CGContextFillPath(ctx); }
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 GraphicsContext::clipOut(const Path& path) { if (paintingDisabled()) return; CGContextBeginPath(platformContext()); CGContextAddRect(platformContext(), CGContextGetClipBoundingBox(platformContext())); CGContextAddPath(platformContext(), path.platformPath()); CGContextEOClip(platformContext()); }
void GraphicsContext::clipOut(const IntRect& rect) { if (paintingDisabled()) return; CGRect rects[2] = { CGContextGetClipBoundingBox(platformContext()), rect }; CGContextBeginPath(platformContext()); CGContextAddRects(platformContext(), rects, 2); CGContextEOClip(platformContext()); }