So does this mean the console must contain a buffer or something of the sort that stores the state of the screen so it knows what characters have been changed? What do you do when dealing with tiles, where the screen is now single pixels and can also have non-tile objects like text?
Yes, but I'm talking specifically about a console emulator. The Console doesn't even know what the resolution of the application is, so it can't represent pixels (unless you increase the logical resolution of the console in such a way that the canvas can only render each tile as a pixel-- but that violates the entire point of emulating a console).
How is text not tiled? Each character is a tile just as any sprite would be.
OK, but how simple should the drawing instructions the canvas uses be? Considering that a lot of low-level libraries like Curses and SDL do provide some features for text drawing -- wouldn't these be more efficient, or what (and on libraries without it, could be faked anyway)?
You will use those to draw characters into tiles.
Also, another question about panes: the area where the game world is drawn is a pane, no? But don't panes contain widgets? What kind of "widgets" does it have that allow it to represent the game world?
You could say that the Camera is a widget.
Here, consider the following example.
https://dl.dropboxusercontent.com/u/10791198/Rebrogue.swfAnd here are the drawing instructions for the above example. This is in HaXe, which is a language with a number of meta-programming features, so some of it may not make sense, but you can see the correlation between method calls and their effect in the above .swf.
var blueOnly = function(c:Int):Int
{
var t = c.toRGB();
t[0] = t[1] = 0;
return t.toHEX(); };
var gradient = function(x:Int,y:Int):Int return x*0x110011+y*0x001111;
var random = function(_,_,_):Int return Math.floor(Math.random() *0xffffff);
//colors may be an int or a function that takes up to 3 parameters- x, y and original color.
//this makes tinting and gradients a no-brainer
console.setDimension([16,6]);
console.clean();
console.begin_draw();
console.fill_rect([0,0],[16,6],random,random,"#");
console.fill_rect([0,0],[16,6],null,gradient); //null preserves the original information
console.plot_char([0,0],"X",0xffffff,0x0);
console.draw_text([0,1],"Blah blah blah",null);
console.fill_rect([0,0],[5,5],0xff00ff,0x0f0f0f);
console.fill_rect([12,3],[16,6],null,blueOnly);
console.fill_rect([12,0],[16,3],blueOnly);
console.end_draw();
The value of having a logical console is that we can perform additive drawing without sending more information to the renderer than we need to. Many of the tiles in the above example get drawn upon multiple times, but only one draw call is made for each modified tile (in end_draw). Some of these draws are a function of the original color or only modify colors without modifying text or vice versa. This provides support for transparency, tinting, lighting effects, and other cool things in a way that is concise and flexible.
This isn't getting into a WM, panes, or widgets as I haven't quite finished that up yet, but maybe seeing an example of how it could work will help you rationalize how it should look on the back-end.
Where would tiles fit in here?
In plot_char or fill_rect, if the string passed is length > 1, then the canvas can perform a library look-up to see if there is a corresponding sprite for that string.