Some (maybe) helpful font size stuff! #223

Open
opened 2019-10-20 14:09:14 +00:00 by KilloZapit · 0 comments
KilloZapit commented 2019-10-20 14:09:14 +00:00 (Migrated from github.com)

Hi! I wanted to share this a while ago, but wasn't sure if this program was still being actively developed. But I decided I might as well! Anyway, while working on my own little RPG Maker VX Ace game, I have been making it with mkxp support in mind. I noticed that there were issues with font sizes and such (and I am pretty sure there still are), which sort of bugged me for a while but I actually found a kind of work around for it! I ended up writing a little ruby script:

# Allows setting the size of fonts using 'px' units 
# (kinda anyway, not sure if it's 100% accurate to how px units work)
# To do this set a font's size to a string with a number and px at the end like "18px".
# Also works with Font.default_size
# Should size diffrently shaped fonts to be about the same.
# Also should kinda fix mkxp sizing fonts in a wacky way.

class Font
  
  alias_method :set_size, :size=
  def size=(value)
    if value.is_a?(String)
      if value.downcase =~ /(\d+)\s*px/
        value = self.font_pixel_size($1.to_i)
      else
        value = value.to_i
      end
    end
    set_size(value)
  end
  
  def font_pixel_size(px)
    table = Font.font_size_table(self.name)
    key = table.keys.min_by{|x| (px-x).abs}
    return table[key]
  end
  
  class << self
    
    alias_method :set_default_size, :default_size=
    def default_size=(value)
      # Make a temp font and pass the size to it to figure out the proper size.
      tmpfnt = Font.new
      tmpfnt.size = value
      set_default_size(tmpfnt.size)
    end
  
    def font_size_table(name)
      if table = ((@size_table ||= {})[name])
        return table
      end
      table = {}
      i = 1
      # We need a bitmap for the .text_size method.
      tmpbitmap = Cache.empty_bitmap
      tmpbitmap.font = Font.new(name)
      loop do
        break if i > 100
        begin
          tmpbitmap.font.set_size(i)
        rescue
          i += 1
          next
        end
        # Pixel size of capital M, width or height what ever is lower
        key = [tmpbitmap.text_size('M').width, tmpbitmap.text_size('M').height].min
        unless table[key]
          #puts name.to_s + ': ' + key.to_s + ' = ' + i.to_s
          table[key] = i
        end
        i += 1
      end
      tmpbitmap.dispose
      @size_table[name] = table
    end
    
  end
  
end

It basically creates a hash table to compare font sizes with the actual pixel size. This might be a helpful tool for tracking down the possible factors making mkxp not render fonts exactly the same perhaps? It's not really a direct solution to the problem, but it might be a good way to more rigorously test how the numbers compare between the different versions of game.exe and mkxp. Might be more helpful to compare the width and height rather then whatever one is smaller like I do, not sure.

I doubt anyone really cares, but hey someone may find it helpful, either to debug mkxp or just to use in their own game, so why not post it here?

Edit: Thought I would double check but it looks to me like the font size in VX Ace at least is equal to the vertical height of the em box (approximated by the result of .text_size for the letter 'M') in pixels? Might depend on the font though. It may simply be that VX Ace just doesn't use point units for fonts and mkxp does.

Edit 2: But in mkxp, when I look at the width and height of the fonts in pixels, the comparable height for the equivalent width is muuuuch different on some fonts, even if they look the same to me... Curiouser and curiouser... How deep will this rabbit hole go?

Hi! I wanted to share this a while ago, but wasn't sure if this program was still being actively developed. But I decided I might as well! Anyway, while working on my own little RPG Maker VX Ace game, I have been making it with mkxp support in mind. I noticed that there were issues with font sizes and such (and I am pretty sure there still are), which sort of bugged me for a while but I actually found a kind of work around for it! I ended up writing a little ruby script: ``` # Allows setting the size of fonts using 'px' units # (kinda anyway, not sure if it's 100% accurate to how px units work) # To do this set a font's size to a string with a number and px at the end like "18px". # Also works with Font.default_size # Should size diffrently shaped fonts to be about the same. # Also should kinda fix mkxp sizing fonts in a wacky way. class Font alias_method :set_size, :size= def size=(value) if value.is_a?(String) if value.downcase =~ /(\d+)\s*px/ value = self.font_pixel_size($1.to_i) else value = value.to_i end end set_size(value) end def font_pixel_size(px) table = Font.font_size_table(self.name) key = table.keys.min_by{|x| (px-x).abs} return table[key] end class << self alias_method :set_default_size, :default_size= def default_size=(value) # Make a temp font and pass the size to it to figure out the proper size. tmpfnt = Font.new tmpfnt.size = value set_default_size(tmpfnt.size) end def font_size_table(name) if table = ((@size_table ||= {})[name]) return table end table = {} i = 1 # We need a bitmap for the .text_size method. tmpbitmap = Cache.empty_bitmap tmpbitmap.font = Font.new(name) loop do break if i > 100 begin tmpbitmap.font.set_size(i) rescue i += 1 next end # Pixel size of capital M, width or height what ever is lower key = [tmpbitmap.text_size('M').width, tmpbitmap.text_size('M').height].min unless table[key] #puts name.to_s + ': ' + key.to_s + ' = ' + i.to_s table[key] = i end i += 1 end tmpbitmap.dispose @size_table[name] = table end end end ``` It basically creates a hash table to compare font sizes with the actual pixel size. This might be a helpful tool for tracking down the possible factors making mkxp not render fonts exactly the same perhaps? It's not really a direct solution to the problem, but it might be a good way to more rigorously test how the numbers compare between the different versions of game.exe and mkxp. Might be more helpful to compare the width and height rather then whatever one is smaller like I do, not sure. I doubt anyone really cares, but hey someone may find it helpful, either to debug mkxp or just to use in their own game, so why not post it here? Edit: Thought I would double check but it looks to me like the font size in VX Ace at least is equal to the vertical height of the em box (approximated by the result of .text_size for the letter 'M') in pixels? Might depend on the font though. It may simply be that VX Ace just doesn't use point units for fonts and mkxp does. Edit 2: But in mkxp, when I look at the width and height of the fonts in pixels, the comparable height for the equivalent width is muuuuch different on some fonts, even if they look the same to me... Curiouser and curiouser... How deep will this rabbit hole go?
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: MapleShrine/mkxp#223
No description provided.