Random error with Sfonts script....

Started by PrinceEndymion88, February 08, 2015, 01:26:02 pm

Previous topic - Next topic

PrinceEndymion88

I'm using this script in my project. Sometimes it works good and other times I get the following error:
Script 'Sfonts' line 147: RGSSError occured.

failed to create bitmap.


I don't know why... Is there something wrong into the script?

Sfonts:
#=============================================================================
# * SFonts
#=============================================================================
# Trickster
# Version 1.0
# 12.19.07
#=============================================================================
# Introduction
#  - This script adds SFont support for rmxp. An sfont is a image file with
#    characters already drawn onto it. The top row of pixels in this image shows
#    where the characters are and where the breaks are.
# Setting up images
#  - The top left hand pixel (0, 0) is the skip color and tells if a column
#    of pixels is empty or contain data
#  - Images should be placed in Graphics/SFonts
#  - For more reference see the example image Arial_Text
# To Use
#  - You can use this script in one of two ways
#    - 1) Set <Bitmap>.sfont to an SFont object then call <Bitmap>.draw_text
#    - 2) Call <SFont>.render(<String>) and then blt it to a Bitmap object
# Documentation
#  - SFont.new(<String/Bitmap>, <Array>, <Integer/String>)
#  - Where the first parameter is a filename (in Graphics/SFonts) or a Bitmap
#     object containing the Font data
#  - the second parameter is an Array of all of the characters in order in the
#    file the default is specified in @@glyphs below you
#  - the last parameter is either the width that should be used for the space
#    character or the character whose width you want to use for the space
#    character the default is " which is the width of the " character if "
#    character is not in the glyph then the height of the bitmap will be used
# Credits
#  - John Croisant for the original code for Rubygame which I used as a base for
#    this script
#  - Adam Bedore for the example sfont image more of his sfont work is given
#    here - http://www.zlurp.com/irq/download.html
# Websites
#  - Official SFont Page with sample fonts - http://www.linux-games.com/sfont
#  - SFont generator utility - http://www.nostatic.org/sfont
#  - SFont generator script for GIMP by Roger Feese
#       http://www.nostatic.org/sfont/render-sfont22.scm
#=============================================================================

module RPG
module Cache
  #--------------------------------------------------------------------------
  # * SFont Load
  #--------------------------------------------------------------------------
  def self.sfont(file)
    self.load_bitmap("Graphics/SFonts/", file)
  end
end
end

class SFont
  #--------------------------------------------------------------------------
  # * Class Variables
  #--------------------------------------------------------------------------
  @@glyphs = [
    "!",'"',"#","$","%","&","'","(",")","*","+",",","-",".","/","0",
    "1","2","3","4","5","6","7","8","9",":",";","<","=",">","?","@",
    "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P",
    "Q","R","S","T","U","V","W","X","Y","Z","[","\\","]","^","_","`",
    "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p",
    "q","r","s","t","u","v","w","x","y","z","{","|","}","~","∞",
    ]
  #--------------------------------------------------------------------------
  # * Get Glyphs
  #--------------------------------------------------------------------------
  def SFont.glyphs
    return @@glyphs
  end
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(file, glyphs = @@glyphs, space = '"')
    if file.is_a?(String)
      bitmap = RPG::Cache.sfont(file)
    elsif file.is_a?(Bitmap)
      bitmap = file
    else
      raise(ArgumentError, "File Must be a String or Bitmap")
    end
   
    @height = bitmap.height
    @skip = bitmap.get_pixel(0, 0)
    @glyphs = {}
   
    x = 2
    glyphs.each {|char| x = load_glyph(bitmap, char, x)}
   
    unless glyphs.include?(' ')
      if space.is_a?(Numeric)
        space = space.to_i
      elsif space.is_a?(String)
        if glyphs.include?(space)
          space = @glyphs[space].width
        elsif !@glyphs['"'].nil?
          space = @glyphs['"'].width
        else
          space = bitmap.height
        end
      else
        raise(ArgumentError, "Space must be either a String or Numeric")
      end
      @glyphs[" "] = Bitmap.new(space, @height)
    end
    @glyphs.default = @glyphs[" "]
  end
  #--------------------------------------------------------------------------
  # * Text Size
  #--------------------------------------------------------------------------
  def text_size(text)
    width = 0
    text.each_byte {|byte| width += @glyphs["%c" % byte].width}
    return width
  end
  #--------------------------------------------------------------------------
  # * Render
  #--------------------------------------------------------------------------
  def render(text)
    width = text_size(text)
    bitmap = Bitmap.new(width, @height)
    x = 0
    text.each_byte do |byte|
      glyph = @glyphs["%c" % byte]
      bitmap.blt(x, 0, glyph, glyph.rect)
      x += glyph.width
    end
    return bitmap
  end
  #--------------------------------------------------------------------------
  # * Private: Load glyph
  #--------------------------------------------------------------------------
  private
  def load_glyph(bitmap, char, xi)
    while bitmap.get_pixel(xi, 0) == @skip && xi < bitmap.width
      xi += 1
    end
    return -1 if xi >= bitmap.width
    xf = xi
    while bitmap.get_pixel(xf, 0) != @skip && xf < bitmap.width
      xf += 1
    end
    return -1 if xf >= bitmap.width
   
    rect = Rect.new(xi, 0, xf - xi, bitmap.height)
    @glyphs[char] = Bitmap.new(xf - xi, bitmap.height)
    @glyphs[char].blt(0, 0, bitmap, rect)
   
    return xf+1
  end
