Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fonts: allow font instancing with different properties #996

Open
ghost opened this issue Dec 1, 2019 · 14 comments
Open

Fonts: allow font instancing with different properties #996

ghost opened this issue Dec 1, 2019 · 14 comments
Labels
context: fonts type: enhancement a suggestion or necessity to have something improved what: editor related to the game editor what: engine related to the game engine

Comments

@ghost
Copy link

ghost commented Dec 1, 2019

Fonts have attached properties that may be changed without altering the source font data itself. For instance: point size / scaling, or line spacing. But currently AGS requires you to create a new copy of a font file if you want to use it with different setting. While fonts files aren't large, this is still unnecessary copying of source data.

My proposal is to change this and treat AGS fonts as "instances" that may refer to same source file, and only separated in memory (even sharing same font data in memory when possible).

@ivan-mogilko ivan-mogilko added type: enhancement a suggestion or necessity to have something improved context: fonts what: editor related to the game editor what: engine related to the game engine labels Dec 1, 2019
@ericoporto
Copy link
Member

Maybe fontDef or fontConfig class where you add this Settings and pass along with the font itself to be consumed by the functions that draws text and objects (eg. Labels) .

@ghost
Copy link
Author

ghost commented Dec 1, 2019

Maybe fontDef or fontConfig class where you add this Settings and pass along with the font itself to be consumed by the functions that draws text and objects (eg. Labels) .

Um, no, there's no need for this, in API "font" number would mean font instance, and for end-user it will work as before. What changes is only how engine and editor handle source data internally. Support shared data instead of multiplying it between instances.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented May 23, 2023

I'd like to propose slightly different approach to this. Originally this ticket was suggesting "instancing fonts with the same source file". I want to suggest other way around: fonts freely link to the source file.

In other words: we have Font entity which is not strictly linked to the actual glyph data. Instead it has a "source file" property, which may be filled or not. Or changed at runtime.

This will allow to link multiple Fonts to the same asset, but also to not link a Font to any asset. The latter may make sense if you expect this font to be drawn by a plugin, or even have glyph data be created by a script.

What will this change immediately in engine and editor?

The engine should provide a dummy font renderer that does nothing, in case no source is linked.

The editor should change a way a font is "imported". When creating a new font it will be "empty". The user will have an option to link a source file to it, or unlink from a file.
But then there's a question on how to keep importing font files convenient. Either there has to be an explicit command for that, or "font files" should have their own node in a project tree.

@ericoporto
Copy link
Member

In the project tree, the font we have could have two subnodes, one for files and the other for the instances.

One thing that I want to ask is, does it make sense an instance be linked to two or more font files in an order? In web development, it's possible to pass a sequence of font family, this is usually done either for a multilingual web page or when using special fonts with symbols along with a different regular font for the letters and numbers, the way it works with web things, which are usually UTF-8, is if a symbol is not available in a font, it goes to the next one to fetch the symbol. The problem is this significantly complicates render code. So, I don't think we need/should support this, but I just wanted to mention because this was a thing I saw being repeatedly mentioned on SDL_TTF related questions - which also doesn't support this.

@ivan-mogilko
Copy link
Contributor

One thing that I want to ask is, does it make sense an instance be linked to two or more font files in an order? In web development, it's possible to pass a sequence of font family, this is usually done either for a multilingual web page or when using special fonts with symbols along with a different regular font for the letters and numbers, the way it works with web things, which are usually UTF-8, is if a symbol is not available in a font, it goes to the next one to fetch the symbol. The problem is this significantly complicates render code. So, I don't think we need/should support this, but I just wanted to mention because this was a thing I saw being repeatedly mentioned on SDL_TTF related questions - which also doesn't support this.

In web design the problem AFAIK is that your webpage will be using fonts installed on user's system, something that you cannot control. This is why it makes sense to make a list of substitutes.

In game dev you are in full control of which fonts are packaged, you're the one responsible for the assets. If you support a language that cannot use one font, then you may just switch the font when the language is selected (or switch the font's source, in the new proposed system). So this auto fallback mechanism does not make much sense.

What could make sense is to automate font or font source switching along with the language, so that you won't have to script this by hand, but idk if that's ever an issue.
Also for translation file to have an option that switches particular Font's "source" to another font file, which is distributed along with tra, for example.

@messengerbag
Copy link

I would like to second ghost's original request to be able to set e.g. point size and line spacing dynamically, rather than having to define separate Fonts at design-time. It's not clear to me that @ivan-mogilko's alternative proposal allows this—at least not without implementing the key elements in a plugin.

