Another Plugin: SpriteFont Renderer. Native Bitmap Fonts.

Started by Calin Leafshade, Fri 02/09/2011 21:30:53

Previous topic - Next topic

Calin Leafshade

I dont think so. It seems to only be related to TextWindow GUIs. Font rendering on other GUIs works fine.

Crimson Wizard

#61
Hmm, well, at the moment I can tell only that the surface bitmap IS 32-bit. But the drawing algorythm there is a bit complicated...

E: I believe it is related strictly to magic pink (transparent color). I've already saw similar problems when blending translucent buttons over gui with magic pink areas.

EE: I must be mistaken. Although the surface seem to be 32-bit, the alpha channel is definitely lost at some point. More simple way to see this is to assign translucent sprite as Text Window background.
This might be due some drawing operation used.


EEE: Ok, the last guess was right, it simply discarded alpha channel at the point of creating a renderer-compatible bitmap.
Quick-fix won't do, because simply forcing alpha there will make text window borders dissapear :).
Need more careful approach.

san.daniele

Quote from: Calin Leafshade on Sun 28/04/2013 19:15:28
It seems to only be related to TextWindow GUIs. Font rendering on other GUIs works fine.

It's even more specific. Using SetTextWindowGUI has no problems with rendering the text in said TextGUI. It's just the dialog options that don't work.

p.s. does it make sense to discuss this further in here? As this is apparently only remotely related to the plugin.

Crimson Wizard

Quote from: san.daniele on Sun 28/04/2013 20:19:57
p.s. does it make sense to discuss this further in here? As this is apparently only remotely related to the plugin.
Right, sorry. Calin made the issue post here: http://www.adventuregamestudio.co.uk/forums/index.php?issue=405.0

Knox

(Sorry for re-opening)

Everything worked great with this plugin up until now: I was fiddling with it today (since looking into how to maybe make my own) and I'm not sure but perhaps I found a possible bug?

If my GUI label is set to "Inventory" from within the editor at the start of the game, but then I change it via script later after a button is pressed to something else ("Closeup", for example),
Code: ags
lblInventoryTitle.Text = "Closeup";


