1. Anders Ruud
  2. love

Issues

Issue #190 resolved

Multiline Imagefonts, and fixed-width imagefonts

textmode
created an issue

imagefont should have support for multi-line font images, and for fixed-width fonts (as an option/optimisation).

Apart from anything else, this would help cover existing font images out there (such as: [[http://df.magmawiki.com/index.php/File:CGA8x8thick.png|CGA8x8thick.png]] ).

It would also make it easier to create or preview imagefonts since they needn't be one long strip anymore.

Comments (16)

  1. Boolsheet

    ImageFonts could now also be upgraded to UTF-8.
    I think they currently have a hard coded limit of 256 characters. And it's a bit akward to use ISO-8859-1 encoding for the glyph string and UTF-8 when printing.

  2. hahawoo

    Other than UTF-8 characters, the linked font image has a background color which would need to be made transparent, as well as multiple lines and fixed width characters.

    So newImageFont might have to look something like...

    love.graphics.newImageFont(image, glyphs, width, height, transparent)

    Where width and height are a number of pixels of each character, and transparent is a list or a table. But if it isn't a fixed width font and it has multiple lines, then width might have to be able to be false or something too. And maybe height be optionally specified by a pixel line too?

    This makes ImageFonts waaay more complicated. I reckon it would be much more lovely if lovers preprocessed font images, which could be in any number of formats, into the standard, simple LÖVE format.

    Here's an example which loads CGA8x8thick.png as an image font, at least with some of the ASCII characters. This could be slow if done at run time, so it would probably make sense to save the image to a file beforehand, in this case using ImageData's encode method.

    function love.load()
        imagefont = newImageFont('CGA8x8thick.png', '????????????????????????????????? !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\[^_\'abcdefghijklmnopqrstuvwxyz{|}~', 8, 8, {255, 0, 255})
        love.graphics.setFont(imagefont)
    end
    
    function love.draw()
        love.graphics.print('This is a test!', 0, 0)
    end
    
    function newImageFont(path, glyphs, width, height, transparent)
    
        if not width and not height then
            return love.graphics.newImageFont(path, glyphs)
        end
    
        local imagedata = love.image.newImageData(path)
    
        if transparent then
            imagedata:mapPixel(function(x, y, r, g, b, a)
                if r == transparent[1] and g == transparent[2] and b == transparent[3] then
                    return 0, 0, 0, 0
                else
                    return r, g, b, a
                end
            end)
        end
    
        if not height then
            height = imagedata:getHeight()
        end
    
        if not width then
            width = imagedata:getWidth()
        end
    
        local columns = imagedata:getWidth() / width
        local rows = imagedata:getHeight() / height
        local glyphcount = columns * rows
    
        local newfontimage = love.image.newImageData(glyphcount * (width + 1), height)
    
        local separator = {}
    
        if transparent then
            separator = transparent
        else
            separator = {255, 0, 255}
        end
    
        for y = 1, rows do
            for x = 1, columns do
                newfontimage:paste(imagedata, ((y-1)*columns+x)*(width+1)+1, 0, (x - 1) * width, (y - 1) * height, width, height)
                for i = 0, height-1 do
                    local separator_x = ((y-1)*columns+x-1)*(width+1)
                    newfontimage:setPixel(separator_x, i, separator[1], separator[2], separator[3], 255)
                end
            end
        end
    
        return love.graphics.newImageFont(newfontimage, glyphs)
    end
    
  3. Alex Szpakowski

    I was thinking of having support for the Angel Code font format - many existing font generators and game frameworks already support it, so it's probably as standardized a format for bitmap/image fonts as we'll find (although I suspect most things only support the very useful parts of the format.)

    Here's a simple example of the format, as exported by a Distance Field font generator tool I used:

      info face="Bitstream Vera Serif"
      chars count=95
      char id=32    x=250   y=181   width=4     height=4     xoffset=-1.500    yoffset=1.500     xadvance=10.500      page=0  chnl=0
      char id=33    x=109   y=141   width=8     height=28    xoffset=3.000     yoffset=25.625    xadvance=13.313      page=0  chnl=0
      char id=34    x=136   y=0     width=12    height=12    xoffset=1.750     yoffset=25.563    xadvance=15.188      page=0  chnl=0
      char id=35    x=228   y=197   width=26    height=27    xoffset=1.063     yoffset=25.250    xadvance=27.625      page=0  chnl=0
      char id=36    x=90    y=141   width=19    height=34    xoffset=1.313     yoffset=26.625    xadvance=21.000      page=0  chnl=0
      char id=37    x=32    y=56    width=31    height=29    xoffset=0.313     yoffset=26.063    xadvance=31.313      page=0  chnl=0
      char id=38    x=90    y=56    width=29    height=29    xoffset=0.875     yoffset=26.063    xadvance=29.375      page=0  chnl=0
      ... etc
    
  4. hahawoo

    Is there anything in that which couldn't be converted to LÖVE's current image font format though, other than kerning? And if kerning for image fonts was supported, wouldn't it be better to have a more general way of specifying it than that format?

  5. Alex Szpakowski

    It's not a fixed-width format, it has many of the same properties that truetype fonts do, etc.

    This format is more general than a custom one, since it can be used outside of LÖVE, and tools outside of LÖVE already export to it. I'm not saying it's the only format ImageFonts should support, just that it makes a lot of sense going forward.

  6. hahawoo

    It sounds like a fine idea to me! :) I meant like, general as in, if you were creating an ImageFont with the current format, could that support kerning too? Or maybe it could just totally replace the current format? Or if you wanted kerning you'd just use that format? I just imagined like, a table of kerning information you could pass to a LÖVE function. I dunno. :P

    Edit: Woah, looking at that format it seems there's more stuff than just kerning... I, uh... I don't really know much about fonts. :D

  7. hahawoo

    Actually supporting that format would go together nicely with combining newFont and newImageFont (#650), because making something from this format is kind of in between. :D It would just be like making a Font from a TTF then.

    And uh, giving kerning (and other crazy font stuff) support to standard LÖVE image fonts would be really confusing and probably not used. :P

  8. hryx

    Alex Szpakowski Wow, that font format looks great. Big fat +1 from me.

    My biggest complaints with current ImageFonts are:

    • Having to put all glyphs on one line and draw in separator pixels makes for a huge pain in the ass during the design process.
    • LÖVE draws the ImageFont with the extra separation pixel as space; this immediately prevents me from using ImageFonts when I want pixel-perfect and grid-aligned printing (think NES sprites as glyphs).

    Are there reservations about supporting the Angel Code format? (By the way, their font generator appears to have gone open source as of April 12, 2014.)

  9. Alex Szpakowski

    Are there reservations about supporting the Angel Code format?

    I certainly don't have any! It would also mean signed distance field fonts could be used with love.graphics.print (and a custom shader), which is great.

    What I'm not too sure about is how the existing ImageFont format should evolve (if it should be kept around at all.) I don't really use monospace bitmap fonts, so I don't have the best idea about what a useful and easy-to-use format for that should have.

    By the way, their font generator appears to have gone open source as of April 12, 2014.

    Nice find!

  10. hryx

    I certainly don't have any!

    Badical!

    What I'm not too sure about is how the existing ImageFont format should evolve (if it should be kept around at all.)

    I think current ImageFonts are a good solution for smaller projects, and they're easy to jump into (good for rapid development and game jams). They become a pain for larger glyph sets, but at that point a more powerful format/editor would make sense.

    The only thing I think really needs to change about them is the fact that the separation pixels are added into the final spacing. To me this is unexpected behavior and should be treated as a bug. Without this problem, I'd actually use ImageFonts.

    With that issue in mind, I don't see why not to keep ImageFonts around as they are for the quick 'n' dirty, at least for now.

  11. Andrew Anderson

    The only thing I think really needs to change about [ImageFonts] is the fact that the separation pixels are added into the final spacing. To me this is unexpected behavior and should be treated as a bug.

    I concur; it is currently not possible to have the characters rendered so that they touch each other with no gap, which is a problem for monospace fonts such as the 8x8 CGA font previously mentioned.

  12. Alex Szpakowski

    Added support for loading BMFont bitmap font files with love.graphics.newFont (see issue #190.) Some esoteric BMFont features are not supported.

    Moved the Font module Lua wrapper code out of the freetype implementation folder.

    → <<cset 95da8e65d9f5>>

  13. Log in to comment