Looking for feedback/suggestions on my free bitmap font library (bit like TextCandy ...)

They can be up to a point. It should work as normal.

What doesn’t happen , at the moment, is the clearing up bit. If you access the view group it should work like any other Corona display object, but the object itself isn’t a display object, it’s a class which manipulates display objects with a common group.

I have some ideas about how to improve the situation so it can respond appropriately if it is removed by (say) being part of a group which is removed. According to the SDK docs it sets the view groups metatable to nil if it is removed, so it should be possible in that case to detect that and remove the object references and so on. 

I will give it some thought.

L8R: If you create a text string and do str:getView():removeSelf() it crashes, which isn’t a surprise, but something I need to fix.

Okay that was probably not a sensible thing to do, but I am concerned at composer’s garbage collection (which doesn’t seem to work properly) and also the display.remove() which may be related. It would appear that nesting groups doesn’t clean up properly - the bitmapstring is a group of bitmaps, which in Composer ends up inserted into the scenes own group, if it garbage collects it apparently doesn’t do anything to the group or the contents… am awaiting some clarification on this problem.

For those that are using this library, opengameart.com has a great collection of bitmap fonts that would work well.

http://opengameart.org/content/bitmap-font-pack

Do you know if this is a common format for bitmap fonts ? Could do it one of two ways ; could modify the library to read them (it is expecting FNT/PNG files as in Glyph Designer) or simply write code to generate the FNT file to match ? 

@paul, I haven’t used your library (definitely going to; it looks superb) but I figured those fonts would work out well. The .zip file does have all fonts as PNG files. Should I be looking for a specific bit sizes? Let me know and I’ll modify my post. Thanks!

No, I’ll have a tinker, probably Tuesday sometime, busy day tomorrow :slight_smile: and come up with some sort of easy solution for converting these font files into bitmap fonts. Not difficult, but the problem is they are all different layouts and so on, and the font manager basically needs to know where the characters for each font are. Most of those look to be straight ASCII and either horizontal or vertical fixed sizes, but there are other bitmap fonts in OpenClipArt which are slightly different.

Just glancing at the font files, the only “easy” way to map them (since they lack .tbl or .fon) is to:

  1. calculate if it’s a horizontal or vertical font using file extents

  2. use a manual arg to determine character size (there are a bunch of non-square ones in there)

  3. Assume it’s a direct key map and write a sequence mapper (00=A, 1A=a, and so on)

To be honest though some of the fonts clearly don’t follow a standard sequence. The safest, most reliable way to accept these fonts is either insist on .fon/.tbl or insist on a string map argument (ex: loadFont(file.png, “ABCDEFabcdef2421”)) That way, character 1 would be A, character 7 would be ‘a’, and so on…)

Looks like I got the waters all muddy… sorry about that folks. I have a tendency to leap before I look!

Just for information ; thinking about what Richard and others said I am completely reengineering it. However, this is a  minimal change reengineering, not a complete rewrite with different calls !

The Font thing suffers a bit because it’s the first Corona thing I did of any consequence :slight_smile:

However it will be pretty much identical, in fact slightly easier. If anyone is using the old one it will be pretty much the same as far as possible. (which is most of it) - it will work the same way, do the same things etc. but be cleaner and more robust.

The main differences are ; this is a lot more robust and well constructed, but also the object is now a display group sub class, so it fits much better into Corona. It’s a view group so it will behave like one (except that anchorChildren will not work if you animate because the enclosing rectangle will cause it to jerk about a lot !)

It allows stuff like this - I will put display.newBitmapFont() back and hopefully I can make anchorX, anchorY and text (the most problematic) work as properties rather than methods (so you can do bms.text = “Hello world !”) - this partly depends on how I can wire it into Corona :slight_smile:

This is actually now working, below :slight_smile:

bms = fm.BitmapString:new("demofont",100) -- will change to display.newBitmapText() bms:setText("Hello world\nAgain.\nLine 3") -- hopefully bms.text = bms.x = 160 bms.y = 240 bms.xScale = 0.5 bms.yScale = 0.5 bms.rotation = 10

Hey PSR,

So I’m taking a closer look at the old code, and a few things puzzle me:

  1. Are you doing auto-linebreaks? (I saw “if code == 10 or code == 13 then”)

  2. How are you interpreting control codes? (i.e.: colour tint)

