123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- package h2d;
- /**
- A `FontChar` kerning information as well as linked list of kernings. See `FontChar.kerning`.
- **/
- class Kerning {
- /**
- A character that should precede current character in order to apply this kerning.
- **/
- public var prevChar : Int;
- /**
- A kerning offset between the character pair in pixels.
- **/
- public var offset : Float;
- /**
- The next kerning reference.
- **/
- public var next : Null<Kerning>;
- /**
- Create a new kerning instance.
- @param c The preceding character.
- @param o The kerning offset.
- **/
- public function new(c, o) {
- this.prevChar = c;
- this.offset = o;
- }
- }
- /**
- A single `Font` character descriptor.
- **/
- class FontChar {
- /**
- A Tile representing position of a character on the texture.
- **/
- public var t : h2d.Tile;
- /**
- Horizontal advance value of the character.
- On top of advance, letter spacing is affected by `FontChar.kerning` matches and `Text.letterSpacing`.
- **/
- public var width : Float;
- /**
- Linked list of kerning values.
- In order to add new kerning values use `FontChar.addKerning` and `FontChar.getKerningOffset` to retrieve kerning offsets.
- **/
- @:dox(show)
- var kerning : Null<Kerning>;
- /**
- Create a new font character.
- @param t The character Tile.
- @param width The horizontal advance of the character.
- **/
- public function new(t,w) {
- this.t = t;
- this.width = w;
- }
- /**
- Adds a new kerning to the character with specified `prevChar` and `offset`.
- **/
- public function addKerning( prevChar : Int, offset : Int ) {
- var k = new Kerning(prevChar, offset);
- k.next = kerning;
- kerning = k;
- }
- /**
- Returns kerning offset for a pair `[prevChar, currentChar]` or `0` if there was no paired kerning value.
- **/
- public function getKerningOffset( prevChar : Int ) {
- var k = kerning;
- while( k != null ) {
- if( k.prevChar == prevChar )
- return k.offset;
- k = k.next;
- }
- return 0;
- }
- /**
- Clones the character instance.
- **/
- public function clone() {
- var c = new FontChar(t.clone(), width);
- // 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;
- }
- }
- /**
- Channel reading method for `FontType.SignedDistanceField`.
- **/
- enum abstract SDFChannel(Int) from Int to Int {
- /** Use red channel of a texture to determine distance. **/
- var Red = 0;
- /** Use green channel of a texture to determine distance. **/
- var Green = 1;
- /** Use blue channel of a texture to determine distance. **/
- var Blue = 2;
- /** Use alpha channel of a texture to determine distance. **/
- var Alpha = 3;
- /** Use RGB channels of a texture to determine distance. See here for details: https://github.com/Chlumsky/msdfgen **/
- var MultiChannel = 4;
- }
- /**
- The rendering type of the of the `Font` instance.
- **/
- enum FontType {
- /**
- A simple raster bitmap font.
- **/
- BitmapFont;
- /**
- A Signed Distance Field font data. Each glyph pixel contains the distance to the closest glyph edge instead of actual color.
- To render an SDF font, `Text` utilizes `h3d.shader.SignedDistanceField` shader to produce smoothed and scalable text.
- Because shader expects texture to use bilinear filtering, Text automatically enables `Drawable.smooth` on itself.
- See [Text](https://github.com/HeapsIO/heaps/wiki/Text) manual and [libgdx wiki](https://github.com/libgdx/libgdx/wiki/Distance-field-fonts) for more details.
- @param channel The channel that serves as distance data source.
- @param alphaCutoff The distance value that is considered to be the edge. Usually should be 0.5.
- @param smoothing The smoothing of edge. Lower value lead to sharper edges. Value of -1 sets it to automatic.
- **/
- SignedDistanceField(channel : SDFChannel, alphaCutoff : Float, smoothing : Float);
- }
- /**
- An instance of a text font.
- Heaps comes with a default Font that covers basic ASCII characters, and can be retrieved via `hxd.res.DefaultFont.get()`.
- **/
- class Font {
- /**
- The font name. Assigned on font creation and can be used to identify font instances.
- **/
- public var name(default, null) : String;
- /**
- Current font size. Font can be resized with `resizeTo`.
- **/
- public var size(default, null) : Int;
- /**
- The baseline value of the font represents the base on which characters will sit.
- Used primarily with `HtmlText` to sit multiple fonts and images at the same line.
- **/
- public var baseLine(default, null) : Float;
- /**
- Font line height provides vertical offset for each new line of the text.
- **/
- public var lineHeight(default, null) : Float;
- /**
- Reference to the source Tile containing all glyphs of the Font.
- **/
- public var tile(default,null) : h2d.Tile;
- /**
- The resource path of the source Tile. Either relative to .fnt or to resources root.
- **/
- public var tilePath(default,null) : String;
- /**
- The font type. BitmapFonts rendered as-is, but SDF fonts will use an extra shader to produce scalable smooth fonts.
- See `FontType.SignedDistanceField` for more details.
- **/
- public var type : FontType;
- /**
- Font charset allows to resolve specific char codes that are not directly present in glyph map as well as detect spaces.
- Defaults to `hxd.Charset.getDefault()`.
- **/
- public var charset : hxd.Charset;
- var glyphs : Map<Int,FontChar>;
- var nullChar : FontChar;
- var defaultChar : FontChar;
- var initSize:Int;
- var offsetX:Float = 0;
- var offsetY:Float = 0;
- /**
- Creates an empty font instance with specified parameters.
- @param name The name of the font.
- @param size Initial size of the font.
- @param type The font type.
- **/
- function new(name : String, size : Int, ?type : FontType) {
- this.name = name;
- this.size = size;
- this.initSize = size;
- glyphs = new Map();
- defaultChar = nullChar = new FontChar(new Tile(null, 0, 0, 0, 0),0);
- charset = hxd.Charset.getDefault();
- if (name != null)
- this.tilePath = haxe.io.Path.withExtension(name, "png");
- if (type == null)
- this.type = BitmapFont;
- else
- this.type = type;
- }
- /**
- Returns a `FontChar` instance corresponding to the `code`.
- If font char is not present in glyph list, `charset.resolveChar` is called.
- Returns `null` if glyph under specified charcode does not exist.
- @param code The charcode to search for.
- **/
- public inline function getChar( code : Int ) {
- var c = glyphs.get(code);
- if( c == null ) {
- c = charset.resolveChar(code, glyphs);
- if( c == null )
- c = code == "\r".code || code == "\n".code ? nullChar : defaultChar;
- }
- return c;
- }
- /**
- Offsets all glyphs by specified amount.
- Affects each glyph `Tile.dx` and `Tile.dy`.
- @param x The X offset of the glyphs.
- @param y The Y offset of the glyphs.
- **/
- public function setOffset( x : Float, y :Float ) {
- var dx = x - offsetX;
- var dy = y - offsetY;
- if( dx == 0 && dy == 0 ) return;
- for( g in glyphs ) {
- g.t.dx += dx;
- g.t.dy += dy;
- }
- this.offsetX += dx;
- this.offsetY += dy;
- }
- /**
- Creates a copy of the font instance.
- **/
- public function clone() {
- var f = new Font(name, size);
- f.baseLine = baseLine;
- f.lineHeight = lineHeight;
- f.tile = tile.clone();
- f.charset = charset;
- f.defaultChar = defaultChar.clone();
- f.type = type;
- f.offsetX = offsetX;
- f.offsetY = offsetY;
- for( g in glyphs.keys() ) {
- var c = glyphs.get(g);
- var c2 = c.clone();
- if( c == defaultChar )
- f.defaultChar = c2;
- f.glyphs.set(g, c2);
- }
- return f;
- }
- /**
- Resizes the Font instance to specified size.
- For BitmapFonts it can be used to create smoother fonts by rasterizing them with double size while still keeping the original glyph size by downscaling the font.
- And SDF fonts can be resized to arbitrary sizes to produce scalable fonts of any size.
- @param size The new font size.
- **/
- public function resizeTo( size : Int ) {
- var ratio = size / initSize;
- for( c in glyphs ) {
- 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 = Math.ceil(lineHeight * ratio);
- baseLine = Math.ceil(baseLine * ratio);
- this.size = size;
- }
- /**
- Checks if character is present in glyph list.
- Compared to `getChar` does not check if it exists through `Font.charset`.
- @param code The charcode to look up.
- **/
- public function hasChar( code : Int ) : Bool {
- return glyphs.get(code) != null;
- }
- /**
- Disposes of the Font instance. Equivalent to `Tile.dispose`.
- **/
- public function dispose() {
- 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;
- }
- }
|