      */
     protected function init (event :Event) :void
     {
-        // create and add the text field display
-        _field = new TextField();
-        addChild(_field);
-        _field.autoSize = TextFieldAutoSize.CENTER;
-        _field.text = " ";
-        _field.selectable = false;
+        // create the text field used to render characters
+        _charField = new TextField();
+        _charField.text = " ";
         _normalFormat = new TextFormat();
-        _normalFormat.color = _field.textColor = 0x00FF00;
+        _normalFormat.color = 0x00FF00;
         _reverseFormat = new TextFormat();
         _reverseFormat.color = 0x000000;
         _dimFormat = new TextFormat();
         _dimFormat.color = 0x008000;
         _normalFormat.font = _reverseFormat.font = _dimFormat.font = "_typewriter";
-        _field.setTextFormat(_normalFormat);
+        _charField.setTextFormat(_normalFormat);
 
         // get the size of a character and use it to determine the char width/height
-        var bounds :Rectangle = _field.getCharBoundaries(0);
-        _width = loaderInfo.width / bounds.width;
-        _height = loaderInfo.height / bounds.height;
-        var line :String = "", text :String = "";
-        for (var ii :int = 0; ii < _width; ii++) {
-            line += " ";
-        }
-        line += '\n';
-        for (ii = 0; ii < _height; ii++) {
-            text += line;
-        }
-        _field.text = text;
-        _field.setTextFormat(_normalFormat);
-        _field.x = (loaderInfo.width - _field.width) / 2;
-        _field.y = (loaderInfo.height - _field.height) / 2;
+        var bounds :Rectangle = _charField.getCharBoundaries(0);
+        _charWidth = bounds.width;
+        _charHeight = bounds.height;
+        _width = loaderInfo.width / _charWidth;
+        _height = loaderInfo.height / _charHeight;
+
+        // center the display
+        _x = (loaderInfo.width - (_charWidth * _width)) / 2;
+        _y = (loaderInfo.height - (_charHeight * _height)) / 2;
 
         // create and initialize the combined contents array
         _contents = new Array(_width * _height);
-        for (ii = 0; ii < _contents.length; ii++) {
+        for (var ii :int = 0; ii < _contents.length; ii++) {
             _contents[ii] = 0x20;
         }
 
-        // create the highlight bitmap data and highlight array
-        _highlightData = new BitmapData(bounds.width, bounds.height, false);
-        _highlights = new Array(_width * _height);
+        // create the bitmap data cache and bitmap array
+        _bitmapData = new Object();
+        _bitmaps = new Array(_width * _height);
 
         // add the context menu to change colors
         contextMenu = new ContextMenu();

                }
                _contents[idx] = nvalue;

                var tidx :int = yy*(_width + 1) + xx;
                var ochar :int = ovalue & 0xFFFF;
                var nchar :int = nvalue & 0xFFFF;
                var nrev :int = (nvalue & REVERSE_FLAG);
                var ndim :int = (nvalue & DIM_FLAG);
                if (ochar != nchar) {
                    _field.replaceText(tidx, tidx + 1, String.fromCharCode(nchar));
                    _field.setTextFormat(nrev == REVERSE_FLAG ? _reverseFormat :
                        (ndim == DIM_FLAG ? _dimFormat : _normalFormat), tidx, tidx + 1);
                }
                if ((ovalue & REVERSE_FLAG) != nrev) {
                    if (nrev == REVERSE_FLAG) {
                        // the char boundaries might not be valid yet, so we compute the location
                        // assuming the text is centered within the field
                        var highlight :Bitmap = new Bitmap(_highlightData);
                        addChildAt(_highlights[idx] = highlight, 0);
                        var cbounds :Rectangle = _field.getCharBoundaries(0);
                        highlight.x = _field.x + cbounds.width*xx +
                            (_field.width - cbounds.width*_width)/2;
                        highlight.y = _field.y + cbounds.height*yy +
                            (_field.height - cbounds.height*_height)/2;
                        if (ochar == nchar) {
                            _field.setTextFormat(_reverseFormat, tidx, tidx + 1);
                        }
                    } else {
                        removeChild(_highlights[idx]);
                        _highlights[idx] = null;
                        if (ochar == nchar) {
                            _field.setTextFormat(ndim == DIM_FLAG ? _dimFormat : _normalFormat,
                                tidx, tidx + 1);
                        }
                    }
                }
                if ((ovalue & DIM_FLAG) != ndim && nrev != REVERSE_FLAG && ochar == nchar) {
                    _field.setTextFormat(ndim == DIM_FLAG ? _dimFormat : _normalFormat,
                        tidx, tidx + 1);
                }
            }
        }
    }

    /**

        stage.focus = this;
        addEventListener(FocusEvent.FOCUS_OUT, function (event :FocusEvent) :void {
            addClientWindow(int.MAX_VALUE - 1, "Click to restore input focus.");

            // attempt to reacquire
            stage.focus = mousePad.parent;
        });
        addEventListener(FocusEvent.FOCUS_IN, function (event :FocusEvent) :void {
            removeWindow(int.MAX_VALUE - 1, false);