...the new title text gets clipped after the 1st character (All I see is "C" as the GUI's new title).
To debug, I tested this using a standard font, and the title switches without that clipping.

What would I have to do to get around that?
--All that is necessary for evil to triumph is for good men to do nothing.

Calin Leafshade

Could you try making the label a little taller.

I think it might not be cutting it off but rather forcing new lines. See if the rest of the text is just on a new line.

Knox

#66
Ok so I tried making the label taller (even really tall values like 400, to test)...still everything but the 1st character gets truncated. I'll continue to do more tests to see if I can pinpoint it.

Ok so I found the prob: my font sheet only has capital letters, so yeah, I'm retarded, lol! :tongue:
--All that is necessary for evil to triumph is for good men to do nothing.

Daniel Eakins

#67
Okay dumb question time: where do I put the PNG file that SpriteFont.exe produces? :confused:

My game_start function looks like this and obviously it's missing something to work but I don't know what:
Code: ags
function game_start() 
{
	SetGlyph(0, 32, 8, 8, 3, 14);
	SetGlyph(0, 33, 19, 8, 1, 14);
	SetGlyph(0, 34, 28, 8, 3, 14);
	SetGlyph(0, 35, 39, 8, 5, 14);
	SetGlyph(0, 36, 52, 8, 5, 14);
	SetGlyph(0, 37, 65, 8, 7, 14);
	SetGlyph(0, 38, 80, 8, 4, 14);
	SetGlyph(0, 39, 92, 8, 1, 14);
	SetGlyph(0, 40, 101, 8, 2, 14);
	SetGlyph(0, 41, 111, 8, 2, 14);
	SetGlyph(0, 42, 121, 8, 5, 14);
	SetGlyph(0, 43, 134, 8, 5, 14);
	SetGlyph(0, 44, 147, 8, 2, 14);
	SetGlyph(0, 45, 157, 8, 3, 14);
	SetGlyph(0, 46, 168, 8, 1, 14);
	SetGlyph(0, 47, 177, 8, 5, 14);
	SetGlyph(0, 48, 8, 30, 4, 14);
	SetGlyph(0, 49, 20, 30, 2, 14);
	SetGlyph(0, 50, 30, 30, 4, 14);
	SetGlyph(0, 51, 42, 30, 4, 14);
	SetGlyph(0, 52, 54, 30, 4, 14);
	SetGlyph(0, 53, 66, 30, 4, 14);
	SetGlyph(0, 54, 78, 30, 4, 14);
	SetGlyph(0, 55, 90, 30, 4, 14);
	SetGlyph(0, 56, 102, 30, 4, 14);
	SetGlyph(0, 57, 114, 30, 4, 14);
	SetGlyph(0, 58, 126, 30, 1, 14);
	SetGlyph(0, 59, 135, 30, 2, 14);
	SetGlyph(0, 60, 145, 30, 3, 14);
	SetGlyph(0, 61, 156, 30, 3, 14);
	SetGlyph(0, 62, 167, 30, 3, 14);
	SetGlyph(0, 63, 178, 30, 4, 14);
	SetGlyph(0, 64, 8, 52, 8, 14);
	SetGlyph(0, 65, 24, 52, 4, 14);
	SetGlyph(0, 66, 36, 52, 4, 14);
	SetGlyph(0, 67, 48, 52, 4, 14);
	SetGlyph(0, 68, 60, 52, 4, 14);
	SetGlyph(0, 69, 72, 52, 4, 14);
	SetGlyph(0, 70, 84, 52, 4, 14);
	SetGlyph(0, 71, 96, 52, 4, 14);
	SetGlyph(0, 72, 108, 52, 4, 14);
	SetGlyph(0, 73, 120, 52, 1, 14);
	SetGlyph(0, 74, 129, 52, 3, 14);
	SetGlyph(0, 75, 140, 52, 4, 14);
	SetGlyph(0, 76, 152, 52, 3, 14);
	SetGlyph(0, 77, 163, 52, 5, 14);
	SetGlyph(0, 78, 176, 52, 5, 14);
	SetGlyph(0, 79, 189, 52, 4, 14);
	SetGlyph(0, 80, 8, 74, 4, 14);
	SetGlyph(0, 81, 20, 74, 4, 14);
	SetGlyph(0, 82, 32, 74, 4, 14);
	SetGlyph(0, 83, 44, 74, 4, 14);
	SetGlyph(0, 84, 56, 74, 5, 14);
	SetGlyph(0, 85, 69, 74, 4, 14);
	SetGlyph(0, 86, 81, 74, 5, 14);
	SetGlyph(0, 87, 94, 74, 5, 14);
	SetGlyph(0, 88, 107, 74, 4, 14);
	SetGlyph(0, 89, 119, 74, 5, 14);
	SetGlyph(0, 90, 132, 74, 4, 14);
	SetGlyph(0, 91, 144, 74, 2, 14);
	SetGlyph(0, 92, 154, 74, 5, 14);
	SetGlyph(0, 93, 167, 74, 2, 14);
	SetGlyph(0, 94, 177, 74, 3, 14);
	SetGlyph(0, 95, 188, 74, 3, 14);
	SetGlyph(0, 96, 8, 96, 2, 14);
	SetGlyph(0, 97, 18, 96, 4, 14);
	SetGlyph(0, 98, 30, 96, 4, 14);
	SetGlyph(0, 99, 42, 96, 4, 14);
	SetGlyph(0, 100, 54, 96, 4, 14);
	SetGlyph(0, 101, 66, 96, 4, 14);
	SetGlyph(0, 102, 78, 96, 3, 14);
	SetGlyph(0, 103, 89, 96, 4, 14);
	SetGlyph(0, 104, 101, 96, 4, 14);
	SetGlyph(0, 105, 113, 96, 1, 14);
	SetGlyph(0, 106, 122, 96, 2, 14);
	SetGlyph(0, 107, 132, 96, 4, 14);
	SetGlyph(0, 108, 144, 96, 1, 14);
	SetGlyph(0, 109, 153, 96, 7, 14);
	SetGlyph(0, 110, 168, 96, 4, 14);
	SetGlyph(0, 111, 180, 96, 4, 14);
	SetGlyph(0, 112, 8, 118, 4, 14);
	SetGlyph(0, 113, 20, 118, 4, 14);
	SetGlyph(0, 114, 32, 118, 3, 14);
	SetGlyph(0, 115, 43, 118, 4, 14);
	SetGlyph(0, 116, 55, 118, 3, 14);
	SetGlyph(0, 117, 66, 118, 4, 14);
	SetGlyph(0, 118, 78, 118, 4, 14);
	SetGlyph(0, 119, 90, 118, 5, 14);
	SetGlyph(0, 120, 103, 118, 4, 14);
	SetGlyph(0, 121, 115, 118, 4, 14);
	SetGlyph(0, 122, 127, 118, 3, 14);
	SetGlyph(0, 123, 138, 118, 3, 14);
	SetGlyph(0, 124, 149, 118, 1, 14);
	SetGlyph(0, 125, 158, 118, 3, 14);
	SetGlyph(0, 126, 169, 118, 4, 14);
	SetGlyph(0, 161, 181, 118, 1, 14);
	SetGlyph(0, 162, 8, 140, 4, 14);
	SetGlyph(0, 163, 20, 140, 4, 14);
	SetGlyph(0, 164, 32, 140, 5, 14);
	SetGlyph(0, 165, 45, 140, 5, 14);
	SetGlyph(0, 166, 58, 140, 1, 14);
	SetGlyph(0, 167, 67, 140, 4, 14);
	SetGlyph(0, 168, 79, 140, 3, 14);
	SetGlyph(0, 169, 90, 140, 8, 14);
	SetGlyph(0, 170, 106, 140, 3, 14);
	SetGlyph(0, 171, 117, 140, 6, 14);
	SetGlyph(0, 172, 131, 140, 3, 14);
	SetGlyph(0, 173, 142, 140, 3, 14);
	SetGlyph(0, 174, 153, 140, 8, 14);
	SetGlyph(0, 175, 169, 140, 3, 14);
	SetGlyph(0, 176, 180, 140, 3, 14);
	SetGlyph(0, 177, 191, 140, 5, 14);
	SetGlyph(0, 178, 8, 162, 3, 14);
	SetGlyph(0, 179, 19, 162, 3, 14);
	SetGlyph(0, 180, 30, 162, 2, 14);
	SetGlyph(0, 181, 40, 162, 4, 14);
	SetGlyph(0, 182, 52, 162, 5, 14);
	SetGlyph(0, 183, 65, 162, 1, 14);
	SetGlyph(0, 184, 74, 162, 2, 14);
	SetGlyph(0, 185, 84, 162, 2, 14);
	SetGlyph(0, 186, 94, 162, 3, 14);
	SetGlyph(0, 187, 105, 162, 6, 14);
	SetGlyph(0, 188, 119, 162, 9, 14);
	SetGlyph(0, 189, 136, 162, 10, 14);
	SetGlyph(0, 190, 154, 162, 10, 14);
	SetGlyph(0, 191, 172, 162, 4, 14);
	SetGlyph(0, 192, 184, 162, 4, 14);
	SetGlyph(0, 193, 196, 162, 4, 14);
	SetGlyph(0, 194, 8, 184, 4, 14);
	SetGlyph(0, 195, 20, 184, 4, 14);
	SetGlyph(0, 196, 32, 184, 4, 14);
	SetGlyph(0, 197, 44, 184, 4, 14);
	SetGlyph(0, 198, 56, 184, 7, 14);
	SetGlyph(0, 199, 71, 184, 4, 14);
	SetGlyph(0, 200, 83, 184, 4, 14);
	SetGlyph(0, 201, 95, 184, 4, 14);
	SetGlyph(0, 202, 107, 184, 4, 14);
	SetGlyph(0, 203, 119, 184, 4, 14);
	SetGlyph(0, 204, 131, 184, 2, 14);
	SetGlyph(0, 205, 141, 184, 2, 14);
	SetGlyph(0, 206, 151, 184, 3, 14);
	SetGlyph(0, 207, 162, 184, 3, 14);
	SetGlyph(0, 208, 173, 184, 5, 14);
	SetGlyph(0, 209, 186, 184, 5, 14);
	SetGlyph(0, 210, 8, 206, 4, 14);
	SetGlyph(0, 211, 20, 206, 4, 14);
	SetGlyph(0, 212, 32, 206, 4, 14);
	SetGlyph(0, 213, 44, 206, 4, 14);
	SetGlyph(0, 214, 56, 206, 4, 14);
	SetGlyph(0, 215, 68, 206, 5, 14);
	SetGlyph(0, 216, 81, 206, 5, 14);
	SetGlyph(0, 217, 94, 206, 4, 14);
	SetGlyph(0, 218, 106, 206, 4, 14);
	SetGlyph(0, 219, 118, 206, 4, 14);
	SetGlyph(0, 220, 130, 206, 4, 14);
	SetGlyph(0, 221, 142, 206, 5, 14);
	SetGlyph(0, 222, 155, 206, 4, 14);
	SetGlyph(0, 223, 167, 206, 4, 14);
	SetGlyph(0, 224, 179, 206, 4, 14);
	SetGlyph(0, 225, 191, 206, 4, 14);
	SetGlyph(0, 226, 8, 228, 4, 14);
	SetGlyph(0, 227, 20, 228, 4, 14);
	SetGlyph(0, 228, 32, 228, 4, 14);
	SetGlyph(0, 229, 44, 228, 4, 14);
	SetGlyph(0, 230, 56, 228, 7, 14);
	SetGlyph(0, 231, 71, 228, 4, 14);
	SetGlyph(0, 232, 83, 228, 4, 14);
	SetGlyph(0, 233, 95, 228, 4, 14);
	SetGlyph(0, 234, 107, 228, 4, 14);
	SetGlyph(0, 235, 119, 228, 4, 14);
	SetGlyph(0, 236, 131, 228, 2, 14);
	SetGlyph(0, 237, 141, 228, 2, 14);
	SetGlyph(0, 238, 151, 228, 3, 14);
	SetGlyph(0, 239, 162, 228, 3, 14);
	SetGlyph(0, 240, 173, 228, 4, 14);
	SetGlyph(0, 241, 185, 228, 4, 14);
	SetGlyph(0, 242, 8, 250, 4, 14);
	SetGlyph(0, 243, 20, 250, 4, 14);
	SetGlyph(0, 244, 32, 250, 4, 14);
	SetGlyph(0, 245, 44, 250, 4, 14);
	SetGlyph(0, 246, 56, 250, 4, 14);
	SetGlyph(0, 247, 68, 250, 5, 14);
	SetGlyph(0, 248, 81, 250, 5, 14);
	SetGlyph(0, 249, 94, 250, 4, 14);
	SetGlyph(0, 250, 106, 250, 4, 14);
	SetGlyph(0, 251, 118, 250, 4, 14);
	SetGlyph(0, 252, 130, 250, 4, 14);
	SetGlyph(0, 253, 142, 250, 4, 14);
	SetGlyph(0, 254, 154, 250, 4, 14);
	SetGlyph(0, 255, 166, 250, 4, 14);
}
We all have our time machines, don't we?

Calin Leafshade

You load it as a sprite like any other sprite and then pass the sprite number to the SetGlyph function as the first parameter.

Daniel Eakins

Oh right! :shocked: Thanks, it works now. This plugin is perfect for translations and support for 256-character fonts.
We all have our time machines, don't we?

JSH

I must say this is an awesome plugin, pretty much the only way to get a flawless result in AGS regarding fonts. Great work Calin, gave you a spot in the credits :)