end


Bitmap:
class Rect
  #--------------------------------------------------------------------------
  # * Strict Conversion to Array
  #--------------------------------------------------------------------------
  def to_ary
    return x, y, width, height
  end
  alias bounds to_ary
end

 
class Bitmap
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :sfont
  #--------------------------------------------------------------------------
  # * Draw Text
  #--------------------------------------------------------------------------
  alias_method :trick_sfont_bitmap_draw_text, :draw_text
  def draw_text(*args)
    if self.sfont == nil
      trick_sfont_bitmap_draw_text(*args)
    else
      align = 0
      case args.size
      when 2
        rect, text = args
        x, y, width, height = rect
      when 3
        rect, text, align = args
        x, y, width, height = rect
      when 5
        x, y, width, height, text = args
      when 6
        x, y, width, height, text, align = args
      end
      bitmap = sfont.render(text)
      if align == 1
        x += (width - bitmap.width) / 2
      elsif align == 2
        x += width - bitmap.width
      end
      y += (height - bitmap.height) / 2
      blt(x, y, bitmap, bitmap.rect)
    end
  end
end


I've putted it above main and below Scene_debug...

KK20

Post a demo. It's impossible to tell what the error is when it's graphics related.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

PrinceEndymion88

yes, this file contain the script and my font resource in Graphics/Sfonts

http://uploaded.net/file/di5x336k

KK20

February 08, 2015, 02:33:30 pm #3 Last Edit: February 08, 2015, 02:45:46 pm by KK20
Website is complaining that it's "exhausted" and wants me to buy premium. If you want me to get to work as soon as possible on this, choose a different service please.

EDIT
So I got the download. I don't know what I should be doing in the demo. Menu opens up fine with the different font.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

PrinceEndymion88

February 08, 2015, 02:54:45 pm #4 Last Edit: February 08, 2015, 03:06:02 pm by PrinceEndymion88
Yes but sometimes I have the error... is really random, and when it happens the game crash! I don't know why... cause sometimes the game runs perfectly

KK20

February 08, 2015, 03:57:09 pm #5 Last Edit: February 08, 2015, 03:58:47 pm by KK20
Here's a thing to try:
Put F0's Console Output script into your project.
Spoiler: ShowHide


if $DEBUG || $TEST
 # Create a console object and redirect standard output to it.
 Win32API.new('kernel32', 'AllocConsole', 'V', 'L').call
 $stdout.reopen('CONOUT$')
 # Find the game title.
 ini = Win32API.new('kernel32', 'GetPrivateProfileString','PPPPLP', 'L')
 title = "\0" * 256
 ini.call('Game', 'Title', '', title, 256, '.\\Game.ini')
 title.delete!("\0")
 # Set the game window as the top-most window.
 hwnd = Win32API.new('user32', 'FindWindowA', 'PP', 'L').call('RGSS Player', title)  
 Win32API.new('user32', 'SetForegroundWindow', 'L', 'L').call(hwnd)
 # Set the title of the console debug window'
 Win32API.new('kernel32','SetConsoleTitleA','P','S').call("#{title} :  Debug Console")
 # Draw the header, displaying current time.
#  puts ('=' * 75, Time.now, '=' * 75, "\n")
end

alias zer0_console_inspect puts
def puts(*args)
 inspected = args.collect {|arg| arg.inspect }
 zer0_console_inspect(*inspected)
end


On the line just before your error, add:

   rect = Rect.new(xi, 0, xf - xi, bitmap.height)
   puts [char, xf, xi, bitmap.height] #<==================== ADD THIS LINE IN HERE
   @glyphs[char] = Bitmap.new(xf - xi, bitmap.height)

When the game errors, look at the last thing the console window shows you and report back here.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

PrinceEndymion88

Done. I have this when I start the game (I don't know if it can help):


and this when the error happens:

KK20

It seems like this is a hardware problem. Having a lot of bitmaps saved in memory can cause a "failure to create" error when trying to make another bitmap. I think it has to do with available memory your computer has. You can run Task Manager and see for yourself.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

PrinceEndymion88

Ah okay!Actually I'm on an old pc with 1GB of ram... but I remember that I get the error even with my laptop (4gb of ram)! Maybe the best thing is to use classic font, no?

Blizzard

That particular error can happen if the width and/or height is 0 or less. (There is an error in the Bitmap class and only a height of exactly 0 will trigger the condition, but that's not so important in this case.) Try printing out the width and height of the bitmap before trying to create it.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

KK20

February 08, 2015, 04:39:56 pm #10 Last Edit: February 08, 2015, 04:42:43 pm by KK20
He already did. There's nothing wrong with that as shown in the screenshot.

Quote from: PrinceEndymion88 on February 08, 2015, 04:26:39 pm
Ah okay!Actually I'm on an old pc with 1GB of ram... but I remember that I get the error even with my laptop (4gb of ram)! Maybe the best thing is to use classic font, no?

Maybe check again that you don't have a lot of background processes eating up your laptop's memory. I don't really see how this script uses a lot of memory as the bitmap objects created are pretty small. Like I said for myself, it works fine (16 GB of RAM though :P).

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Blizzard

Then keep your Task Manager open and watch if it explodes while the game runs.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

PrinceEndymion88

Maybe this happens because it has to convert long text strings to bitmap... I don't know I'll test again with taskmanager! Otherwise I'll use classic font... thanks guys! =)