Ability to specify font weight for HTML5 (Google Fonts)

In a HTML5 project I’m currently building, I’m using Roboto Regular, Roboto Bold and Roboto Light. If I allow the user to pull those fonts in via Google, which would be more efficient, I’m not sure how I can reference them.

According to Google Fonts, all three of those fonts have the same name ('Roboto'). Which one is used is based on the font weight specified.

Is it possible to set the font weight in OpenFL?

Currently the internals of the TextField class will look for the font name + “Bold”, “Italic” or “Bold Italic” (and will ignore “Regular” at the end of a font name) to search for a variant.

If we were to make it work based on weights, I believe it would have to affect how we render the font, but the concern I have is whether we would know what weights are supported? Perhaps if the Font class had a weight property then the TextField renderer could use that so it could be possible to manually add a Roboto Bold that is “Roboto” + a higher weight?

Thanks @singmajesty.

I’ve had a bit more of a play around with this and I think I have a working option, albeit editing the produced HTML as opposed to an in-OpenFL fix. It still doesn’t allow me to specify weight, but I was able to successfully access web fonts based on the font name (eg 'Roboto Light'), as opposed to the family name (eg 'Roboto').

  1. I still bring the fonts into my project as local assets, as this allows me to easily reference the fonts by their correct names in code and see how things should look when debugging using Neko or HashLink. I think it’s important here that I’m using this class as a means to reference the fonts by their fontName property, because this’ll marry up with the web fonts I use later.

Example:

class Fonts 
{
    public static var ELSIE_BLACK(default, null):String;
    public static var ELSIE_REGULAR(default, null):String;
    public static var ROBOTO_BOLD(default, null):String;
    public static var ROBOTO_LIGHT(default, null):String;
    public static var ROBOTO_REGULAR(default, null):String;        

    public static function init():Void {
        #if js
            ELSIE_BLACK = Assets.getFont("fonts/Elsie-Black.ttf").fontName;
            ELSIE_REGULAR = Assets.getFont("fonts/Elsie-Regular.ttf").fontName;
            ROBOTO_BOLD = Assets.getFont("fonts/Roboto-Bold.ttf").fontName;
            ROBOTO_LIGHT = Assets.getFont("fonts/Roboto-Light.ttf").fontName;
            ROBOTO_REGULAR = Assets.getFont("fonts/Roboto-Regular.ttf").fontName;
        #else
            Font.registerFont(ElsieBlack);
            ELSIE_BLACK = (new ElsieBlack()).fontName;
            Font.registerFont(ElsieRegular);
            ELSIE_REGULAR = (new ElsieRegular()).fontName;
            Font.registerFont(RobotoBold);
            ROBOTO_BOLD = (new RobotoBold()).fontName;
            Font.registerFont(RobotoLight);
            ROBOTO_LIGHT = (new RobotoLight()).fontName;
            Font.registerFont(RobotoRegular);
            ROBOTO_REGULAR = (new RobotoRegular()).fontName;
        #end
    }
}

@:font("assets/fonts/Elsie-Black.ttf")
private class ElsieBlack extends Font {}

@:font("assets/fonts/Elsie-Regular.ttf")
private class ElsieRegular extends Font {}

@:font("assets/fonts/Roboto-Bold.ttf")
private class RobotoBold extends Font {}

@:font("assets/fonts/Roboto-Light.ttf")
private class RobotoLight extends Font {}

@:font("assets/fonts/Roboto-Regular.ttf")
private class RobotoRegular extends Font {}

When the HTML5 is built (openfl build html5), the index.html will contain CSS to load those supplied fonts into the app.

  1. To use Google web fonts instead, I go to Google Fonts, select the specific font variants I need (the same as those already referenced above), then have a look at the Embed snippet Google provide. I want to copy the CSS URL in that (see image below) and paste that URL directly into my browser. Now I copy the entire CSS code from here.

image

  1. In my projects assets folder, make a css folder and create a new file called fonts.css. Paste the Google Fonts CSS into that new file and save. I keep this open in my editor, as I’ll come back to it.

image

  1. Define this new asset in project.xml so it’s automatically included with the build.

image

  1. I open the built index.html file in an editor. I find the @font-face rules, paying particular attention to the font-family definitions in each.

Eg:

@font-face {
		font-family: 'Roboto Light';

Now I modify the fonts.css file created in step 3. Each font-family name, needs to be changed to match the respective font-family name used in index.html. So in the instance of 'Roboto Light':

Before:

@font-face {
		font-family: 'Roboto';
		font-style: normal;
		font-weight: 300;
		font-display: swap;
		src: local('Roboto Light'), local('Roboto-Light'), url(https://fonts.gstatic.com/s/roboto/v20/KFOlCnqEu92Fr1MmSU5fChc4EsA.woff2) format('woff2');
		unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

After:

@font-face {
		font-family: 'Roboto Light';
		font-style: normal;
		font-weight: 300;
		font-display: swap;
		src: local('Roboto Light'), local('Roboto-Light'), url(https://fonts.gstatic.com/s/roboto/v20/KFOlCnqEu92Fr1MmSU5fChc4EsA.woff2) format('woff2');
		unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
  1. I link fonts.css in index.html (needs to be re-done every time the HTML5 project is built).
<link rel="stylesheet" href="css/fonts.css">
  1. In index.html, I delete any @font-face CSS rules (needs to be re-done every time the HTML5 project is built).

I tested this by uninstalling the Elsie fonts from my local PC, forcing it to use the web fonts, and it worked. Further confirmation was made when not making the manual changes to the font-family failed to load the Elsie font.