Hi, I’m using a TextField object with the autosize property set to LEFT (as the text align). I’m getting some strange results while running it on HTML5 target. The width I get from the TextField after setting the text is smaller than the actual text, like the image below. There, I put a transparent overlay above the text with the width I get by reading the TextField width property for comparison. This is an embed font.
// creating the text field
this._text = new TextField();
this._text.selectable = false;
this._format = new TextFormat();
this._format.align = TextFormatAlign.LEFT;
this._format.font = 'font name';
this._format.size = font size;
this._text.defaultTextFormat = this._format;
this._text.autoSize = TextFieldAutoSize.LEFT;
this._text.wordWrap = false;
this._text.multiline = false;
this._text.embedFonts = true;
this._text.cacheAsBitmap = true;
this.addChild(this._text);
// setting the text
var txt:String = 'My text here';
this._text.text = txt;
// getting text field size
trace (this._text.width);
My issue is that this._text.width is in fact lower than it should be (even considering it is being displayed correctly). On my picture above, the tranaparent box width is set to the value I get: it corresponds to the with I get from the below text.
I run example of our code and all works correctly.
My settings :
haxe 4.2.5
openfl 9.3.2
lime 8.1.1
My by You are using bad file of font or wrong type (svg or eot). (In may case it was *.ttf)
Send my your project on mail. [email protected]
(System Win 10, Chrome)
No, in fact I use this class to enable the user to upload the font at runtime:
package com.tilbuci.font;
/** OPENFL **/
import openfl.text.Font;
#if (js && html5)
import js.Browser;
import js.html.FontFace;
import js.lib.ArrayBuffer;
import js.lib.DataView;
#end
/** TILBUCI **/
import com.tilbuci.data.DataLoader;
import com.tilbuci.data.Global;
/**
Embeds a font file at runtime.
(many thanks to sanline for HTML5 font loading - https://github.com/scanline)
**/
class EmbedFont {
/**
loaded font name
**/
public var fname(get, null):String;
private var _fname:String = '';
private function get_fname():String { return (this._fname); }
/**
method to call after font load
**/
private var _ac:Dynamic;
/**
Constructor.
@param path the path to the font (ttf, otf or woff2 file)
@param name the font family name
@param ac a method to call after font loading (receives two parameters: Bool and EmbedFont)
**/
public function new(path:String, name:String, ac:Dynamic = null) {
// adjust path
#if (js && html5)
path = StringTools.replace(path, '.ttf', '.woff2');
path = StringTools.replace(path, '.otf', '.woff2');
#else
path = StringTools.replace(path, '.woff2', '.ttf');
path = StringTools.replace(path, '.woff', '.ttf');
#end
// load file
this._fname = name;
this._ac = ac;
new DataLoader(true, path, 'GET', null, DataLoader.MODEBINARY, onLoad);
}
/**
File loading ends.
@param ok load successful?
@param ld the loader reference
**/
private function onLoad(ok:Bool, ld:DataLoader):Void {
if (ok) {
// load the font file
#if (js && html5)
// browser
var buffer:ArrayBuffer = new ArrayBuffer(ld.binary.length);
var view:DataView = new DataView(buffer, 0, buffer.byteLength);
for (i in 0...ld.binary.length) view.setUint8(i, ld.binary[i]);
var face:FontFace = new FontFace(this._fname, buffer);
Browser.document.fonts.add(face);
face.load().then(function(_){
var future:lime.app.Future<Font> = Font.loadFromName(this._fname);
future.onComplete(function(font){
// warn listeners about load ok
Global.fonts.push(this._fname);
if (this._ac != null) this._ac(true, this);
this._ac = null;
});
});
#elseif air
// no support for AIR dynamic font loading
this._fname = '';
if (this._ac = null) this._ac(false, this);
this._ac = null;
#else
// binary font load
var fnt:Font = Font.fromBytes(ld.binary);
Font.registerFont(fnt);
this._fname = fnt.fontName;
// warn listeners about load ok
Global.fonts.push(this._fname);
if (this._ac != null) this._ac(true, this);
this._ac = null;
#end
} else {
// error loading the font file
this._fname = '';
if (this._ac = null) this._ac(false, this);
this._ac = null;
}
}
}
/**
Information about an embed font.
**/
typedef FontInfo = {
var name:String; // name
var file:String; // file
}
By measuring line metrics char by char when I set a text I realized that I get a slightly lower value for width that it should be, so when I add up all of them, the result gets worse for bigger lines.
Another thing I noticed is that if I try to draw the textfield into a bitmapdata, it won’t work as expected as blurred squares appear instead of the text itself. I was trying to use this as an alternate way to measure the line width.
I see. I was in fact expecting something like that. Since I’m unable to know what fonts will be used beforehand, I managed to calculate a width by getting metrics for individual chars on my string and apply it to the TextField manually.