{"id":1167,"url":"https://github.com/mpw/MPWDrawingContext","last_synced_at":"2025-07-30T20:32:33.801Z","repository":{"id":3554438,"uuid":"4615419","full_name":"mpw/MPWDrawingContext","owner":"mpw","description":"An Objective-C wrapper for CoreGraphics CGContext","archived":false,"fork":false,"pushed_at":"2023-05-17T12:32:03.000Z","size":58,"stargazers_count":101,"open_issues_count":1,"forks_count":9,"subscribers_count":15,"default_branch":"master","last_synced_at":"2024-08-14T14:06:24.751Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mpw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2012-06-10T13:53:32.000Z","updated_at":"2024-04-13T09:01:14.000Z","dependencies_parsed_at":"2024-01-26T21:06:39.841Z","dependency_job_id":"6ebe8968-1785-41fb-bbc1-af82f22a37f4","html_url":"https://github.com/mpw/MPWDrawingContext","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpw%2FMPWDrawingContext","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpw%2FMPWDrawingContext/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpw%2FMPWDrawingContext/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpw%2FMPWDrawingContext/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mpw","download_url":"https://codeload.github.com/mpw/MPWDrawingContext/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228187539,"owners_count":17882322,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-01-05T20:15:40.380Z","updated_at":"2024-12-04T20:31:02.273Z","avatar_url":"https://github.com/mpw.png","language":"Objective-C","funding_links":[],"categories":["Graphics","UI"],"sub_categories":["Getting Started","Other free courses","Linter"],"readme":"MPWDrawingContext, version 0.3\n==============================\n\nAn Objective-C wrapper around the CoreGraphics CGContextRef.  It includes\nthe MPWDrawingContext protocol and the MPWCGDrawingContext class that \nimplements that protocol by calling CoreGraphics CGContextRef functions.\n\nThe idea is for the context to be lightweight and straightforward enough\nthat including it is a no-brainer.\n\nThe MPWDrawingContext protocol itself has no dependencies on AppKit, \nUIKit or CoreGraphics.\n\nAlso includes is MPWView, a View class that subclasses UIView on iOS\nand NSView on OSX and renders using an MPWDrawingContext.  The sample\napplications for both OSX and iOS use the same view code.  MPWView\nalso allows drawing and event-handling code to be specified using\nblocks, so trivial views don't require a subclass.\n\nPhoneGeometry.h\nprovides NSPoint, NSSize and NSRect data-types on iOS by mapping them \nto their CoreGraphcis equivalents there.\n\nThe protocol aims to provide a \"fluent\" interface so that commands\ncan be chained.\n\nChangeLog\n---------\n\nVersion 0.3\n-----------\n\n- object-based single argument convenience methods (moveto,lineto,etc.)\n- shadows also block-based\n- linecap\n- drawOnContext: for blocks\n- some unit tests\n\nVersion 0.2\n-----------\n\n- actually made separate subclasses for PDF and Bitmap contexts\n- initial pattern support (only for colored patterns)\n- blocks everywhere, especially for re-usable images\n- use images or block-drawables directly as (pattern colors)\n\n\nVersion 0.1\n-----------\n\n- first release\n\nFuture Plans\n------------\n\n- expand text rendering to include most of CoreText (or equivalents)\n- more context types, for example rendering to CALayers, SVG and Canvas or OpenGL textures\n- image processing options, both stand-alone and as layered contexts\n\nCreation\n--------\n\nCreation methods are not part of the MPWDrawingContext protocol, but left to specific context classes.\n\nIf you already have a CGContextRef or want to use the current one:\n\n    +contextWithCGContext:(CGContextRef)c;\n    -initWithCGContext:(CGContextRef)newContext;\n    +currentContext;\n\n\nAlternatively you can create a new bitmap context with a current size.\n\n    +rgbBitmapContext:(NSSize)size;\n    +cmykBitmapContext:(NSSize)size;\n\n    -initBitmapContextWithSize:(NSSize)size colorSpace:(CGColorSpaceRef)colorspace;\n\n\n\nPaths\n-----\n\nThese are direct analogs to the corresponding CG functions.  Use like\nthis:   [[context nsrect:[self bounds]] fill];\n\nConstruction:\n\n    -(id \u003cMPWDrawingContext\u003e)moveto:(float)x :(float)y;\n    -(id \u003cMPWDrawingContext\u003e)lineto:(float)x :(float)y;\n    -(id \u003cMPWDrawingContext\u003e)curveto:(float)cp1x :(float)cp1y :(float)cp2x :(float)cp2y :(float)x :(float)y;\n    -(id \u003cMPWDrawingContext\u003e)closepath;\n    -(id \u003cMPWDrawingContext\u003e)nsrect:(NSRect)r;\n    -(id \u003cMPWDrawingContext\u003e)arcWithCenter:(NSPoint)center radius:(float)radius startDegrees:(float)start endDegrees:(float)stop  clockwise:(BOOL)clockwise;\n    -(id \u003cMPWDrawingContext\u003e)arcFromPoint:(NSPoint)p1 toPoint:(NSPoint)p2 radius:(float)radius;\n    -(id \u003cMPWDrawingContext\u003e)ellipseInRect:(NSRect)r;\n\n\nDrawing:\n\n    -(void)clip;\n    -(void)fill;\n    -(void)eofill;\n    -(void)eofillAndStroke;\n    -(void)fillAndStroke;\n    -(void)stroke;\n\nGradients:\n\n\n    -(id \u003cMPWDrawingContext\u003e)drawLinearGradientFrom:(NSPoint)startPoint to:(NSPoint)endPoint colors:(NSArray*)colors offsets:(NSArray*)offsets;\n    -(id \u003cMPWDrawingContext\u003e)drawRadialGradientFrom:(NSPoint)startPoint radius:(float)startRadius to:(NSPoint)endPoint radius:(float)endRadius colors:(NSArray*)colors offsets:(NSArray*)offsets;\n\n\n\nImages\n------\n\nThere is currently just a single method:\n\n    -(id \u003cMPWDrawingContext\u003e)drawImage:anImage;\n\nThe type of the image is purposely undefined.   MPWCGDrawingContext\nexpects that it either responds to (a) -CGImage to return a CGImageRef\n(as both UIImage and NSBitmapImageRep do) or (b) can render itself \nusing  -drawOnContext:(id \u003cMPWDrawingContext\u003e)aContext;\n\nImages are rendered at their natural size (sent -size).\n\n\nText\n----\n\n    -(id \u003cMPWDrawingContext\u003e)show:(id)someText; \n    -(id \u003cMPWDrawingContext\u003e)setTextPosition:(NSPoint)p;\n    -(id)fontWithName:(NSString*)name size:(float)size;\n    -(id \u003cMPWDrawingContext\u003e)setFont:aFont;\n\nText support is currently very rudimentary, sporting only the\nsingle -show: message.  It can be passed either an NSString\nor an NSAttributedString.   In the former case, drawing \nparameters will be taken from the current graphics state,\nin the latter they will be taken from the NSAttributedString\nitself.\n\nThe -setFont: message takes as its argument a font returned\nby -fontWithName:size:.   We purposely don't specify what\nexact class the font will be.\n\n\nGraphics State\n--------------\n\nSetting colors uses the same pattern as setting fonts: there are\ntwo basic color-setting messages:\n\n    -(id \u003cMPWDrawingContext\u003e)setFillColor:(id)aColor;\n    -(id \u003cMPWDrawingContext\u003e)setStrokeColor:(id)aColor;\n\nThese are complemented by a number of messages returning color objects,\nagain we don't exactly say what class they will be, just that they are\ncompatible with the color-setting methods.\n\n    -(id)colorRed:(float)r green:(float)g blue:(float)b alpha:(float)alpha;\n    -(id)colorCyan:(float)c magenta:(float)m yellow:(float)y black:(float)k alpha:(float)alpha;\n    -(id)colorGray:(float)gray alpha:(float)alpha;\n\nSo setting an RGB fill color works as follows:\n\n    [context setFillColor:[context colorRed:1.0 green:0 blue:0 alpha:0]];\n\nThere are also plural versions of these methods:\n\n    -(id)colorsRed:r green:g blue:b alpha:alpha;\n    -(id)colorsCyan:c magenta:m yellow:y black:k alpha:alpha;\n    -(id)colorsGray:gray alpha:alpha;\n\nThe key to these methods is that they allow array parameters and allow\narray an non-array parameters to be mixed.  For example:\n\n    [context colorRed:@[ 0.0 0.5 1.0 ] green:@0 blue:@0 alpha:@1];\n\nwill return 3 colors ranging from black to red.  This comes in\nhandy when specifying sets of related colors, for example\nfor gradients.\n\nCTM transformations:\n\n    -(id \u003cMPWDrawingContext\u003e)translate:(float)x :(float)y;\n    -(id \u003cMPWDrawingContext\u003e)scale:(float)x :(float)y;\n    -(id \u003cMPWDrawingContext\u003e)rotate:(float)degrees;\n\nSaving and restoring:\n\n    -(id \u003cMPWDrawingContext\u003e)gsave;\n    -(id \u003cMPWDrawingContext\u003e)grestore;\n\nMiscellaneous parameters:\n\n    -(id \u003cMPWDrawingContext\u003e)setdashpattern:array phase:(float)phase;\n    -(id \u003cMPWDrawingContext\u003e)setlinewidth:(float)width;\n    -(id \u003cMPWDrawingContext\u003e)setlinecapRound;\n    -(id \u003cMPWDrawingContext\u003e)setlinecapSquare;\n    -(id \u003cMPWDrawingContext\u003e)setlinecapButt;\n\n\n    -(id \u003cMPWDrawingContext\u003e)setAlpha:(float)alpha;\n    -(id \u003cMPWDrawingContext\u003e)setAntialias:(BOOL)doAntialiasing;\n    -(id \u003cMPWDrawingContext\u003e)setShadowOffset:(NSSize)offset blur:(float)blur color:(id)aColor;\n    -(id \u003cMPWDrawingContext\u003e)clearShadow;\n\nBlock-based:\n\n\n    -withShadowOffset:(NSSize)offset blur:(float)blur color:aColor draw:(DrawingBlock)commands;\n    -ingsave:(DrawingBlock)drawingCommands;\n    -(id)drawLater:(DrawingBlock)drawingCommands;\n    -layerWithSize:(NSSize)size content:(DrawingBlock)drawingCommands;\n    -laterWithSize:(NSSize)size content:(DrawingBlock)drawingCommands;\n    -page:(NSDictionary*)parameters content:(DrawingBlock)drawingCommands;\n\nConvenience:\n\n    -(id \u003cMPWDrawingContext\u003e)translate:(id)aPoint;\n    -(id \u003cMPWDrawingContext\u003e)scale:(id)aPointOrNumber;\n    -(id \u003cMPWDrawingContext\u003e)moveto:(id)aPoint;\n    -(id \u003cMPWDrawingContext\u003e)lineto:(id)aPoint;\n\nInfrequently Asked Questions\n----------------------------\n\n\n**Why would anyone need an Objective-C drawing context?**\n\nIn short, while CoreGraphics is an awesome graphics subsystem, not having OO features makes CGContext closed to extension by anyone but Apple, and somewhat unpleasant to use, IMHO.\n\nI explain a bit more about the motivation on my blog:   http://blog.metaobject.com/2012/06/pleasant-objective-c-drawing-context.html\n\n**Who cares about possible future expansion when that means there's lots of code to integrate with nasty dependencies?**\n\nIt used to be just 1 Class,  1 Protocol, 3 extra include files to equalize some of the differences between iOS and OSX (could probably be reduced), but it's admittedly a little more now:  Classes for different context types, for storing drawing commands\nand even (gasp!) an abstract class that captures some commonality between contexts.  Still totally worth it, though.\n\n1 additional class (MPWView) is purely optional\n\nIn the [github project](https://github.com/mpw/MPWDrawingContext), the code\nis actually integrated into an adapted version of Matt Gallagher's\n[IconApp](http://www.cocoawithlove.com/2011/01/advanced-drawing-using-appkit.html) (with some inspiration from Marcus\nCrafter's [iOS port](http://redartisan.com/2011/05/13/porting-iconapp-core-graphics) of same), so you have a working example right there.\n\n**But Cocoa has some fine drawing functionality with NSBezierPath, NSAffineTransform and friends**\n\nTrue, but MPWDrawingContext works identically on both iOS and Mac OS X.  In fact there's also an MPWView class that works on both iOS and OSX, which is used in the sample code mentioned above to create an iOS app using the same drawing code as the OS X app.\n\nI also prefer my graphics context to not be a hidden global parameter that's implicitly used by a bunch of other objects.\n\n**Who cares about OSX^H^H^H iOS?**\n\nBased on my unscientific experiments, MPWDrawingContext reduces the code I have to write for even one of the two platforms by about 20-30%.  Your mileage will almost certainly vary.\n\n**Who cares about less code?**\n\nWell, it\\s not just less code, it's more pleasant code as well:\n\n\t[[[[[context moveto:0 :0] lineto:100 :0] lineto:50 :50] closepath] stroke];\n\nvs.\n\n\tCGContextMoveToPoint( context, 0, 0 );\n\tCGContextAddLineToPoint( context, 100, 0);\n\tCGContextAddLineToPoint( context, 50, 50 );\n\tCGContextClosePath( context );\n\tCGContextFillPath( context );\n\nAnd\n\n        bitmap = [context bitmapWithSize:NSMakeSize( 595, 842 ) commands:^(Drawable){  ... }];\n\nvs.\n\t\n\tbitmapContext = CGBitmapContextCreate(NULL, size.width, size.height, 8, 0,\n                           CGColorSpaceCreateDeviceRGB(),   \n                           kCGImageAlphaPremultipliedLast)  | kCGBitmapByteOrderDefault );\n\t{ .... } \n        cgBitmap = CGBitmapContextCreateImage( bitmapContext );\n\tbitmap = [UIImage imageWithCGImage:cgBitmap];\n\tCGImageRelease(cgBitmap);\n\tCGContextRelease(bitmapContext);\n\n\n**No it's not!**\n\nOK :-)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmpw%2FMPWDrawingContext","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmpw%2FMPWDrawingContext","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmpw%2FMPWDrawingContext/lists"}