textland: attribute.py + colors.py => image.py

This large patch merges textland.attribute and textland.colors into
textland.image module. The rationale is that those are tightly coupled
concepts and they benefit from being in one module.

Now all text attributes can be expressed as an unsigned 16 bit number.
The TextAttribute class provides simple attribute access to foreground
and background color as well as text style. It also offers
packing/unpacking facilities.

All of the drawing methods simply use explicit packed attribute _or_ get
one from the DrawingContext.attributes.packed.

The {get,set,reset}_attribute methods are gone. Same for
set_{fg,bf}_color and reset_colors. Responsibility for that is now
entirely upon properties, attributes and methods of TextAttributes.

CursesDisplay now pre-computes a mapping table to translate from
TextLand to curses attribute bitmap. This is faster but might be further
improved if all brush manipulation painted the non-portable attributes
directly.

The TextImage.{get,put}() methods were optimized to multiply arguments
exactly once, for both text and attribute data

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
textland: allow color setup code to fail.

Currently this code fails for me, with TERM=xterm-256color so before it
gets fixed let's make it non-lethal.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
textland: clanup curses even if init fails

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
textland: fix curses on TERM=xterm-256colors

This patch (cherry picked from Sylvain's tree) stops using
curses.COLORS, which could be larger than 8, to initialize curses color
pairs. Instead we assume 8 colors as this allows us to use the
"standard" maximum of 64 color pairs.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
demos: add demo for DisplayContext.border()

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
demos: add demo for color grid

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>