This might be an entirely inappropriate question for StackOverFlow, but I don't know where else to turn, having read a bunch of online stuff about them*, I'm stuck on understanding what a context actually is. And why, how, where it exists.
Existential questions, I know, but I'm trying to grok these things.
/* YES, including the relevant Apple documentation, I've read much. ASSUME I'm stupid, and try to answer the following questions about what the Context is in a way that's simpler, easier to understand and perhaps even more prescient than the technically obfuscated guff and shortcut abbreviations of "you just need it" that's written by all others. If you can't do that, then feel free to be as derogatory and demeaning to me as you like. */
Contexts? How many of them there are, do they have names or other IDs, can they be sorted, transformed (rotation, position, scale, skew and opacity changes). Can they be layered, or are they somehow fixed to something else, and is that a children or parent kind of relationship? Can they be linked or nested???? etc etc.
I just don't get what they are, at all. Yes, before you ask, I do feel stupid for not instantly grokking something that everyone else seems to just "get" by referring to them as "contexts".
I see that I have to draw to these things, that nothing happens if I don't but that's about the end of the possible comprehension of what, why and how they came to be/are, and their need, potential, practical uses are all, for lack of a better term, invisible.
I'm completely flummoxed as to what these things are.
EDIT: Addition. Taking an example from the docs:
"A bitmap graphics context accepts a pointer to a memory buffer that contains storage space for the bitmap. When you paint into the bitmap graphics context, the buffer is updated. After you release the graphics context, you have a fully updated bitmap in the pixel format you specify."
Ok... release, and have, (where), what can be done with this? Where was it released to, and from?
Is this the most obtuse possible way of saying that a context is a "pretend" representation of the screen area available to draw into without directly drawing on the screen, and that this can then be mapped onto the screen? Is this blotting? Does this get massively memory intensive when doing full screen retina iPad graphics drawing?
If so... wouldn't it make sense that this context has a transform? That it can be rotated, scaled and repositioned relative to where it's going to be drawn? Can it therefore be duplicated and rotated?
If it's transformed, how are its contents scaled without aliasing issues. etc etc.
Does this mean there can be more than one context of the same type, and that they can be blended with different levels of opacity and different blend modes?
These documents only seem to partially explain, at best, what this thing is. It seems that it's right there, easy to grasp for everyone but me.
Is there anyone that can simply explain wtf it IS? Because even a vague effort at explaining what a context is might set me on the right path to instantly getting all the rest.
A CoreGraphics context represents drawing state. It contains things such as the current transformation matrix, the width and height of any lines to be drawn, the fill color, the stroke color, and a bunch of other information about how the computer should draw things. You can imagine it as some sort of C struct (though whether it is or not is irrelevant - it might be a C++ object, an Objective-C Object, or something else). It might look something like this:
struct CGBitmapContext {
void* bitmapData;
UInt32 rowBytes;
float currentTransform [4][4];
float lineWidth;
CGColorRef fillColor;
CGColorRef strokeColor;
// ... other graphics state needed for drawing ...
};
When you issue commands to draw, such as calling CGContextFillRect()
, it uses that state to decide how and where to draw. It will transform the rectangle you passed in using the current transformation matrix, then fill it in with the fill color.
But you don't deal directly with a CGContext
. Instead, you have a CGContextRef
, which is a pointer to the above struct (or object, or whatever it really is). So the context resides at the address pointed to by the CGContextRef
. When you call CGContextRelease()
, if the retain count for the context is 0, then the memory for the struct or object or whatever, is freed, probably using free()
, or delete
or -release
.
You can have as many contexts of any type as will fit in memory. They are all independent. If you are using bitmap contexts, freeing the context does not necessarily free the bitmap data. (I believe it depends on how you created the context.) You can use the data from various contexts to blend together, if you want. You could make CGImages out of them if you want, or upload them to the video card for use with OpenGL. You can do whatever you want with them.
In the days of MacOS 9, this was much more confusing because there were not contexts. You had to set the state every time you wanted to draw. And if you weren't careful, a previous function may have set the state to something odd. If you didn't notice the state had changed, and didn't change it back to what you wanted, the drawing would look bad. With a context, you can save the state and restore it using CGContextSaveGState()
and CGContextRestoreGState()
, and you can use different contexts for drawing to different views within the same window, for example. This greatly simplifies drawing.