diff --git a/haxework/gui/TextView.hx b/haxework/gui/TextView.hx index 63c6765..7a7008c 100755 --- a/haxework/gui/TextView.hx +++ b/haxework/gui/TextView.hx @@ -1,5 +1,7 @@ package haxework.gui; +import haxework.text.TextUtil; +import haxework.text.BitmapTextField; import flash.geom.Point; import flash.text.TextFieldAutoSize; import haxework.gui.core.HAlign; @@ -12,8 +14,6 @@ import flash.text.TextField; class TextView extends SpriteView implements ITextView { - private static var K_HEIGHT = 1.185; - public var textField(default, null):TextField; public var text(get, set):String; private var _text:String; @@ -34,6 +34,9 @@ class TextView extends SpriteView implements ITextView { public var bottomPadding(default, set):Float = 0.0; public var paddings(null, set):Float = 0.0; + public var shadow(default, set):Bool; + public var shadowColor(default, set):Int; + private var textFormat:TextFormat; private var _textWidth:Float; @@ -61,7 +64,8 @@ class TextView extends SpriteView implements ITextView { } private function buildTextField():TextField { - return new TextField(); + return new BitmapTextField(); + //return new TextField(); } private function set_fill(value:Bool):Bool { @@ -158,19 +162,9 @@ class TextView extends SpriteView implements ITextView { } private function updateTextSize():Void { - //ToDo: canvas.getContext("2d").measureText very slow - #if js - var s = 1; - var t = currentText(); - if (t != null) for (i in 0...t.length) { - if (t.charCodeAt(i) == 10) s++; - } - _textHeight = (textFormat.size + 2) * s * K_HEIGHT; - _textWidth = width; - #else - _textWidth = textField.textWidth; - _textHeight = textField.textHeight * K_HEIGHT; - #end + var size = TextUtil.getSize(textField); + _textWidth = size.x; + _textHeight = size.y; } override public function update():Void { @@ -184,10 +178,10 @@ class TextView extends SpriteView implements ITextView { if (contentSize && !Std.is(skin, ISize)) { #if html5 var h = _textHeight; - //var w = _textWidth; + var w = _textWidth; //if (h > textFormat.size * 1.5) h = h / 2; textField.height = h; - //textField.width = w; + textField.width = w; #end width = textField.width + leftPadding + rightPadding; height = textField.height + topPadding + bottomPadding; @@ -278,4 +272,23 @@ class TextView extends SpriteView implements ITextView { invalidate(); return value; } + + private function set_shadow(value) { + if (Std.is(textField, BitmapTextField)) { + cast(textField, BitmapTextField).shadow = value; + return cast(textField, BitmapTextField).shadow; + } else { + return value; + } + } + + private function set_shadowColor(value) { + if (Std.is(textField, BitmapTextField)) { + cast(textField, BitmapTextField).shadowColor = value; + cast(textField, BitmapTextField).shadow = true; + return cast(textField, BitmapTextField).shadowColor; + } else { + return value; + } + } } diff --git a/haxework/text/BitmapTextField.hx b/haxework/text/BitmapTextField.hx new file mode 100644 index 0000000..add1e1b --- /dev/null +++ b/haxework/text/BitmapTextField.hx @@ -0,0 +1,165 @@ +package haxework.text; + +import flash.text.TextFormat; +import flash.events.Event; +import flash.display.Bitmap; +import flash.geom.Matrix; +import flash.display.BitmapData; +import flash.text.TextField; + +class BitmapTextField extends TextField { + + public var shadow(default, set):Bool = false; + public var stroke(default, set):Bool = false; + public var shadowColor(default, set):Int = 0x000000; + public var shadowAlpha(default, set):Float = 0.6; + + private static var K_HEIGHT = 1.185; + + private var bitmap:Bitmap; + + private var _text:String; + private var _invalidated:Bool; + private var _invalidatedNext:Bool; + + public function new() { + super(); + bitmap = new Bitmap(); + bitmap.smoothing = true; + visible = false; + addEventListener(Event.ADDED, onAdded); + addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); + addEventListener(Event.REMOVED, onRemoved); + addEventListener(Event.ENTER_FRAME, onEnterFrame); + } + + private function set_shadow(value) { + if (shadow != value) { + shadow = value; + _invalidated = true; + } + return shadow; + } + + private function set_stroke(value) { + if (stroke != value) { + stroke = value; + _invalidated = true; + } + return stroke; + } + + private function set_shadowColor(value) { + if (shadowColor != value) { + shadowColor = value; + _invalidated = true; + } + return shadowColor; + } + + + private function set_shadowAlpha(value) { + if (shadowAlpha != value) { + shadowAlpha = value; + _invalidated = true; + } + return shadowAlpha; + } + + private function onAdded(_) { + parent.addChild(bitmap); + _invalidated = true; + } + + private function onAddedToStage(_) { + _invalidatedNext = true; + } + + private function onRemoved(_) { + if (bitmap.parent != null) { + bitmap.parent.removeChild(bitmap); + } + } + + private function onEnterFrame(_) { + if (_text != text) { + _text = text; + _invalidated = true; + } + if (_invalidated) { + redraw(); + } + if (_invalidatedNext) { + _invalidated = true; + _invalidatedNext = false; + } + } + + private function redraw() { + var size = TextUtil.getSize(this); + bitmap.bitmapData = draw(this, size.x, size.y, shadowColor, shadowAlpha, shadow, stroke); + bitmap.x = x; + bitmap.y = y; + _invalidated = false; + } + + public static function draw(textField:TextField, textWidth:Float, textHeight:Float, color:Int, alpha:Float, shadow:Bool, stroke:Bool):BitmapData { + textField.visible = true; + var bd = new BitmapData(Std.int(textWidth) + 6, Std.int(textHeight) + 6, true, 0x00000000); + + if (shadow || stroke) { + var baseTf = textField.getTextFormat(); + var tf = textField.getTextFormat(); + tf.color = color; + textField.setTextFormat(tf); + textField.alpha = alpha; + + //ToDo: matrix arrays + if (stroke) { + var m = new Matrix(); + m.translate(1, 2); + bd.draw(textField, m); + + var m = new Matrix(); + m.translate(2, 1); + bd.draw(textField, m); + + var m = new Matrix(); + m.translate(1, 0); + bd.draw(textField, m); + + var m = new Matrix(); + m.translate(0, 1); + bd.draw(textField, m); + } + + if (shadow) { + var m = new Matrix(); + m.translate(2, 3); + bd.draw(textField, m); + + var m = new Matrix(); + m.translate(3, 2); + bd.draw(textField, m); + + var m = new Matrix(); + m.translate(1, 0); + bd.draw(textField, m); + + var m = new Matrix(); + m.translate(0, 1); + bd.draw(textField, m); + } + + textField.alpha = 1.0; + textField.setTextFormat(baseTf); + } + + var m = new Matrix(); + m.translate(1, 1); + bd.draw(textField, m); + + textField.visible = false; + return bd; + } +} \ No newline at end of file diff --git a/haxework/text/TextUtil.hx b/haxework/text/TextUtil.hx new file mode 100644 index 0000000..aa9f08d --- /dev/null +++ b/haxework/text/TextUtil.hx @@ -0,0 +1,26 @@ +package haxework.text; + +import flash.geom.Point; +import flash.text.TextField; + +class TextUtil { + + private static var K_HEIGHT = 1.185; + + public static function getSize(textField:TextField):Point { + //ToDo: canvas.getContext("2d").measureText very slow + #if js + var s = 1; + var t = textField.text; + if (t != null) for (i in 0...t.length) { + if (t.charCodeAt(i) == 10) s++; + } + var _textHeight = (textField.getTextFormat().size + 2) * s * K_HEIGHT; + var _textWidth = textField.width; + #else + var _textWidth = textField.textWidth; + var _textHeight = textField.textHeight;// * K_HEIGHT; + #end + return new Point(_textWidth, _textHeight); + } +} \ No newline at end of file