On OSX, we have the Cocoa APIs, which are at least somewhat OO, but on the other hand don't have a real
graphics context, only the stunted NSGraphcisContext
which doesn't actually allow you to do,
you know, graphics. Instead we have a whole bunch of "use-once" objects that are typically
instantiated, told to draw themselves to an implicit global drawing context and then discarded. This
seems exactly backwards, I would expect an explicit graphics context that I can use to draw using a
consolidated API.
That consolidated API is only available in the form of the CGContextRef
and its associated
functions, but alas that's a C API. So extremely long names, but without named parameters or useful
polymorphism. Despite the fact that a graphics context is a quintessential example of OO, only
Apple can create subclasses of a CGContext, and even then in only a sorta-kinda sort of way: CGBitmapContextCreate
returns
a CGContextRef
that silently knows how to do things that other
CGContextRef
s do not. Same for CGPDFContextCreate
.
On iOS, CoreGraphics is really your only choice, and double so if you want code that works on both iOS and OSX, but that means having to put up with the API, constantly converting between UI/NS objects and CoreGraphics and then there's the whole text mess.
Having been a great fan of algorithmic drawing every since my exposure to DisplayPostscript on the NeXT Cube, I found all of this sufficiently unsatisfactory that I decided to work on a solution, the first step of which is a lightweight drawing context that provides a reasonable Objective-C drawing API on top of CoreGraphics and works the same on OSX and iOS.
The result is on github: MPWDrawingContext, embedded in a version of Mark Gallagher's excellent IconApp AppKit drawing example. The same code is also used in the iOS target (a variant of Marcus Crafter's version of IconApp). I've also started using the context in a bunch of my own projects (that was the purpose after all) and so far it's made my graphics coding much more pleasant.
Another advantage, at least for me, is that bridging to scripting languages is automatic due to Objective-C's runtime information, whereas C functions have to have to be bridged separately and maintained, which is burdensome and doesn't necessarily get done.
At least one of Peter's problem with CGBitmapContextCreate
is also solved: creating a bitmap context is as easy as
[MPWCGDrawingContext rgbBitmapContext:NSMakeSize(595,842)]
Last not least: although it wasn't an explicit goal, there is also a pleasant reduction in code bulk.
Lines | Characters | Lines % | Characters % | |
---|---|---|---|---|
AppKit | 146 | 6593 | 67.12% | 76.69% |
CGContext | 134 | 7367 | 73.13% | 68.63% |
MPWDrawingContext | 98 | 5056 | - | - |