Browse Source

allow offset(x) in font declaration to adjust auto baseline

Nicolas Cannasse 3 years ago
parent
commit
ace37f6230
3 changed files with 50 additions and 31 deletions
  1. 19 0
      h2d/Font.hx
  2. 29 15
      h2d/domkit/BaseComponents.hx
  3. 2 16
      hxd/fmt/bfnt/FontParser.hx

+ 19 - 0
h2d/Font.hx

@@ -312,4 +312,23 @@ class Font {
 		tile.dispose();
 	}
 
+	/**
+	 	Calculate a baseLine default value based on available glyphs.
+	 */
+	public function calcBaseLine() {
+		var padding : Float = 0;
+		var space = glyphs.get(" ".code);
+		if( space != null )
+			padding = (space.t.height * .5);
+
+		var a = glyphs.get("A".code);
+		if( a == null )
+			a = glyphs.get("a".code);
+		if( a == null )
+			a = glyphs.get("0".code); // numerical only
+		if( a == null )
+			return lineHeight - 2 - padding;
+		return a.t.dy + a.t.height - padding;
+	}
+
 }

+ 29 - 15
h2d/domkit/BaseComponents.hx

@@ -177,22 +177,32 @@ class CustomParser extends CssValue.ValueParser {
 	public function parseFont( value : CssValue ) {
 		var path = null;
 		var sdf = null;
+		var offset = 0;
 		switch(value) {
 			case VGroup(args):
+				var args = args.copy();
 				path = parsePath(args[0]);
-				sdf = {
-					size: parseInt(args[1]),
-					channel: args.length >= 3 ? switch(args[2]) {
-						case VIdent("red"): h2d.Font.SDFChannel.Red;
-						case VIdent("green"): h2d.Font.SDFChannel.Green;
-						case VIdent("blue"): h2d.Font.SDFChannel.Blue;
-						case VIdent("multi"): h2d.Font.SDFChannel.MultiChannel;
-						default: h2d.Font.SDFChannel.Alpha;
-					} : h2d.Font.SDFChannel.Alpha,
-					cutoff: args.length >= 4 ? parseFloat(args[3]) : 0.5,
-					smooth: args.length >= 5 ? parseFloat(args[4]) : 1.0/32.0
-				};
-				adjustSdfParams(sdf);
+				switch( args[1] ) {
+				case VCall("offset", [v]):
+					offset = parseInt(v);
+					args.splice(1,1);
+				default:
+				}
+				if( args[1] != null ) {
+					sdf = {
+						size: parseInt(args[1]),
+						channel: args.length >= 3 ? switch(args[2]) {
+							case VIdent("red"): h2d.Font.SDFChannel.Red;
+							case VIdent("green"): h2d.Font.SDFChannel.Green;
+							case VIdent("blue"): h2d.Font.SDFChannel.Blue;
+							case VIdent("multi"): h2d.Font.SDFChannel.MultiChannel;
+							default: h2d.Font.SDFChannel.Alpha;
+						} : h2d.Font.SDFChannel.Alpha,
+						cutoff: args.length >= 4 ? parseFloat(args[3]) : 0.5,
+						smooth: args.length >= 5 ? parseFloat(args[4]) : 1.0/32.0
+					};
+					adjustSdfParams(sdf);
+				}
 			default:
 				path = parsePath(value);
 		}
@@ -200,10 +210,14 @@ class CustomParser extends CssValue.ValueParser {
 		#if macro
 		return res;
 		#else
+		var fnt;
 		if(sdf != null)
-			return res.to(hxd.res.BitmapFont).toSdfFont(sdf.size, sdf.channel, sdf.cutoff, sdf.smooth);
+			fnt = res.to(hxd.res.BitmapFont).toSdfFont(sdf.size, sdf.channel, sdf.cutoff, sdf.smooth);
 		else
-			return res.to(hxd.res.BitmapFont).toFont();
+			fnt = res.to(hxd.res.BitmapFont).toFont();
+		if( offset != 0 )
+			@:privateAccess fnt.baseLine = fnt.calcBaseLine() - offset;
+		return fnt;
 		#end
 	}
 

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

@@ -259,22 +259,8 @@ class FontParser {
 
 		font.tile = tile;
 
-		if ( font.baseLine == 0 ) {
-			var padding : Float = 0;
-			var space = glyphs.get(" ".code);
-			if( space != null )
-				padding = (space.t.height * .5);
-
-			var a = glyphs.get("A".code);
-			if( a == null )
-				a = glyphs.get("a".code);
-			if( a == null )
-				a = glyphs.get("0".code); // numerical only
-			if( a == null )
-				font.baseLine = font.lineHeight - 2 - padding;
-			else
-				font.baseLine = a.t.dy + a.t.height - padding;
-		}
+		if( font.baseLine == 0 )
+			font.baseLine = font.calcBaseLine();
 
 		var fallback = glyphs.get(0xFFFD); // <?>
 		if( fallback == null )