Igor Hardy


Monsieur OUXX

More detailed guidelines, courtesy of Daniel Eakins :

Quote
1) Once you have downloaded Calin's plugin, you have to launch "SpriteFont.exe". This is program will create two files: "Texture.png" and "Metrics.xml". Make sure you select the ranges of characters that you want to include in your future font (in the cart icon):

2) In AGS, activate AGSSpriteFont in the Plugins icon in the right panel.
3) Import "Texture.png" as a sprite.
4) In function game_start(), type a SetVariableSpriteFont(AAA, BBB) command (where AAA is the font slot you want to use, such as 0, and BBB is the number of the sprite you have just imported).
5) Launch "AGSSpriteFontGen.exe" and open "Metrics.xml" in it to get some AGS coding. Paste that coding in function game_start() after the SetVariableSpriteFont command.

That's all, that should work. The best thing about this plugin is that you can open "Texture.png" in any image editor if you want to edit the font pixel by pixel. Also check Calin's first post in his thread to understand what the coding you get from "AGSSpriteFontGen.exe" means if you want to also edit that.



Also, for all those interested in multilingual fonts, this page could come handy : http://www.adventuregamestudio.co.uk/wiki/Fonts
 

is a cool guy.

How do I apply a tint to a sprite font? I read in a previous reply that tinting was implemented, but changing the font colour of my labels doesn't seem to do anything. Am I doing it wrong?