I’m tempted to go with your font library but to be honest I need a much more extensible control code system (I have to support things like {shake}, {fast}, {slow} and {icon}. My basic implementation uses a string processor to record code instructions and then return a clean string, so I’m curious how your method works. (I admit I have trouble seeing through the unicode implementation that may be obscuring the method)

EDIT: I can provide my processor code; but mostly interested in your approach because as it is I’m not sure our approaches are compatible?

Yes ; it does line breaks by having \r or \n (13 or 10) in the code. The new branch allows you to control the justification as well.

Much clearer too ; the previous one suffers from being experimental and expanded - the newer one is much more robust, and it also decorates a group to get its functionality, so it behaves almost exactly as a group does (the one difference is that it has a runtime listener to do the animation if you turn the animation on).

The control system is only for tinting (e.g. {red} is red {1,0,0} is also red. I’m a bit puzzled by the {shake} {fast} {slow} thing - do you mean you want to be able to specify these things purely in text for the whole thing or that  you want different effects and speeds at different points in the string ?

e.g.

This {shake}{fast} shakes {off} this {wobble}{slow} wobbles {off}

This is a bit more complicated, not much but a bit.  Bit like extending the tints so you could change them in code. 

Really depends how much flexibility you want, writing something so you could do

{shake}this shakes  

and the whole thing shakes via some sort of scheme like

BitmapString:addInlineCommand("shake",function(bitmapString) bitmapString:setModifier(\<some such\>) end)

is much easier but this would apply shake to the whole thing, it would be a way of putting API calls into the string.

TBH I didn’t perceive it as for anything much more than some pretty text displays for scores, HUDs, title pages, high score tables and so on. Bit like the old Amiga demos. I do sometimes think the functionality is a bit excessive anyway, it can do some eye-exploding things :slight_smile:

The other thing would be to subclass the BitmapString;setText() method so that it extracted the various requirements and write a modifier that worked on that data.

Basically - there is a group containing the bitmap characters - this is mirrored in classes for the strings and characters. The basic implementation just allows ordinary text, any size, static, basic tinting. But the modifiers allow you to butcher the scaling/position/rotating/tinting of each character on the fly

I like the ease of use and the system (so far) seems to do what it says it will do.

Great work!

Cheers.

  • Not really aware of the use of \r , and typically \n just line breaks where you want it, so wasn’t sure what the 13/10 statement meant. Word count per line? Character code?
     
  • {fast}, {slow}, {mid} are speed presets. When I wrote the old typer() library on the code repository, the idea was eventually that you could change the speed at which words or characters print out, rather than just applying a speed to the entire string. Useful for both RPGs and narrative adventure games (ex: Phoenix Wright)
     
  • {shake} would call a (seperated) screen shake function. Useful for moments where someone shouts or something ridiculous happens. Abused quite often in narrative adventures.
     
  • {icon} calls ({item}, {weapon}, etc.) would just call special characters or images that take the space of a single font character. 

Anyway, what I’m trying to do is understand where your code interprets these control codes and records or acts upon them. ie: in my instruction recorder function, I use string.gsub to search out {} placements, record them and their position, and then return the cleaned string.

When the text is set (setText() mostly) it parses out anything in between {} (it is possible to change these delimiters) and tries to convert it to a named colour or a r,g,b value - {red} or {1,0,0.5}.

I can see a fairly simple way of doing it. If it comes across {xxxx} - where x is alphanumeric or a comma -

  1. Call self:extensionCommand(xxxx) (used for commands)

  2. Call self:extensionImage(xxxx) if the above returns nil, if this returns a display object use this as a ‘font character’.

  3. if *that* returns nil, look to see if it is a known colour or a numeric RGB value, and if it is tint accordingly.

  4. Cause an error if that fails.

What do you think ? Could just have a dummy extensionCommand() and extensionImage() which could be overridden.

(I must see if the class system works. The ‘problem’ is that the BitmapString is not technically a class, it is an object decorated with the BitmapString methods. I think it will work if you subclass it :slight_smile: )

I guess…your code structure is completely alien to me, so it’s hard to say?

My structure worked like this:

-- Use a Lua table to define control codes local codes = {] codes[1] = { code="red", mode="color", details={1,0,1} } codes[2] = { code="fast", mode="speed", details={ speed=50 } } -- Expose this somewhere coder-friendly

-- Use a converter function to process the string local function convertString( str ) -- use string.gsub to return all instances of {} and start/end position -- use an offset to count where that point will be after the code is removed -- store those instances in an instruction table -- at the end string.gsub returns the cleaned string. -- this is all done in \<10 lines, actually more chars spent talking about it... return new\_str, instructions end

Finally, whenever you start displaying each character of the string, consult the instruction table to see if anything should be applied.  Actions (functions) are assigned to the same functions as the ‘mode’ would indicate. (self.color, self.shake, etc.)

It sounds like in your OOP style, you’re instead:

  1. calling a function to register (add) a command, if it’s special

  2. using the special case “extensionImage” for image characters

  3. falling back on assuming an RGB color.

It’s not bad, and certainly would work for your setup, but I’ll admit it seems a little special-case focused?

It’s not a dissimilar idea. As I start displaying, or refreshing each character of the string (it’s continually refreshed to animate) the system asks the modifier class/function, “what do you want me to do with this line ?” along with a pile of other information. The text modifiers “wobble” and so on, are just classes/functions that do standard things stored in a library.

There’s really two separate issues. The system uses images as font bitmaps already, but it is about having alternatives to that so you can place any arbitrary image in the structure instead of requiring it from the Font. The BitmapFont has a factory method which creates images on demand. I just need to generalise the Factory method out a bit. (All these comments refer to the reengineered v2)

Then there’s the other stuff ; the library is about manipulating and animating text fonts - this it can do - this modifier reveals the text a bit at a time (and if you put other images in there, it will do the same thing) - as time elapses it reveals more and more characters and the characters alpha makes them become visible. 

bms:setModifier(function(modifier,cPos,infoTable) local pos = math.floor(infoTable.elapsed / 2) modifier.alpha = 0 if infoTable.totalIndex \< math.floor(pos/100) then modifier.alpha = 1 elseif infoTable.totalIndex == math.floor(pos/100) then modifier.alpha = pos % 100 / 100 end end)

You can easily twiddle with this without changing the core so, for example to make it rotate the currently waiting character just put in.

modifier.rotation = pos % 100 \* 360 / 100

Executing arbitrary code probably belongs separately. Something like {shake} probably needs to be separated out, because it’s nothing to do with the Text per se, it’s the whole screen that shakes. Stuff like {fast} and {slow} is really just a synonym for different modifiers (or instances of a modifier class) so putting {fast} in the text does much the same as

myString:setModifier(RollOutTextModifier:new(3))

and to change the speed just change the constructor parameter.

Cool. I guess I’d need to see some example documentation understand that last line there - :setModifier() makes sense, but the call inside just appears to be gobbledygook to me. My code is pretty corona specific because I don’t have any sort of C background. 

The point of having {fast} and {shake} is that there may be times in text where you need to change speed or perform an action while the text is printing. So rather than just apply speed to everything, just make this word appear fast. Only shake when somebody screams, etc. So maybe that’s what you’re saying?

The animation stuff is interesting, though I only need to just turn on characters as time progresses (.isVisible or alpha=1, whichever), so I suspect I would have to dumb that function down a bit.

Regarding images, I think the safest way might be to just have some kind of method where people can reference in their own display calls. For example, my projects use a custom imageSheet manager, so I can already, say, call display.visSprite(“dude”) and have it automatically find the right frame from the right sheet without any other trouble. Just an idea, though.

(You can take all of my blabbing as me hoping I can use this instead of my own control code structure…really would rather not have to build a unicode framework! ;) )

Anyway if everything you’ve said is mostly possible I’ll take another look at your latest code.

myString:setModifier(RollOutTextModifier:new(3))

Creates a new RollOutTextModifier object with a speed of 3. It’s the same as new RollOutTextModifier(3) in Java, except that lua doesn’t support this syntax. It is then used as the modifier for myString, 

Having given it some thought, the library is not about actions that take place in mid strings - the alternate images fit the model, but the shaking and speed changing doesn’t.

The best way to do it , IMO, is to have the alternate images - icons or whatever - as part of the library but implement the roll out text with events as a modifier class which has an event queue which it fires as time goes on.

So basically the text would be scanned for things like {fast} and {slow} and the like at the start, these would be pulled out of the text and added to the event queue “when the 10th character appears, do this”. As the animation goes on, revealing the text, this would call code to process these events accordingly, thus you could arbitrarily execute any code you like as the text appears.

This way the core purpose of the library, rendering animated bitmaps stays the same, but it can do what you want.

I will do a mock up of the sort of thing I have in mind (the event queue) so you can see what I mean. I’ll let you know when it’s done, probably be tomorrow.

Your plan (to pre-queue commands) sounds identical to my system, except that I use gsub to search for anything in {} rather than specific things. To save time, here’s what it looks like. You could easily adapt this to your structure with a few modifications, I think…

function convert(str) local steps = {} local offset = 0 local function iterator( start, code, finish ) steps[#steps+1] = { code=code, start=start-offset } offset = offset + (finish-start) return "" end local result = string.gsub( str, "()(%b{})()", iterator) return result, steps end

There’s a demo of the pre-queue version on https://github.com/autismuk/Font-Manager/tree/revamped-version - it doesn’t have the icon characters (yet). It allows speed changes of the ‘roll out’ - and does a shake event, even though it only actually prints “Shake” to the console :slight_smile: