Explorar o código

Merge pull request #521 from Yanrishatum/feature_float_tile

Change `h2d.Tile` to use Float.
trethaller %!s(int64=6) %!d(string=hai) anos
pai
achega
ada42608e9

+ 1 - 1
h2d/CdbLevel.hx

@@ -357,7 +357,7 @@ class CdbLevel extends Layers {
 				var curY = -1;
 				var curY = -1;
 				var content = null;
 				var content = null;
 				for( o in objects ) {
 				for( o in objects ) {
-					var baseY = o.y + o.obj.tile.height;
+					var baseY = o.y + Std.int(o.obj.tile.height);
 					if( baseY != curY ) {
 					if( baseY != curY ) {
 						curY = baseY;
 						curY = baseY;
 						content = byY[baseY];
 						content = byY[baseY];

+ 1 - 1
h2d/Console.hx

@@ -38,7 +38,7 @@ class Console #if !macro extends h2d.Object #end {
 
 
 	public function new(font:h2d.Font,?parent) {
 	public function new(font:h2d.Font,?parent) {
 		super(parent);
 		super(parent);
-		height = font.lineHeight + 2;
+		height = Math.ceil(font.lineHeight) + 2;
 		logTxt = new h2d.HtmlText(font, this);
 		logTxt = new h2d.HtmlText(font, this);
 		logTxt.x = 2;
 		logTxt.x = 2;
 		logTxt.dropShadow = { dx : 0, dy : 1, color : 0, alpha : 0.5 };
 		logTxt.dropShadow = { dx : 0, dy : 1, color : 0, alpha : 0.5 };

+ 31 - 15
h2d/Font.hx

@@ -2,7 +2,7 @@ package h2d;
 
 
 class Kerning {
 class Kerning {
 	public var prevChar : Int;
 	public var prevChar : Int;
-	public var offset : Int;
+	public var offset : Float;
 	public var next : Null<Kerning>;
 	public var next : Null<Kerning>;
 	public function new(c, o) {
 	public function new(c, o) {
 		this.prevChar = c;
 		this.prevChar = c;
@@ -13,7 +13,7 @@ class Kerning {
 class FontChar {
 class FontChar {
 
 
 	public var t : h2d.Tile;
 	public var t : h2d.Tile;
-	public var width : Int;
+	public var width : Float;
 	var kerning : Null<Kerning>;
 	var kerning : Null<Kerning>;
 
 
 	public function new(t,w) {
 	public function new(t,w) {
@@ -39,7 +39,18 @@ class FontChar {
 
 
 	public function clone() {
 	public function clone() {
 		var c = new FontChar(t.clone(), width);
 		var c = new FontChar(t.clone(), width);
-		c.kerning = kerning;
+		// Clone entire kerning tree in case Font got resized.
+		var k = kerning;
+		if ( k != null ) {
+			var kc = new Kerning(k.prevChar, k.offset);
+			c.kerning = kc;
+			k = k.next;
+			while ( k != null ) {
+				var kn = new Kerning(k.prevChar, k.offset);
+				kc = kc.next = kn;
+				k = k.next;
+			}
+		}
 		return c;
 		return c;
 	}
 	}
 
 
@@ -69,8 +80,8 @@ class Font {
 
 
 	public var name(default, null) : String;
 	public var name(default, null) : String;
 	public var size(default, null) : Int;
 	public var size(default, null) : Int;
-	public var baseLine(default, null) : Int;
-	public var lineHeight(default, null) : Int;
+	public var baseLine(default, null) : Float;
+	public var lineHeight(default, null) : Float;
 	public var tile(default,null) : h2d.Tile;
 	public var tile(default,null) : h2d.Tile;
 	public var tilePath(default,null) : String;
 	public var tilePath(default,null) : String;
 	public var type : FontType;
 	public var type : FontType;
@@ -79,10 +90,10 @@ class Font {
 	var nullChar : FontChar;
 	var nullChar : FontChar;
 	var defaultChar : FontChar;
 	var defaultChar : FontChar;
 	var initSize:Int;
 	var initSize:Int;
-	var offsetX:Int = 0;
-	var offsetY:Int = 0;
+	var offsetX:Float = 0;
+	var offsetY:Float = 0;
 
 
-	function new(name,size,?type) {
+	function new(name : String, size : Int, ?type : FontType) {
 		this.name = name;
 		this.name = name;
 		this.size = size;
 		this.size = size;
 		this.initSize = size;
 		this.initSize = size;
@@ -107,7 +118,7 @@ class Font {
 		return c;
 		return c;
 	}
 	}
 
 
-	public function setOffset(x,y) {
+	public function setOffset( x : Float, y :Float ) {
 		var dx = x - offsetX;
 		var dx = x - offsetX;
 		var dy = y - offsetY;
 		var dy = y - offsetY;
 		if( dx == 0 && dy == 0 ) return;
 		if( dx == 0 && dy == 0 ) return;
@@ -142,13 +153,18 @@ class Font {
 	public function resizeTo( size : Int ) {
 	public function resizeTo( size : Int ) {
 		var ratio = size / initSize;
 		var ratio = size / initSize;
 		for( c in glyphs ) {
 		for( c in glyphs ) {
-			c.width = Std.int(c.width * ratio);
-			c.t.scaleToSize(Std.int(c.t.width * ratio), Std.int(c.t.height * ratio));
-			c.t.dx = Std.int(c.t.dx * ratio);
-			c.t.dy = Std.int(c.t.dy * ratio);
+			c.width *= ratio;
+			c.t.scaleToSize(c.t.width * ratio, c.t.height * ratio);
+			c.t.dx *= ratio;
+			c.t.dy *= ratio;
+			var k = @:privateAccess c.kerning;
+			while ( k != null ) {
+				k.offset *= ratio;
+				k = k.next;
+			}
 		}
 		}
-		lineHeight = Std.int(lineHeight * ratio);
-		baseLine = Std.int(baseLine * ratio);
+		lineHeight = lineHeight * ratio;
+		baseLine = baseLine * ratio;
 		this.size = size;
 		this.size = size;
 	}
 	}
 
 

+ 15 - 15
h2d/HtmlText.hx

@@ -7,10 +7,10 @@ class HtmlText extends Text {
 	public var condenseWhite(default,set) : Bool = true;
 	public var condenseWhite(default,set) : Bool = true;
 
 
 	var elements : Array<Object> = [];
 	var elements : Array<Object> = [];
-	var xPos : Int;
-	var yPos : Int;
-	var xMax : Int;
-	var xMin : Int;
+	var xPos : Float;
+	var yPos : Float;
+	var xMax : Float;
+	var xMin : Float;
 	var sizePos : Int;
 	var sizePos : Int;
 	var dropMatrix : h3d.shader.ColorMatrix;
 	var dropMatrix : h3d.shader.ColorMatrix;
 	var prevChar : Int;
 	var prevChar : Int;
@@ -63,7 +63,7 @@ class HtmlText extends Text {
 			case Center, Right, MultilineCenter, MultilineRight:
 			case Center, Right, MultilineCenter, MultilineRight:
 				lines = [];
 				lines = [];
 				initGlyphs(text, false, false, lines);
 				initGlyphs(text, false, false, lines);
-				var max = if( align == MultilineCenter || align == MultilineRight ) calcWidth else realMaxWidth < 0 ? 0 : Std.int(realMaxWidth);
+				var max = if( align == MultilineCenter || align == MultilineRight ) hxd.Math.ceil(calcWidth) else realMaxWidth < 0 ? 0 : hxd.Math.ceil(realMaxWidth);
 				var k = align == Center || align == MultilineCenter ? 1 : 0;
 				var k = align == Center || align == MultilineCenter ? 1 : 0;
 				for( i in 0...lines.length )
 				for( i in 0...lines.length )
 					lines[i] = (max - lines[i]) >> k;
 					lines[i] = (max - lines[i]) >> k;
@@ -79,7 +79,7 @@ class HtmlText extends Text {
 
 
 		var doc = try Xml.parse(text) catch( e : Dynamic ) throw "Could not parse " + text + " (" + e +")";
 		var doc = try Xml.parse(text) catch( e : Dynamic ) throw "Could not parse " + text + " (" + e +")";
 
 
-		var sizes = [];
+		var sizes = new Array<Float>();
 		prevChar = -1;
 		prevChar = -1;
 		newLine = true;
 		newLine = true;
 		for( e in doc )
 		for( e in doc )
@@ -90,7 +90,7 @@ class HtmlText extends Text {
 		for( e in doc )
 		for( e in doc )
 			addNode(e, font, rebuild, handleAlign, sizes, lines);
 			addNode(e, font, rebuild, handleAlign, sizes, lines);
 
 
-		if (!handleAlign && !rebuild && lines != null) lines.push(xPos);
+		if (!handleAlign && !rebuild && lines != null) lines.push(hxd.Math.ceil(xPos));
 		if( xPos > xMax ) xMax = xPos;
 		if( xPos > xMax ) xMax = xPos;
 
 
 		var y = yPos;
 		var y = yPos;
@@ -101,9 +101,9 @@ class HtmlText extends Text {
 		calcDone = true;
 		calcDone = true;
 	}
 	}
 
 
-	function buildSizes( e : Xml, font : Font, sizes : Array<Int> ) {
+	function buildSizes( e : Xml, font : Font, sizes : Array<Float> ) {
 		if( e.nodeType == Xml.Element ) {
 		if( e.nodeType == Xml.Element ) {
-			var len = 0;
+			var len = 0.;
 			var nodeName = e.nodeName.toLowerCase();
 			var nodeName = e.nodeName.toLowerCase();
 			switch( nodeName ) {
 			switch( nodeName ) {
 			case "p":
 			case "p":
@@ -141,7 +141,7 @@ class HtmlText extends Text {
 		} else {
 		} else {
 			newLine = false;
 			newLine = false;
 			var text = htmlToText(e.nodeValue);
 			var text = htmlToText(e.nodeValue);
-			var xp = 0;
+			var xp = 0.;
 			for( i in 0...text.length ) {
 			for( i in 0...text.length ) {
 				var cc = text.charCodeAt(i);
 				var cc = text.charCodeAt(i);
 				var fc = font.getChar(cc);
 				var fc = font.getChar(cc);
@@ -165,8 +165,8 @@ class HtmlText extends Text {
 		return t;
 		return t;
 	}
 	}
 
 
-	function remainingSize( sizes : Array<Int> ) {
-		var size = 0;
+	function remainingSize( sizes : Array<Float> ) {
+		var size = 0.;
 		for( i in sizePos...sizes.length ) {
 		for( i in sizePos...sizes.length ) {
 			var s = sizes[i];
 			var s = sizes[i];
 			if( s < 0 ) {
 			if( s < 0 ) {
@@ -178,7 +178,7 @@ class HtmlText extends Text {
 		return size;
 		return size;
 	}
 	}
 
 
-	function addNode( e : Xml, font : Font, rebuild : Bool, handleAlign:Bool, sizes : Array<Int>, ?lines : Array<Int> = null ) {
+	function addNode( e : Xml, font : Font, rebuild : Bool, handleAlign:Bool, sizes : Array<Float>, ?lines : Array<Int> = null ) {
 		sizePos++;
 		sizePos++;
 		var calcLines = !handleAlign && !rebuild && lines != null;
 		var calcLines = !handleAlign && !rebuild && lines != null;
 		var align = handleAlign ? textAlign : Left;
 		var align = handleAlign ? textAlign : Left;
@@ -187,7 +187,7 @@ class HtmlText extends Text {
 			function makeLineBreak()
 			function makeLineBreak()
 			{
 			{
 				if( xPos > xMax ) xMax = xPos;
 				if( xPos > xMax ) xMax = xPos;
-				if( calcLines ) lines.push(xPos);
+				if( calcLines ) lines.push(hxd.Math.ceil(xPos));
 				switch( align ) {
 				switch( align ) {
 					case Left:
 					case Left:
 						xPos = 0;
 						xPos = 0;
@@ -301,7 +301,7 @@ class HtmlText extends Text {
 				var cc = t.charCodeAt(i);
 				var cc = t.charCodeAt(i);
 				if( cc == "\n".code ) {
 				if( cc == "\n".code ) {
 					if( xPos > xMax ) xMax = xPos;
 					if( xPos > xMax ) xMax = xPos;
-					if( calcLines ) lines.push(xPos);
+					if( calcLines ) lines.push(hxd.Math.ceil(xPos));
 					switch( align ) {
 					switch( align ) {
 						case Left:
 						case Left:
 							xPos = 0;
 							xPos = 0;

+ 2 - 2
h2d/KeyFrames.hx

@@ -187,8 +187,8 @@ class KeyFrames extends Mask {
 		case AnchorPoint:
 		case AnchorPoint:
 			var bmp = Std.instance(l.spr, h2d.Bitmap);
 			var bmp = Std.instance(l.spr, h2d.Bitmap);
 			if( bmp != null ) {
 			if( bmp != null ) {
-				bmp.tile.dx = -Std.int(calcValue(0));
-				bmp.tile.dy = -Std.int(calcValue(1));
+				bmp.tile.dx = -calcValue(0);
+				bmp.tile.dy = -calcValue(1);
 			}
 			}
 		case XPosition:
 		case XPosition:
 			l.spr.x = calcValue(0);
 			l.spr.x = calcValue(0);

+ 1 - 1
h2d/RenderContext.hx

@@ -348,7 +348,7 @@ class RenderContext extends h3d.impl.RenderContext {
 			if( cx < -tr || cy < -tr || cx - tr > curWidth || cy - tr > curHeight ) return false;
 			if( cx < -tr || cy < -tr || cx - tr > curWidth || cy - tr > curHeight ) return false;
 		} else {
 		} else {
 			var xMin = 1e20, yMin = 1e20, xMax = -1e20, yMax = -1e20;
 			var xMin = 1e20, yMin = 1e20, xMax = -1e20, yMax = -1e20;
-			inline function calc(x:Int, y:Int) {
+			inline function calc(x:Float, y:Float) {
 				var px = (x + tile.dx) * matA + (y + tile.dy) * matC;
 				var px = (x + tile.dx) * matA + (y + tile.dy) * matC;
 				var py = (x + tile.dx) * matB + (y + tile.dy) * matD;
 				var py = (x + tile.dx) * matB + (y + tile.dy) * matD;
 				if( px < xMin ) xMin = px;
 				if( px < xMin ) xMin = px;

+ 2 - 2
h2d/ScaleGrid.hx

@@ -6,8 +6,8 @@ class ScaleGrid extends h2d.TileGroup {
 	public var borderWidth(default,set) : Int;
 	public var borderWidth(default,set) : Int;
 	public var borderHeight(default,set) : Int;
 	public var borderHeight(default,set) : Int;
 
 
-	public var width(default,set) : Int;
-	public var height(default,set) : Int;
+	public var width(default,set) : Float;
+	public var height(default,set) : Float;
 
 
 	public var tileBorders(default, set) : Bool;
 	public var tileBorders(default, set) : Bool;
 
 

+ 1 - 1
h2d/Scene.hx

@@ -511,7 +511,7 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 			target = new Tile(tex,0, 0, width, height);
 			target = new Tile(tex,0, 0, width, height);
 		}
 		}
 		engine.begin();
 		engine.begin();
-		engine.setRenderZone(target.x, target.y, target.width, target.height);
+		engine.setRenderZone(Std.int(target.x), Std.int(target.y), hxd.Math.ceil(target.width), hxd.Math.ceil(target.height));
 
 
 		var tex = target.getTexture();
 		var tex = target.getTexture();
 		engine.pushTarget(tex);
 		engine.pushTarget(tex);

+ 17 - 17
h2d/Text.hx

@@ -16,20 +16,20 @@ class Text extends Drawable {
 	public var maxWidth(default, set) : Null<Float>;
 	public var maxWidth(default, set) : Null<Float>;
 	public var dropShadow : { dx : Float, dy : Float, color : Int, alpha : Float };
 	public var dropShadow : { dx : Float, dy : Float, color : Int, alpha : Float };
 
 
-	public var textWidth(get, null) : Int;
-	public var textHeight(get, null) : Int;
+	public var textWidth(get, null) : Float;
+	public var textHeight(get, null) : Float;
 	public var textAlign(default, set) : Align;
 	public var textAlign(default, set) : Align;
-	public var letterSpacing(default, set) : Int;
-	public var lineSpacing(default,set) : Int;
+	public var letterSpacing(default, set) : Float;
+	public var lineSpacing(default,set) : Float;
 
 
 	var glyphs : TileGroup;
 	var glyphs : TileGroup;
 
 
 	var calcDone:Bool;
 	var calcDone:Bool;
-	var calcXMin:Int;
-	var calcYMin:Int;
-	var calcWidth:Int;
-	var calcHeight:Int;
-	var calcSizeHeight:Int;
+	var calcXMin:Float;
+	var calcYMin:Float;
+	var calcWidth:Float;
+	var calcHeight:Float;
+	var calcSizeHeight:Float;
 	var constraintWidth:Float = -1;
 	var constraintWidth:Float = -1;
 	var realMaxWidth:Float = -1;
 	var realMaxWidth:Float = -1;
 
 
@@ -43,7 +43,7 @@ class Text extends Drawable {
 		this.font = font;
 		this.font = font;
 		textAlign = Left;
 		textAlign = Left;
 		letterSpacing = 1;
 		letterSpacing = 1;
-        lineSpacing = 0;
+		lineSpacing = 0;
 		text = "";
 		text = "";
 		textColor = 0xFFFFFF;
 		textColor = 0xFFFFFF;
 	}
 	}
@@ -170,7 +170,7 @@ class Text extends Drawable {
 		}
 		}
 	}
 	}
 
 
-	public function splitText( text : hxd.UString, leftMargin = 0, afterData = 0 ) {
+	public function splitText( text : hxd.UString, leftMargin = 0., afterData = 0. ) {
 		if( realMaxWidth < 0 )
 		if( realMaxWidth < 0 )
 			return text;
 			return text;
 		var lines = [], rest = text, restPos = 0;
 		var lines = [], rest = text, restPos = 0;
@@ -229,13 +229,13 @@ class Text extends Drawable {
 
 
 	function initGlyphs( text : hxd.UString, rebuild = true, handleAlign = true, lines : Array<Int> = null ) : Void {
 	function initGlyphs( text : hxd.UString, rebuild = true, handleAlign = true, lines : Array<Int> = null ) : Void {
 		if( rebuild ) glyphs.clear();
 		if( rebuild ) glyphs.clear();
-		var x = 0, y = 0, xMax = 0, xMin = 0, prevChar = -1;
+		var x = 0., y = 0., xMax = 0., xMin = 0., prevChar = -1;
 		var align = handleAlign ? textAlign : Left;
 		var align = handleAlign ? textAlign : Left;
 		switch( align ) {
 		switch( align ) {
 		case Center, Right, MultilineCenter, MultilineRight:
 		case Center, Right, MultilineCenter, MultilineRight:
 			lines = [];
 			lines = [];
 			initGlyphs(text, false, false, lines);
 			initGlyphs(text, false, false, lines);
-			var max = if( align == MultilineCenter || align == MultilineRight ) calcWidth else realMaxWidth < 0 ? 0 : Std.int(realMaxWidth);
+			var max = if( align == MultilineCenter || align == MultilineRight ) hxd.Math.ceil(calcWidth) else realMaxWidth < 0 ? 0 : hxd.Math.ceil(realMaxWidth);
 			var k = align == Center || align == MultilineCenter ? 1 : 0;
 			var k = align == Center || align == MultilineCenter ? 1 : 0;
 			for( i in 0...lines.length )
 			for( i in 0...lines.length )
 				lines[i] = (max - lines[i]) >> k;
 				lines[i] = (max - lines[i]) >> k;
@@ -245,7 +245,7 @@ class Text extends Drawable {
 		}
 		}
 		var dl = font.lineHeight + lineSpacing;
 		var dl = font.lineHeight + lineSpacing;
 		var calcLines = !handleAlign && !rebuild && lines != null;
 		var calcLines = !handleAlign && !rebuild && lines != null;
-		var yMin = 0;
+		var yMin = 0.;
 		var t = splitText(text);
 		var t = splitText(text);
 		for( i in 0...t.length ) {
 		for( i in 0...t.length ) {
 			var cc = t.charCodeAt(i);
 			var cc = t.charCodeAt(i);
@@ -256,7 +256,7 @@ class Text extends Drawable {
 
 
 			if( cc == '\n'.code ) {
 			if( cc == '\n'.code ) {
 				if( x > xMax ) xMax = x;
 				if( x > xMax ) xMax = x;
-				if( calcLines ) lines.push(x);
+				if( calcLines ) lines.push(Math.ceil(x));
 				switch( align ) {
 				switch( align ) {
 				case Left:
 				case Left:
 					x = 0;
 					x = 0;
@@ -275,7 +275,7 @@ class Text extends Drawable {
 				prevChar = cc;
 				prevChar = cc;
 			}
 			}
 		}
 		}
-		if( calcLines ) lines.push(x);
+		if( calcLines ) lines.push(Math.ceil(x));
 		if( x > xMax ) xMax = x;
 		if( x > xMax ) xMax = x;
 
 
 		calcXMin = xMin;
 		calcXMin = xMin;
@@ -334,7 +334,7 @@ class Text extends Drawable {
 		var x, y, w : Float, h;
 		var x, y, w : Float, h;
 		if ( forSize ) {
 		if ( forSize ) {
 			x = calcXMin;  // TODO: Should be 0 as well for consistency, but currently causes problems with Flows
 			x = calcXMin;  // TODO: Should be 0 as well for consistency, but currently causes problems with Flows
-			y = 0;
+			y = 0.;
 			w = calcWidth;
 			w = calcWidth;
 			h = calcSizeHeight;
 			h = calcSizeHeight;
 		} else {
 		} else {

+ 5 - 5
h2d/TextInput.hx

@@ -17,13 +17,13 @@ class TextInput extends Text {
 
 
 	var interactive : h2d.Interactive;
 	var interactive : h2d.Interactive;
 	var cursorText : String;
 	var cursorText : String;
-	var cursorX : Int;
+	var cursorX : Float;
 	var cursorXIndex : Int;
 	var cursorXIndex : Int;
 	var cursorBlink = 0.;
 	var cursorBlink = 0.;
 	var cursorScroll = 0;
 	var cursorScroll = 0;
-	var scrollX = 0;
-	var selectionPos : Int;
-	var selectionSize : Int;
+	var scrollX = 0.;
+	var selectionPos : Float;
+	var selectionSize : Float;
 	var undo : Array<TextHistoryElement> = [];
 	var undo : Array<TextHistoryElement> = [];
 	var redo : Array<TextHistoryElement> = [];
 	var redo : Array<TextHistoryElement> = [];
 	var lastChange = 0.;
 	var lastChange = 0.;
@@ -255,7 +255,7 @@ class TextInput extends Text {
 		super.set_font(f);
 		super.set_font(f);
 		cursorTile = h2d.Tile.fromColor(0xFFFFFF, 1, font.size);
 		cursorTile = h2d.Tile.fromColor(0xFFFFFF, 1, font.size);
 		cursorTile.dy = 2;
 		cursorTile.dy = 2;
-		selectionTile = h2d.Tile.fromColor(0x3399FF, 0, font.lineHeight);
+		selectionTile = h2d.Tile.fromColor(0x3399FF, 0, hxd.Math.ceil(font.lineHeight));
 		return f;
 		return f;
 	}
 	}
 
 

+ 34 - 22
h2d/Tile.hx

@@ -10,14 +10,26 @@ class Tile {
 	var u2 : Float;
 	var u2 : Float;
 	var v2 : Float;
 	var v2 : Float;
 
 
-	public var dx : Int;
-	public var dy : Int;
-	public var x(default,null) : Int;
-	public var y(default,null) : Int;
-	public var width(default,null) : Int;
-	public var height(default,null) : Int;
-
-	function new(tex : h3d.mat.Texture, x : Int, y : Int, w : Int, h : Int, dx=0, dy=0) {
+	public var dx : Float;
+	public var dy : Float;
+	public var x(default,null) : Float;
+	public var y(default,null) : Float;
+	public var width(default,null) : Float;
+	public var height(default,null) : Float;
+
+	public var ix(get,never) : Int;
+	inline function get_ix() return Math.floor(x);
+
+	public var iy(get,never) : Int;
+	inline function get_iy() return Math.floor(y);
+
+	public var iwidth(get,never) : Int;
+	inline function get_iwidth() return Math.ceil(width + x) - ix;
+
+	public var iheight(get,never) : Int;
+	inline function get_iheight() return Math.ceil(height + y) - iy;
+
+	function new(tex : h3d.mat.Texture, x : Float, y : Float, w : Float, h : Float, dx : Float=0, dy : Float=0) {
 		this.innerTex = tex;
 		this.innerTex = tex;
 		this.x = x;
 		this.x = x;
 		this.y = y;
 		this.y = y;
@@ -50,17 +62,17 @@ class Tile {
 		setTexture(t.innerTex);
 		setTexture(t.innerTex);
 	}
 	}
 
 
-	public function sub( x : Int, y : Int, w : Int, h : Int, dx = 0, dy = 0 ) : Tile {
+	public function sub( x : Float, y : Float, w : Float, h : Float, dx = 0., dy = 0. ) : Tile {
 		return new Tile(innerTex, this.x + x, this.y + y, w, h, dx, dy);
 		return new Tile(innerTex, this.x + x, this.y + y, w, h, dx, dy);
 	}
 	}
 
 
 	public function center():Tile {
 	public function center():Tile {
-		return sub(0, 0, width, height, -(width>>1), -(height>>1));
+		return sub(0, 0, width, height, -(width * .5), -(height * .5));
 	}
 	}
 
 
 	public inline function setCenterRatio(?px:Float=0.5, ?py:Float=0.5) : Void {
 	public inline function setCenterRatio(?px:Float=0.5, ?py:Float=0.5) : Void {
-		dx = -Std.int(px*width);
-		dy = -Std.int(py*height);
+		dx = -(px*width);
+		dy = -(py*height);
 	}
 	}
 
 
 	public function flipX() : Void {
 	public function flipX() : Void {
@@ -73,7 +85,7 @@ class Tile {
 		dy = -dy - height;
 		dy = -dy - height;
 	}
 	}
 
 
-	public function setPosition(x : Int, y : Int) : Void {
+	public function setPosition(x : Float, y : Float) : Void {
 		this.x = x;
 		this.x = x;
 		this.y = y;
 		this.y = y;
 		var tex = innerTex;
 		var tex = innerTex;
@@ -85,7 +97,7 @@ class Tile {
 		}
 		}
 	}
 	}
 
 
-	public function setSize(w : Int, h : Int) : Void {
+	public function setSize(w : Float, h : Float) : Void {
 		this.width = w;
 		this.width = w;
 		this.height = h;
 		this.height = h;
 		var tex = innerTex;
 		var tex = innerTex;
@@ -95,7 +107,7 @@ class Tile {
 		}
 		}
 	}
 	}
 
 
-	public function scaleToSize( w : Int, h : Int ) : Void {
+	public function scaleToSize( w : Float, h : Float ) : Void {
 		this.width = w;
 		this.width = w;
 		this.height = h;
 		this.height = h;
 	}
 	}
@@ -106,8 +118,8 @@ class Tile {
 		v -= dy / tex.height;
 		v -= dy / tex.height;
 		u2 += dx / tex.width;
 		u2 += dx / tex.width;
 		v2 -= dy / tex.height;
 		v2 -= dy / tex.height;
-		x = Std.int(u * tex.width);
-		y = Std.int(v * tex.height);
+		x = u * tex.width;
+		y = v * tex.height;
 	}
 	}
 
 
 	public function dispose() : Void {
 	public function dispose() : Void {
@@ -128,18 +140,18 @@ class Tile {
 	/**
 	/**
 		Split horizontaly or verticaly the number of given frames
 		Split horizontaly or verticaly the number of given frames
 	**/
 	**/
-	public function split( frames : Int = 0, vertical = false ) : Array<Tile> {
+	public function split( frames : Int = 0, vertical = false, subpixel = false ) : Array<Tile> {
 		var tl = [];
 		var tl = [];
 		if( vertical ) {
 		if( vertical ) {
 			if( frames == 0 )
 			if( frames == 0 )
 				frames = Std.int(height / width);
 				frames = Std.int(height / width);
-			var stride = Std.int(height / frames);
+			var stride = subpixel ? height / frames : Std.int(height / frames);
 			for( i in 0...frames )
 			for( i in 0...frames )
 				tl.push(sub(0, i * stride, width, stride));
 				tl.push(sub(0, i * stride, width, stride));
 		} else {
 		} else {
 			if( frames == 0 )
 			if( frames == 0 )
 				frames = Std.int(width / height);
 				frames = Std.int(width / height);
-			var stride = Std.int(width / frames);
+			var stride = subpixel ? width / frames : Std.int(width / frames);
 			for( i in 0...frames )
 			for( i in 0...frames )
 				tl.push(sub(i * stride, 0, stride, height));
 				tl.push(sub(i * stride, 0, stride, height));
 		}
 		}
@@ -150,14 +162,14 @@ class Tile {
 		Split the tile into a list of tiles of Size x Size pixels.
 		Split the tile into a list of tiles of Size x Size pixels.
 		Unlike grid which is X/Y ordered, gridFlatten returns a single dimensional array ordered in Y/X.
 		Unlike grid which is X/Y ordered, gridFlatten returns a single dimensional array ordered in Y/X.
 	**/
 	**/
-	public function gridFlatten( size : Int, dx = 0, dy = 0 ) : Array<Tile> {
+	public function gridFlatten( size : Float, dx = 0., dy = 0. ) : Array<Tile> {
 		return [for( y in 0...Std.int(height / size) ) for( x in 0...Std.int(width / size) ) sub(x * size, y * size, size, size, dx, dy)];
 		return [for( y in 0...Std.int(height / size) ) for( x in 0...Std.int(width / size) ) sub(x * size, y * size, size, size, dx, dy)];
 	}
 	}
 
 
 	/**
 	/**
 		Split the tile into a list of tiles of Size x Size pixels.
 		Split the tile into a list of tiles of Size x Size pixels.
 	**/
 	**/
-	public function grid( size : Int, dx = 0, dy = 0 ) : Array<Array<Tile>> {
+	public function grid( size : Float, dx = 0., dy = 0. ) : Array<Array<Tile>> {
 		return [for( x in 0...Std.int(width / size) ) [for( y in 0...Std.int(height / size) ) sub(x * size, y * size, size, size, dx, dy)]];
 		return [for( x in 0...Std.int(width / size) ) [for( y in 0...Std.int(height / size) ) sub(x * size, y * size, size, size, dx, dy)]];
 	}
 	}
 
 

+ 7 - 7
h2d/TileGroup.hx

@@ -30,11 +30,11 @@ private class TileLayerContent extends h3d.prim.Primitive {
 		return if( buffer == null ) tmp.length >> 4 else buffer.totalVertices() >> 1;
 		return if( buffer == null ) tmp.length >> 4 else buffer.totalVertices() >> 1;
 	}
 	}
 
 
-	public inline function addColor( x : Int, y : Int, color : h3d.Vector, t : Tile ) {
+	public inline function addColor( x : Float, y : Float, color : h3d.Vector, t : Tile ) {
 		add(x, y, color.r, color.g, color.b, color.a, t);
 		add(x, y, color.r, color.g, color.b, color.a, t);
 	}
 	}
 
 
-	public function add( x : Int, y : Int, r : Float, g : Float, b : Float, a : Float, t : Tile ) {
+	public function add( x : Float, y : Float, r : Float, g : Float, b : Float, a : Float, t : Tile ) {
 		var sx = x + t.dx;
 		var sx = x + t.dx;
 		var sy = y + t.dy;
 		var sy = y + t.dy;
 		tmp.push(sx);
 		tmp.push(sx);
@@ -79,7 +79,7 @@ private class TileLayerContent extends h3d.prim.Primitive {
 		if( y > yMax ) yMax = y;
 		if( y > yMax ) yMax = y;
 	}
 	}
 
 
-	public function addTransform( x : Int, y : Int, sx : Float, sy : Float, r : Float, c : h3d.Vector, t : Tile ) {
+	public function addTransform( x : Float, y : Float, sx : Float, sy : Float, r : Float, c : h3d.Vector, t : Tile ) {
 
 
 		var ca = Math.cos(r), sa = Math.sin(r);
 		var ca = Math.cos(r), sa = Math.sin(r);
 		var hx = t.width, hy = t.height;
 		var hx = t.width, hy = t.height;
@@ -437,19 +437,19 @@ class TileGroup extends Drawable {
 		curColor.w = alpha;
 		curColor.w = alpha;
 	}
 	}
 
 
-	public inline function add(x : Int, y : Int, t : h2d.Tile) {
+	public inline function add(x : Float, y : Float, t : h2d.Tile) {
 		content.add(x, y, curColor.x, curColor.y, curColor.z, curColor.w, t);
 		content.add(x, y, curColor.x, curColor.y, curColor.z, curColor.w, t);
 	}
 	}
 
 
-	public inline function addColor( x : Int, y : Int, r : Float, g : Float, b : Float, a : Float, t : Tile) {
+	public inline function addColor( x : Float, y : Float, r : Float, g : Float, b : Float, a : Float, t : Tile) {
 		content.add(x, y, r, g, b, a, t);
 		content.add(x, y, r, g, b, a, t);
 	}
 	}
 
 
-	public inline function addAlpha(x : Int, y : Int, a : Float, t : h2d.Tile) {
+	public inline function addAlpha(x : Float, y : Float, a : Float, t : h2d.Tile) {
 		content.add(x, y, curColor.x, curColor.y, curColor.z, a, t);
 		content.add(x, y, curColor.x, curColor.y, curColor.z, a, t);
 	}
 	}
 
 
-	public inline function addTransform(x : Int, y : Int, sx : Float, sy : Float, r : Float, t : Tile) {
+	public inline function addTransform(x : Float, y : Float, sx : Float, sy : Float, r : Float, t : Tile) {
 		content.addTransform(x, y, sx, sy, r, curColor, t);
 		content.addTransform(x, y, sx, sy, r, curColor, t);
 	}
 	}
 
 

+ 2 - 2
h2d/col/Matrix.hx

@@ -71,12 +71,12 @@ class Matrix {
 		return new Point(pt.x * a + pt.y * c + x, pt.x * b + pt.y * d + y);
 		return new Point(pt.x * a + pt.y * c + x, pt.x * b + pt.y * d + y);
 	}
 	}
 
 
-	public inline function translate(x, y) {
+	public inline function translate( x : Float, y : Float ) {
 		this.x += x;
 		this.x += x;
 		this.y += y;
 		this.y += y;
 	}
 	}
 
 
-	public inline function prependTranslate( x, y ) {
+	public inline function prependTranslate( x : Float, y : Float ) {
 		this.x += a * x + c * y;
 		this.x += a * x + c * y;
 		this.y += b * x + d * y;
 		this.y += b * x + d * y;
 	}
 	}

+ 1 - 1
h2d/filter/Ambient.hx

@@ -17,7 +17,7 @@ class Ambient extends AbstractMask {
 	inline function set_invert(v) return pass.shader.maskInvert = v;
 	inline function set_invert(v) return pass.shader.maskInvert = v;
 
 
 	override function draw( ctx : RenderContext, t : h2d.Tile ) {
 	override function draw( ctx : RenderContext, t : h2d.Tile ) {
-		var out = ctx.textures.allocTarget("ambientTmp", t.width, t.height, false);
+		var out = ctx.textures.allocTileTarget("ambientTmp", t);
 		pass.apply(t.getTexture(), out, getMaskTexture(t), maskMatrix);
 		pass.apply(t.getTexture(), out, getMaskTexture(t), maskMatrix);
 		return h2d.Tile.fromTexture(out);
 		return h2d.Tile.fromTexture(out);
 	}
 	}

+ 1 - 1
h2d/filter/Bloom.hx

@@ -20,7 +20,7 @@ class Bloom extends Blur {
 	inline function set_power(v) return bloom.shader.power = v;
 	inline function set_power(v) return bloom.shader.power = v;
 
 
 	override function draw( ctx : RenderContext, t : h2d.Tile ) {
 	override function draw( ctx : RenderContext, t : h2d.Tile ) {
-		var dst = ctx.textures.allocTarget("dest", t.width, t.height, false);
+		var dst = ctx.textures.allocTileTarget("dest", t);
 		h3d.pass.Copy.run(t.getTexture(), dst);
 		h3d.pass.Copy.run(t.getTexture(), dst);
 		var blurred = super.draw(ctx, t);
 		var blurred = super.draw(ctx, t);
 		bloom.shader.texture = blurred.getTexture();
 		bloom.shader.texture = blurred.getTexture();

+ 1 - 1
h2d/filter/ColorMatrix.hx

@@ -16,7 +16,7 @@ class ColorMatrix extends Filter {
 	inline function set_matrix(m) return pass.matrix = m;
 	inline function set_matrix(m) return pass.matrix = m;
 
 
 	override function draw( ctx : RenderContext, t : h2d.Tile ) {
 	override function draw( ctx : RenderContext, t : h2d.Tile ) {
-		var tout = ctx.textures.allocTarget("colorMatrixOut", t.width, t.height, false);
+		var tout = ctx.textures.allocTileTarget("colorMatrixOut", t);
 		pass.apply(t.getTexture(), tout);
 		pass.apply(t.getTexture(), tout);
 		return h2d.Tile.fromTexture(tout);
 		return h2d.Tile.fromTexture(tout);
 	}
 	}

+ 1 - 1
h2d/filter/Displacement.hx

@@ -28,7 +28,7 @@ class Displacement extends Filter {
 	}
 	}
 
 
 	override function draw( ctx : RenderContext, t : h2d.Tile ) {
 	override function draw( ctx : RenderContext, t : h2d.Tile ) {
-		var out = ctx.textures.allocTarget("displacementOutput", t.width, t.height, false);
+		var out = ctx.textures.allocTileTarget("displacementOutput", t);
 		ctx.engine.pushTarget(out);
 		ctx.engine.pushTarget(out);
 		var s = disp.shader;
 		var s = disp.shader;
 		s.texture = t.getTexture();
 		s.texture = t.getTexture();

+ 1 - 1
h2d/filter/DropShadow.hx

@@ -21,7 +21,7 @@ class DropShadow extends Glow {
 
 
 	override function draw( ctx : RenderContext, t : h2d.Tile ) {
 	override function draw( ctx : RenderContext, t : h2d.Tile ) {
 		setParams();
 		setParams();
-		var save = ctx.textures.allocTarget("glowSave", t.width, t.height, false);
+		var save = ctx.textures.allocTileTarget("glowSave", t);
 		h3d.pass.Copy.run(t.getTexture(), save, None);
 		h3d.pass.Copy.run(t.getTexture(), save, None);
 		pass.apply(ctx, save);
 		pass.apply(ctx, save);
 		var dx = Math.round(Math.cos(angle) * distance);
 		var dx = Math.round(Math.cos(angle) * distance);

+ 1 - 1
h2d/filter/Glow.hx

@@ -25,7 +25,7 @@ class Glow extends Blur {
 		setParams();
 		setParams();
 		var tex = t.getTexture();
 		var tex = t.getTexture();
 		var old = tex.filter;
 		var old = tex.filter;
-		var save = ctx.textures.allocTarget("glowSave", t.width, t.height, false);
+		var save = ctx.textures.allocTileTarget("glowSave", t);
 		h3d.pass.Copy.run(tex, save, None);
 		h3d.pass.Copy.run(tex, save, None);
 		tex.filter = Linear;
 		tex.filter = Linear;
 		pass.apply(ctx, tex);
 		pass.apply(ctx, tex);

+ 1 - 1
h2d/filter/Mask.hx

@@ -42,7 +42,7 @@ class Mask extends AbstractMask {
 		var mask = getMaskTexture(t);
 		var mask = getMaskTexture(t);
 		if( mask == null )
 		if( mask == null )
 			throw "Mask should be rendered before masked object";
 			throw "Mask should be rendered before masked object";
-		var out = ctx.textures.allocTarget("maskTmp", t.width, t.height, false);
+		var out = ctx.textures.allocTileTarget("maskTmp", t);
 		ctx.engine.pushTarget(out);
 		ctx.engine.pushTarget(out);
 		pass.shader.texture = t.getTexture();
 		pass.shader.texture = t.getTexture();
 		pass.shader.mask = getMaskTexture(t);
 		pass.shader.mask = getMaskTexture(t);

+ 1 - 1
h2d/filter/Shader.hx

@@ -24,7 +24,7 @@ class Shader< T:h3d.shader.ScreenShader > extends Filter {
 	function get_shader() return pass.shader;
 	function get_shader() return pass.shader;
 
 
 	override function draw( ctx : RenderContext, t : h2d.Tile ) {
 	override function draw( ctx : RenderContext, t : h2d.Tile ) {
-		var out = ctx.textures.allocTarget("shaderTmp", t.width, t.height, false);
+		var out = ctx.textures.allocTileTarget("shaderTmp", t);
 		ctx.engine.pushTarget(out);
 		ctx.engine.pushTarget(out);
 		Reflect.setField(shader, textureParam + "__", t.getTexture());
 		Reflect.setField(shader, textureParam + "__", t.getTexture());
 		if( nearest ) t.getTexture().filter = Nearest;
 		if( nearest ) t.getTexture().filter = Nearest;

+ 2 - 2
h3d/impl/Benchmark.hx

@@ -154,7 +154,7 @@ class Benchmark extends h2d.Graphics {
 	function syncTip(s:StatsObject) {
 	function syncTip(s:StatsObject) {
 		tip.text = s.name+"( " + Std.int(s.time / 1e6) + "." + StringTools.lpad(""+(Std.int(s.time/1e4)%100),"0",2) + " ms " + s.drawCalls + " draws )";
 		tip.text = s.name+"( " + Std.int(s.time / 1e6) + "." + StringTools.lpad(""+(Std.int(s.time/1e4)%100),"0",2) + " ms " + s.drawCalls + " draws )";
 		var tw = tip.textWidth;
 		var tw = tip.textWidth;
-		var tx = s.xPos + ((s.xSize - tw) >> 1);
+		var tx = s.xPos + ((s.xSize - tw) * .5);
 		if( tx + tw > curWidth ) tx = curWidth - tw;
 		if( tx + tw > curWidth ) tx = curWidth - tw;
 		if( tx < 0 ) tx = 0;
 		if( tx < 0 ) tx = 0;
 		if( hxd.Math.abs(tip.x - tx) > 5 ) tip.x = tx;
 		if( hxd.Math.abs(tip.x - tx) > 5 ) tip.x = tx;
@@ -294,7 +294,7 @@ class Benchmark extends h2d.Graphics {
 				l.visible = true;
 				l.visible = true;
 				l.textColor = textColor;
 				l.textColor = textColor;
 				l.text = s.name;
 				l.text = s.name;
-				l.x = xPos + ((xSize - l.textWidth) >> 1);
+				l.x = xPos + ((xSize - l.textWidth) * .5);
 			}
 			}
 
 
 			s.xPos = xPos;
 			s.xPos = xPos;

+ 4 - 0
h3d/impl/TextureCache.hx

@@ -61,6 +61,10 @@ class TextureCache {
 		return allocTarget(name, Math.ceil(e.width * scale), Math.ceil(e.height * scale), defaultDepth, format);
 		return allocTarget(name, Math.ceil(e.width * scale), Math.ceil(e.height * scale), defaultDepth, format);
 	}
 	}
 
 
+	public function allocTileTarget( name : String, tile : h2d.Tile, defaultDepth=false, ?format:hxd.PixelFormat ) {
+		return allocTarget( name, tile.iwidth, tile.iheight, defaultDepth, format );
+	}
+
 	public function dispose() {
 	public function dispose() {
 		for( t in cache )
 		for( t in cache )
 			t.dispose();
 			t.dispose();

+ 2 - 2
hxd/fmt/bfnt/FontParser.hx

@@ -260,10 +260,10 @@ class FontParser {
 		font.tile = tile;
 		font.tile = tile;
 
 
 		if ( font.baseLine == 0 ) {
 		if ( font.baseLine == 0 ) {
-			var padding = 0;
+			var padding : Float = 0;
 			var space = glyphs.get(" ".code);
 			var space = glyphs.get(" ".code);
 			if( space != null )
 			if( space != null )
-				padding = (space.t.height >> 1);
+				padding = (space.t.height * .5);
 
 
 			var a = glyphs.get("A".code);
 			var a = glyphs.get("A".code);
 			if( a == null )
 			if( a == null )

+ 10 - 10
hxd/fmt/bfnt/Writer.hx

@@ -30,8 +30,8 @@ class Writer {
 		writeString(font.name);
 		writeString(font.name);
 		out.writeInt16(font.size);
 		out.writeInt16(font.size);
 		writeString(font.tilePath);
 		writeString(font.tilePath);
-		out.writeInt16(font.lineHeight);
-		out.writeInt16(font.baseLine);
+		out.writeInt16(Std.int(font.lineHeight));
+		out.writeInt16(Std.int(font.baseLine));
 		if (font.defaultChar != font.nullChar) {
 		if (font.defaultChar != font.nullChar) {
 			var found = false;
 			var found = false;
 			for ( k in font.glyphs.keys() ) {
 			for ( k in font.glyphs.keys() ) {
@@ -53,18 +53,18 @@ class Writer {
 			var glyph = font.glyphs.get(id);
 			var glyph = font.glyphs.get(id);
 			var t = glyph.t;
 			var t = glyph.t;
 			out.writeInt32(id);
 			out.writeInt32(id);
-			out.writeUInt16(t.x);
-			out.writeUInt16(t.y);
-			out.writeUInt16(t.width);
-			out.writeUInt16(t.height);
-			out.writeInt16(t.dx);
-			out.writeInt16(t.dy);
-			out.writeInt16(glyph.width);
+			out.writeUInt16(Std.int(t.x));
+			out.writeUInt16(Std.int(t.y));
+			out.writeUInt16(Std.int(t.width));
+			out.writeUInt16(Std.int(t.height));
+			out.writeInt16(Std.int(t.dx));
+			out.writeInt16(Std.int(t.dy));
+			out.writeInt16(Std.int(glyph.width));
 			var kern = @:privateAccess glyph.kerning;
 			var kern = @:privateAccess glyph.kerning;
 			while ( kern != null ) {
 			while ( kern != null ) {
 				if (kern.prevChar != 0) {
 				if (kern.prevChar != 0) {
 					out.writeInt32(kern.prevChar);
 					out.writeInt32(kern.prevChar);
-					out.writeInt16(kern.offset);
+					out.writeInt16(Std.int(kern.offset));
 				}
 				}
 				kern = kern.next;
 				kern = kern.next;
 			}
 			}

+ 2 - 2
samples/Pad.hx

@@ -112,7 +112,7 @@ class PadUI extends h2d.Object {
 
 
 		buttons = new Map();
 		buttons = new Map();
 
 
-		var x = 0;
+		var x = 0.;
 		for( n in ["A","B","X","Y","LB","RB","LT","RT","back","start","dpadUp","dpadDown","dpadLeft","dpadRight"] ){
 		for( n in ["A","B","X","Y","LB","RB","LT","RT","back","start","dpadUp","dpadDown","dpadLeft","dpadRight"] ){
 			var t = new h2d.Text(fnt,this);
 			var t = new h2d.Text(fnt,this);
 			x += 20;
 			x += 20;
@@ -120,7 +120,7 @@ class PadUI extends h2d.Object {
 			t.y = 140;
 			t.y = 140;
 			t.text = n;
 			t.text = n;
 			t.alpha = 0.1;
 			t.alpha = 0.1;
-			var bg = new h2d.Bitmap(h2d.Tile.fromColor(0xFFFFFF, t.textWidth, 8), t);
+			var bg = new h2d.Bitmap(h2d.Tile.fromColor(0xFFFFFF, hxd.Math.ceil(t.textWidth), 8), t);
 			bg.y = 10;
 			bg.y = 10;
 			bg.alpha = 0;
 			bg.alpha = 0;
 			buttons.set(n, { tf : t, bg : bg });
 			buttons.set(n, { tf : t, bg : bg });