Edit: I also ran into the new line bug when not all of my characters were defined. Here's a suggestion: have SetVariableSpriteFont take a height parameter to use as the default height when some characters are used but not defined. It would make building and testing incomplete fonts a bit easier. That said, variable heights seem to inconsistently alter the line height anyway, so maybe it'd be an idea to remove that parameter from SetGlyph.

Calin Leafshade

Tinting should be automatic and follow the label color. Tinting is multiplicative not additive so white = your tint color, black = black.

As for the line height, yea youre right that it probably doesnt handle it very well. I'll consider changing for the next version (which will be OOP)

Gurok

Thanks Calin! The white/black thing sent me in the right direction. Importantly, I found you must also use the file from page 3 of this thread. The file in the original post has not been updated to support tinting.
[img]http://7d4iqnx.gif;rWRLUuw.gi

Gurok

I have a 9 pixel high font with 1 pixel of spacing. In GUI windows, the spacing looks correct. In Text windows, however, the vertical spacing appears to be ignored. GetTextHeight also returns 18 for two lines of text. I'm thinking there's some bug with sprite fonts and text windows, but it's also possible I've overlooked something. Any ideas?

[img]http://7d4iqnx.gif;rWRLUuw.gi

Calin Leafshade

The rendering should be same either way from the plugins point of view. I will investigate.

Gurok

Any luck on that text v/s GUI line spacing issue, Calin?
[img]http://7d4iqnx.gif;rWRLUuw.gi

Gurok

I have worked out what this is, Calin.

From line 229 of graphics_mode.cpp, labels use this value for font height:

usetup.textheight = wgetfontheight(0) + 1;

And regular fonts in text window GUIs use this value for font height (display.cpp, line 94):

texthit = wgetfontheight(usingfont);

I am not sure what the best course of action is here. Breaking font height handling in labels would probably break legacy code.

The ideal would be for both to use wgetfontheight(n) + line_spacing, but that would require some kind of switch between legacy<-->rational mode.

For now, I might have to stick to single line descriptions in GUIs and just add 1 to the overall font height.
[img]http://7d4iqnx.gif;rWRLUuw.gi

SMF spam blocked by CleanTalk