It would also be nice to be able to import multiple variations of a TrueType font (such as different weights, italics, etc.) "as one"; though this is less essential, and probably implies a bigger change to the AGS font model.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented May 29, 2023

I would like to second ghost's original request to be able to set e.g. point size and line spacing dynamically, rather than having to define separate Fonts at design-time.

The "ghost" is me, it's my old account that was deleted, then restored. Unfortunately a big number of my older posts were not connected back to the restored account.

It's not clear to me that @ivan-mogilko's alternative proposal allows this—at least not without implementing the key elements in a plugin.

There's no difference in that regard, you may implement dynamic change of point size and linespacing even now, within the current font system. I'm not sure how plugins are related to this.

@messengerbag
Copy link

(I thought the original post was by former AGSer Ghost, though possibly the timing doesn't fit.)

you may implement dynamic change of point size and linespacing even now

How? AFAIK you need to choose the point size when you import the font at design time. Is this a 4.0 thing?

@messengerbag
Copy link

If instead of "Fonts" you had two types of entities, static FontFiles defined in the project and FontStyles that could be dynamically instantiated and modified with data about things like point size, line spacing, outline, etc., and linked to specific FontFiles, wouldn't that meet both of your proposals (and ericoporto's too)?

(To jump topic a little, one use-case for @ericoporto's suggestion of fallback fonts is if the renderer comes across a character/codepoint that isn't present in the primary font.)

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented May 29, 2023

you may implement dynamic change of point size and linespacing even now

How? AFAIK you need to choose the point size when you import the font at design time. Is this a 4.0 thing?

I mean that you may implement a script function in the engine that changes a point size, and recreates the internal data. This may be done even now, without any additional modifications to the font system.

If instead of "Fonts" you had two types of entities, static FontFiles defined in the project and FontStyles that could be dynamically instantiated and modified with data about things like point size, line spacing, outline, etc., and linked to specific FontFiles, wouldn't that meet both of your proposals (and ericoporto's too)?

I guess, except my proposal was to keep both entities in the project too, as that might be easier for some, and also let see the result in the Editor.

@messengerbag
Copy link

I mean that you may implement a script function in the engine that changes a point size, and recreates the internal data. This may be done even now, without any additional modifications to the font system.

Right, that's more or less the original proposal, which is what I seconded. I was thrown because you introduced the second version as an alternative approach, but without mentioning any way it would actually allow you to do this (e.g. change the point size), instead focusing on the possibility of not having it linked to a specific font file. But I now suppose that you considered it to be implicit that this "Font" entity (equivalent to what I call FontStyle) would allow you to set those properties dynamically.

I guess, except my proposal was to keep both entities in the project too

Yes, I agree that this would be useful, and necessary in order to preview text in the editor. Are there any examples already in 4.0 of entities that can be created both in the editor and dynamically? Otherwise I suppose you could always create a bunch of them as placeholders (as long as the properties can be edited dynamically), but it gets tedious.

@ericoporto
Copy link
Member

Just a note, setting properties dynamically may not be interesting if you want to cache the glyphs and benefit from it, as they need to be regenerated for each point size or other property change - there is a glyph cache in alfont and I believe SDL_ttf has it too.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented May 29, 2023

Are there any examples already in 4.0 of entities that can be created both in the editor and dynamically?

I think only sprites. They are separated on "static" sprites and dynamic sprites.
In the past we discussed changing AGS to have everything created same way (whether loaded from game files or ordered in script), and let delete anything at runtime, but we are currently not close to that.

Just a note, setting properties dynamically may not be interesting if you want to cache the glyphs and benefit from it, as they need to be regenerated for each point size or other property change

That depends on how often do you change the properties, and for which purpose; and it's the same problem as with anything else that requires reloading or regenerating data. If this is done only on language change, that may be tolerated. A warning to users in documentation may be enough to help avoid misuse.

@ericoporto
Copy link
Member

ericoporto commented Sep 4, 2023

Just a note, setting properties dynamically may not be interesting if you want to cache the glyphs

Other approach to speed up is not only cache the glyph but use a font atlas - this means like pushing a font atlas to the GPU, and then rendering from it. Of course there are the ranges of characters that one wants to do this. And about font size, there are SDF fonts, which, although not perfectly, may enable font atlas with variable font size.

This comment is less about implementing this and more about not blocking being able to implement this in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
context: fonts type: enhancement a suggestion or necessity to have something improved what: editor related to the game editor what: engine related to the game engine
Projects
None yet
Development

No branches or pull requests

3 participants