Yeah, it’s very solid and performs well.
I added preliminary support for kerning in my fork of the library. In my projects it works well, but I haven’t tested it yet with any of the fancy features available…
Yeah, it’s very solid and performs well.
I added preliminary support for kerning in my fork of the library. In my projects it works well, but I haven’t tested it yet with any of the fancy features available…
That looks great - I will review it to check it fits in with the design, but if you have done it the way I had planned to, which is fairly likely
then it should work fine and everything else should work pretty much automatically. (I haven’t looked yet, but I’m presuming you parsed the .fnt file to get kerning pairs out and modified the reformatText() method appropriately.
…but I’m presuming you parsed the .fnt file to get kerning pairs out and modified the reformatText() method…
Almost. Yes I parsed the fnt file to get the kerning data. But I modified the reformatLine() method.
I also added a new function BitmapString:applyKerning(flag) where flag is true/false. This is so that you can disable kerning on specific strings if needed (like scores/timers etc). Kerning is enabled by default as long as kerning data exists in the fnt file.
The way I implemented it was to create a global kerning table for the font, which is loaded into a property named kerningInfo.
To make things easier in the reformat method I included links for each character into the kerningInfo table (kerning property). It only links to the appropriate subtable for that specific character.
Hmm, I look forward to seeing kerning in action. Has this been merged yet?
Also, paulscottrobson, I noticed the rollout library doesn’t include any sort of onComplete functionality (important for a variety of reasons, like pages). That being said, the workaround is fairly easy; I just created an {onComplete} event and make sure to automatically append it to my strings.
(It almost works better than an actual onComplete call, as I can determine whether to call a page onComplete (i.e.: setup next page) or a text onComplete (setup window close)
can i use this with starter Corona SDK? I’m getting a few error when running the demo
Don’t know - what errors are you getting ?
I had forgotten ! Sorry - I’m away tomorrow for a couple of days but it will be first thing to do when I come back (after saying hi to Children, Wife, Cats etc. 
Richard9, quite happy to add that into the main_roll.lua if you want.
I’ll provide the code, but kind of trying to solve a bigger problem:
I just noticed that your method of setText overwrites the old text. Is there a way to append?
I’m trying to find a way to mimic the old method of text displays where the game pauses at the end of each “page” and then on button press, continues like a typewriter. I have the basics (display.newContainer will handle keeping the text within a window, and then I presumably just need to call a transition with each page break) But the trick here is that I either need an :append() action or I need to stall (but not stop) the bitmap rollout until an arbitrary time occurs (ex: touch event). But since rollout is handled with a while loop, adding an arbitrary variable will just end the loop, putting me back in the “need append” zone.
The standard Corona way to handle dynamic scale naming is to have a base-name and let the imageSuffix in config.lua decide which suffix to use. Instead of having a forced naming convention, I’ve modified the code somewhat so that it uses the imageSuffix extensions found in config.lua.
First I require(“config”) at the top of the module to get the imageSuffix table.
In the code below, I’ve made 3 modifications delimited by:
–>> modification (n) >>>>>>>>>>>>>>>
some code here
–<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
I’ve done some initial testing and it seems to work well.
require ("config") . . . function BitmapFont:loadFont(fontName) local options = { frames = {} } local spriteCount = 1 local imageFile = nil local charData = {} local source = io.lines(self:getFontFile(fontName)) self.padding = { 0,0,0,0 } for l in source do --\>\>\> modification 1 \>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\> local page = l:match('^%s\*page%s\*id%s\*=%s\*(%d+)%s\*file%s\*=%s\*%"(.\*)%"$') local fileName = fontName .. self.suffix .. ".png" --\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\< if page ~= nil then assert(page == "0","We do not support font files with page \> 0. If you have one contact the author") imageFile = BitmapFont.fontDirectory .. "/" .. fileName end if l:match("^%s\*char%sid") ~= nil then local x,y,w,h = l:match("x%s\*=%s\*(%d+)%s\*y%s\*=%s\*(%d+)%s\*width%s\*=%s\*(%d+)%s\*height%s\*=%s\*(%d+)%s\*") assert(h ~= nil,"Failure to read line in .fnt file, contact author") local optionsEntry = { x = x\*1, y = y\*1, width = w\*1, height = h\*1 } options.frames[spriteCount] = optionsEntry local charID,xOffset,yOffset,xAdvance = l:match("id%s\*=%s\*(%d+).\*xoffset%s\*=%s\*([%-%d]+).\*yoffset%s\*=%s\*([%-%d]+).\*xadvance%s\*=%s\*([%-%d]+)") assert(xAdvance ~= nil,"Failure to read line in .fnt file, contact author") local charInfo = { width = xAdvance\*1, xOffset = xOffset\*1, yOffset = yOffset\*1} charInfo.spriteID = spriteCount charInfo.frame = optionsEntry charInfo.height = optionsEntry.height assert(charData[charID] == nil,"Duplicate character code, contact author") charData[charID\*1] = charInfo spriteCount = spriteCount + 1 end if l:match("padding") ~= nil then self.padding[1],self.padding[2],self.padding[3],self.padding[4] = l:match("padding%s\*%=%s\*([%d+])%s\*%,%s\*([%d+])%s\*%,%s\*([%d+])%s\*%,%s\*([%d+])") assert(self.padding[4] ~= nil,"Bad padding parameter format") for i = 1,4 do self.padding[i] = self.padding[i] \* 1 end end end assert(imageFile ~= nil,"No image file in fnt file, contact the author") self.imageSheet = graphics.newImageSheet(imageFile,options) assert(self.imageSheet ~= nil,"Image file " .. imageFile .. "failed to load for fnt file ".. fontName) return charData end --//% Get font file name, scaling for display size and checking for @nx files. --// @fontFile [string] Base name of font file. May use @4x tags to force high res font --// @return [string] Path of font file. function BitmapFont:getFontFile(fontFile) --\>\> modification 2 \>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\> --// TODO: Work out scale, check if 4x, 3x 2x 1x exist and use them if they do. --// TODO: Explain in docs what it actually does. -- local scaleFactor = 1 / display.contentScaleX -- if fontFile:match("%@%d+x$") == nil then -- local deviceWidth = ( display.contentWidth - (display.screenOriginX \* 2) ) / -- display.contentScaleX -- scaleFactor = math.floor( deviceWidth / display.contentWidth ) -- scaleFactor = math.max(scaleFactor,1) -- while scaleFactor \> 1 and self:getFileNameScalar(fontFile,scaleFactor) == nil do -- scaleFactor = scaleFactor - 1 -- end -- end self.fontScalar = 1 / display.contentScaleX --\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\< return self:getFileNameScalar(fontFile,scaleFactor) end --//% Create a full file name for a font scaled by a particular amount (so 2 =\> @2x etc.) --// @fontFile [string] Base name of font file --// @fontScalar [number] Possible scalar size 2,3,4 etc. --// @return [string] Path of font file. function BitmapFont:getFileNameScalar(fontFile,fontScalar) --\>\> modification 3 \>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\>\> local suffix = "" local selectedScale = -1 for k, v in pairs(application.content.imageSuffix) do if (self.fontScalar \>= v) and (v \> selectedScale) then selectedScale = v suffix = k end end fontFile = fontFile .. suffix self.suffix = suffix --\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\< return system.pathForFile(BitmapFont.fontDirectory .. "/" .. fontFile .. ".fnt", system.ResourceDirectory) end
Thanks - it’s much appreciated - do you want to push that or shall I do it ?
I’m still testing it to see if there are any unwanted side-effects to my changes.
Did you see if my changes have broken something in your object logic or not?
I can do the push when I’m done. Do you want me to fork it and create a separate branch with a pull request?
I have reviewed Ingemar’s code and merged it into the main tree, so Kerning now works by default.
Richard 9 ; I think the best way to handle that is not to append it but to divide the text into chunks - do you mean on the same page or a new page ?
Dividing into chunks was my original thought, but what I’m trying to build is basically an 8-bit typewriter, so it would actually work like this, assuming a container that can display 3 lines of text at a time:
Print Line 1
Print Line 2
Print Line 3
Wait for container touch
Scroll “up” by one line. (Line 1 is now no longer visible within the container)
Print Line 4
Scroll up again
Print Line 5
Scroll up again
Print Line 6
3 more lines have printed, so wait for touch
The crucial things here are interrupting print based touch or appending text. (Actually, now that I think of it, old Dragon Quest games do this too; see this youtube)
Not sure if any upgrades have been done here since June, but I did notice that the github version fires a warning if you don’t have @2x/@4x files now?
Guess I need to dig in and find a way to disable that…(GL_NEAREST doesn’t require different size assets; it’s strictly optional and silently just does Corona scaling otherwise)
I have merged Ingemar’s changes to use config.lua to use imageSuffix - I added an or {} so that it still works if there isn’t an Image suffix. AFAICS the changes work fine.
I downloaded this today to play with it, so I have whatever is currently on github. I’m also using bmGlyph (can’t afford the other one right now) and I’m still seeing soft fonts. I output my font at 128 point which should be plenty big.
Do I have the latest that supports the @2x and @4x? Should I be outputting “Corona 2.0” or some other output type?
Rob
The latest version supports Corona’s dynamic scaling. The suffixes used for the imagesheet and fnt files are taken from whatever is put in config.lua’s imageSuffix entry.
I’m on Mac and have tested only with fnt files generated by GlyphDesigner. I haven’t tried bmGlyph. I’ll give it a try to see if I find any issues with it…
When you publish, you should either use “Cocos2d/BMFont” or “Corona” format.
The “Corona 2.0” format outputs a lua control-file instead of fnt which doesn’t work.
I just tested bmGlyph and it works as expected. (Although the trial is severely limited to 50px Arial only). I couldn’t see much difference between the files generated by bmGlyph and GlyphDesigner, but the limit of the bmGlyph-trial prevented me from doing a proper test.
Dynamic imagesheet selection is controlled by using imageSuffix in config.lua.
One thing to note is when you specify the fontSize in newBitmapText() it’s best specify the size in “base size” (the size without an image-suffix). Let’s say you have a font that you want to display at 50px base size and want to support @2x and @4x. You’ll publish 3 fonts (50px=base-size, 100px=@2x and 200px=@4x) and set up your imageSuffix entries in config.lua accordingly.
In your call to display.newBitmaptext() you should use fontsize=50. You can use a smaller value to downscale the font a bit, but too much downscaling doesn’t look good. Larger values can also be used, but will upscale and produce fuzzy text.
The basic changes Ingemar made was to use the image suffix table in the config file rather than my method which was to physically search for their existence and pick the best. If there isn’t an imageSuffix entry then it will default to 1x.
Can you let me have the font/.fnt files etc. I have had this problem reported with bmGlyph by Richard9 but I haven’t been able to reproduce it, the only ‘low quality’ font output has been when the font graphic itself was low quality (e.g. small font) and was being scaled up, so it is pretty much doing exactly what it should , as you say 128 point should be fine at almost any zoom level.
I do have bmGlyph and glyphDesigner (both companies let me have a copy, which was very generous of them)
There is a status list at the bottom of the main font manager.lua file , at the time of writing the last entry is “Stopped crashing when no imageSuffix in config dated 5/7/14.” - this is the only change I made to Ingemar’s work, if you didn’t have imageSuffix in it failed. Bear in mind I’m in the UK so times are slightly out.