Objective-C wrapper class for CGContext?

Has anyone created a wrapper class for the CGContext function group?

I created a simple Gradient class yesterday that encapsulates a subset of the CGGradient functions for easier memory management. It was pretty simple. But obviously there are a few more CGContext operations, and I'm not sure I want to invent a wheel there.

Essentially, I'm looking for things like ...

@interface CGContext : NSObject { CGContextRef context; } + (CGContext *) bitmapContextWithData:(void *)data width:(size_t)width height:(size_t)height bitsPerComponent:(size_t)bitsPerComponent bytesPerRow:(size_t)bytesPerRow colorspace:(CGColorSpaceRef)colorspace bitmapInfo:(CGBitmapInfo)bitmapInfo; - (void) saveGState; - (void) restoreGState; - (void) setBlendMode:(CGBlendMode)mode; - (void) addLineToPoint:(CGPoint)point; - (void) addLineToPointX:(CGFloat)x pointY:(CGFloat)y; - (void) drawImage:(CGImageRef)image rect:(CGRect)rect; - (void) concatCTM:(CGAffineTransform)transform; - (CGAffineTransform) getCTM; @end 

etc.

(I do 99% of my drawing into off-screen bitmaps, so I care about memory management in this case. If I always drew the current context of the graphical user interface, for example, the active screen, I would really find a wrapper class that would be very useful. )

+4
source share
1 answer

The UIBezierPath class, according to the docs, "is an Objective-C wrapper for path-related functions in the Core Graphics framework ... [it] is actually just a wrapper for the CGPathRef data type and drawing attributes associated with this path." The Drawing and Printing Guide for iOS contains a description of this class with some good diagrams. (See also his cousins NSBezierPath and CGPathRef .)

As for the wrapper for CGContext itself ... Update: ... after I wrote my own shell with a proof of concept, I discovered MPWDrawingContext from Marcel Weyer. It adds a bunch of useful methods and maintains the chain too!


I just hacked into a Ruby script to create a wrapper class for a CGContext called CGCanvas:

This is not very useful yet, but it proves the concept. I like to see parameter names, although the API is still cumbersomely functional.

Before:

 CGContextFillEllipseInRect(context, CGRectMake(30.0, 210.0, 60.0, 60.0)); CGContextAddArc(context, 150.0, 60.0, 30.0, 0.0, M_PI/2.0, false); CGContextStrokePath(context); CGContextAddArc(context, 150.0, 60.0, 30.0, 3.0*M_PI/2.0, M_PI, true); CGContextStrokePath(context); 

After:

 [canvas fillEllipseInRect:CGRectMake(30.0, 210.0, 60.0, 60.0)]; [canvas addArc_x:150.0 y:60.0 radius:30.0 startAngle:0.0 endAngle:M_PI/2.0 clockwise:false]; [canvas strokePath]; [canvas addArc_x:150.0 y:60.0 radius:30.0 startAngle:3.0*M_PI/2.0 endAngle:M_PI clockwise:true]; [canvas strokePath]; 

I did a few tricks to make the names understandable ... for example, function names with more than one parameter get the name of the first parameter added to the base name (if it doesn't end already). I used the underscore instead of the more Cocoa -like β€œc” to separate the base name from the parameter name, for example. moveToPoint_x:y: instead of moveToPointWithX:y: or moveToPoint:y:

If I continue to use this class, I will probably add more constructors and possibly some block methods ( as this guy did ), so you can start, build and move the path all at once. In addition, many names may be even shorter, and many methods may use some default values.

And perhaps a chain of methods! If only Objective-C weren’t so crazy. It should look like this:

 [[[[[[[[canvas setRGBStrokeColor_red: 1.0 green: 1.0 blue: 1.0 alpha: 1.0] setRGBFillColor_red:0.0 green:0.0 blue:1.0 alpha:1.0] setLineWidth:2.0] fillEllipseInRect:CGRectMake(30.0, 210.0, 60.0, 60.0)] addArc_x:150.0 y:60.0 radius:30.0 startAngle:0.0 endAngle:M_PI/2.0 clockwise:false] strokePath] addArc_x:150.0 y:60.0 radius:30.0 startAngle:3.0*M_PI/2.0 endAngle:M_PI clockwise:true] strokePath]; 

(which is not so terrible, I suppose ...)

+2
source

Source: https://habr.com/ru/post/1415482/


All Articles