Advertisement
modern_algebra

Special Codes Formatter

Apr 25th, 2011
1,163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 18.28 KB | None | 0 0
  1. #==============================================================================
  2. #    Special Codes Formatter (Addon for Paragraph Formatter 2.0)
  3. #    Version: 1.0
  4. #    Author: modern algebra (rmrk.net)
  5. #    Date: September 15, 2009
  6. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7. #  Description:
  8. #
  9. #    This is a formatter and artist combo that interprets and accounts for
  10. #   various special codes:
  11. #
  12. #      \n - line break to next paragraph (Note the single \, NOT \\)
  13. #      \\v[x] - Shows the value located in the variable x
  14. #      \\n[x] - Shows the name of the Actor with ID x
  15. #      \\c[x] - Changes the colour of the text to x. x can be 0 - 31
  16. #      \\c[#hex] - Changes the colour of text to the hex value
  17. #      \\ - \
  18. #      \\pid[x] - Shows Actor ID of Party Member in position X (0-3)
  19. #      \\nc[x]- Shows the name of class with ID x
  20. #      \\np[x]- Shows the name of the Party Member with index x
  21. #      \\ne[x]- Shows the name of Event with ID x on the map
  22. #      \\nm[x]- Shows the name of Monster with ID x
  23. #      \\ni[x]- Shows the name of Item with ID x
  24. #      \\nw[x]- Shows the name of Weapon with ID x
  25. #      \\na[x]- Shows the name of Armour with ID x
  26. #      \\pi[x]- Shows the price of Item with ID x
  27. #      \\pw[x]- Shows the price of Weapon with ID x
  28. #      \\pa[x]- Shows the price of Armour with ID x
  29. #      \\iicon[x] - Shows the Icon of Item with ID x
  30. #      \\wicon[x] - Shows the Icon of Weapon with ID x
  31. #      \\aicon[x] - Shows the Icon of Armour with ID x
  32. #      \\icon[x] - Shows the Icon with ID x
  33. #      \\vocab[value] - prints vocab for that item type. Suitable values are:
  34. #                      level, level_a, hp, hp_a, mp, mp_a, atk, def, spi,
  35. #                      agi, weapon, armor1, armor2, armor3, armor4, weapon1,
  36. #                      weapon2, attack, skill, guard, item, equip, status, save,
  37. #                      game_end, fight, escape, new_game, shutdown, to_title,
  38. #                      continue, cancel, gold
  39. #      \\f[key] - Show Filter phrase attached to key
  40. #      \\b - Bold ON
  41. #      \/b - Bold OFF
  42. #      \\i - Italic ON
  43. #      \/i - Italic OFF
  44. #      \\u - Underline ON
  45. #      \/u - Underline OFF
  46. #      \\s - Shadow ON
  47. #      \/s - Shadow OFF
  48. #      \\hl[x] - Highlights with color x. \\hl toggles off
  49. #      \\ac[x]- Shows class of actor with ID x
  50. #      \\a...[x] - Shows the ... of Actor X. ... can be any of the following:
  51. #                 hp, maxhp, mp, maxmp, atk, def, spi, agi, exp_s, next_exp_s,
  52. #                 next_rest_exp_s, level, weapon_id, armor1_id, armor2_id,
  53. #                 armor3_id, armor4_id - and any other methods from Game_Actor.
  54. #      \\c - Centres text
  55. #      \\r - Sets right alignment to text
  56. #
  57. #  It otherwise functions the same as the default Formatter and Artist combo.
  58. # The names of the classes are:
  59. #
  60. #    Formatter_SpecialCodes
  61. #    Artist_SpecialCodes
  62. #==============================================================================
  63.  
  64. module Paragrapher
  65.   #============================================================================
  66.   # ** FILTERS
  67.   #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  68.   #  FILTERS allows you to set a filter and replace any \F[x] code with it's
  69.   # corresponding Entry in the Hash. Leave the FILTERS = {} line alone and
  70.   # below it, you can set all of the codes you will want to be able to put
  71.   # as an argument in the \F code.
  72.   #============================================================================
  73.   FILTERS = {}
  74.   FILTERS['PF3'] = '\c[1]Paragraph Formatter\c[0], Version 2.0: Formatter_SpecialCodes'
  75.   FILTERS[0] = 'Numbered filters work too'
  76.   #============================================================================
  77.   # ** Formatter 3
  78.   #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  79.   #  This class converts a string into a formatted text object, but also
  80.   # recognizes special message codes.
  81.   #============================================================================
  82.  
  83.   class Formatter_SpecialCodes < Formatter
  84.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  85.     # * Format
  86.     #    string : the string to convert into paragraphs
  87.     #    specs  : the specification, either maximum width or a bitmap
  88.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  89.     def format (string, specs)
  90.       string = convert_special_characters (string)
  91.       @code_argument = false
  92.       @line_width = 0
  93.       @word_width = 0
  94.       @word_letter_count = 0
  95.       @line_letter_count = 0
  96.       # Run Original Method
  97.       return super (string, specs)
  98.     end
  99.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  100.     # * Format Character
  101.     #    i : index of character to format, or the character
  102.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  103.     def format_character (i)
  104.       character = @string[i, 1]
  105.       if args_codes.include? (character)
  106.         extract_code (character)
  107.         @code_argument = true
  108.       elsif @code_argument
  109.         @code_argument = false if character == ">"
  110.       elsif no_args_codes.include? (character)
  111.         extract_code (character)
  112.       elsif character == " "
  113.         char_width = @format_text.bitmap.text_size (character).width
  114.         if @line_width + char_width + @word_width > @max_width
  115.           if @line_width == 0 # Really long word!
  116.             @last_word = i
  117.             @line_width = @word_width
  118.           end
  119.           next_line (@last_word)
  120.         else
  121.           @line_width += char_width
  122.           @line_letter_count += 1
  123.         end
  124.         @line_width += @word_width
  125.         @line_letter_count += @word_letter_count
  126.         @word_width = 0
  127.         @word_letter_count = 0
  128.         @last_word = i
  129.       elsif character == "\n" # Line break
  130.         char_width = @format_text.bitmap.text_size (" ").width
  131.         next_line (@last_word) if @line_width + char_width + @word_width > @max_width
  132.         @line_width += @word_width
  133.         @line_letter_count += @word_letter_count
  134.         next_line (i)
  135.         # Add in \n independent of system
  136.         @format_text.lines[-1].push (character)
  137.         @format_text.blank_width[-1] = 0
  138.         @word_width = 0
  139.         @last_word = i
  140.       else # Regular Character
  141.         @word_width += @format_text.bitmap.text_size(character).width
  142.         @word_letter_count += 1
  143.         if i == @string.size - 1
  144.           next_line (@last_word) if @line_width + @word_width > @max_width
  145.         end
  146.       end
  147.     end
  148.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  149.     # * Proceed to Next Line
  150.     #    last_word : the index of the beginning of the previous word
  151.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  152.     def next_line (last_word)
  153.       line = @string[@line_break, last_word - @line_break]
  154.       # Adds current line to f.lines
  155.       @format_text.lines.push ( line.scan (/./) )
  156.       # Calculates the blank space left to cover in the line
  157.       line_blank = @max_width - @line_width
  158.       @format_text.blank_width.push (line_blank.to_f / (@line_letter_count.to_f) )
  159.       # Keeps track of the position in the array of each line
  160.       @line_break = last_word + 1
  161.       @line_width = 0
  162.       @line_letter_count = 0
  163.     end
  164.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  165.     # * Convert Special Characters
  166.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  167.     def convert_special_characters (text = @string)
  168.       return "" if text == nil
  169.       text = perform_substitution (text)
  170.       # Get substitutions
  171.       text.gsub! (/\\C\[(\d+)\]/i)          { "\x01<#{$1.to_i}>" } # Palette Color
  172.       text.gsub! (/\\C\[#([\dABCDEF]+)\]/i) { "\x01<##{$1.to_s}>" } # Hex Color  
  173.       text.gsub! (/\\IIC?O?N?\[(\d+)\]/i) { $1.to_i > 0 ? "\x02<#{$data_items[$1.to_i].icon_index}>" : ""} # Item Icon
  174.       text.gsub! (/\\WIC?O?N?\[(\d+)\]/i) { $1.to_i > 0 ? "\x02<#{$data_weapons[$1.to_i].icon_index}>" : ""} # Weapon Icon
  175.       text.gsub! (/\\AIC?O?N?\[(\d+)\]/i) { $1.to_i > 0 ? "\x02<#{$data_armors[$1.to_i].icon_index}>" : ""} # Armor Icon
  176.       text.gsub! (/\\IC?O?N?\[(\d+)\]/i)  { "\x02<#{$1.to_s}>" } # Icon
  177.       text.gsub! (/\\B/i) { "\x03" }                      # Bold ON
  178.       text.gsub! (/\\I/i) { "\x04" }                      # Italic ON
  179.       text.gsub! (/\\S/i) { "\x05" }                      # Shadow ON
  180.       text.gsub! (/\\U/i) { "\x06" }                      # Underline ON
  181.       text.gsub! (/\/B/i) { "\x07" }                      # Bold OFF
  182.       text.gsub! (/\/S/i) { "\x09" }                      # Shadow OFF
  183.       text.gsub! (/\/I/i) { "\x08" }                      # Italic OFF
  184.       text.gsub! (/\/U/i) { "\x10" }                      # Underline OFF
  185.       text.gsub! (/\\HL\[(-*\d+)\]/i) { "\x11<#{$1.to_s}>" }   # HighLight
  186.       text.gsub! (/\\HL/i)          { "\x11<-1>" }  
  187.       text.gsub! (/\\C/i)        { "\x12<1>" }          # Align Centre
  188.       text.gsub! (/\\CENTRE/i)   { "\x12<1>" }          # Align Centre  
  189.       text.gsub! (/\\RI?G?H?T?/i)   { "\x12<2>" }          # Align Right
  190.       return text
  191.     end
  192.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  193.     # * Perform Substitution
  194.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  195.     def perform_substitution (text = @string)
  196.       text.gsub!(/\\V\[([0-9]+)\]/i) { $game_variables[$1.to_i] }   # Variable
  197.       # FILTERS
  198.       text.gsub!(/\\F\[["'](.+?)["']\]/i)  { FILTERS[$1.to_s] }
  199.      text.gsub!(/\\F\[(.+?)\]/i)          { FILTERS[$1.to_i] }
  200.      # Party ID to Actor ID
  201.      while text[/\\PID\[(\d+)\]/i] != nil
  202.        x = $1.to_i < $game_party.members.size ? $game_party.members[$1.to_i].id : 0
  203.        text.sub! (/\\PID\[(\d+)\]/i)  { x.to_s }
  204.      end
  205.      # Old Codes
  206.      text.gsub!(/\\N\[([0-9]+)\]/i) { $1.to_i > 0 ? $game_actors[$1.to_i].name : ""} # Actor Name
  207.      text.gsub!(/\\\\/)             { "\\" }
  208.      # New Codes
  209.      begin
  210.        text.gsub! (/\\VOCAB\[(\w+)\]/i) { Vocab.send ($1.downcase) } # Vocab
  211.      rescue
  212.      end
  213.      text.gsub! (/\\AC\[(\d+)\]/i) { $game_actors[$1.to_i].class.name } # Actor Class
  214.      # Actor Stats
  215.      begin
  216.        text.gsub! (/\\A([^\[]+?)\[(\d+)\]/i) { $game_actors[$2.to_i].send ($1.to_s.downcase) }
  217.      rescue
  218.      end
  219.      text.gsub! (/\\NC\[(\d+)\]/i) { $1.to_i > 0 ? $data_classes[$1.to_i].name : "" } # Class Name
  220.      text.gsub! (/\\NE\[(\d+)\]/i) { $1.to_i > 0 ? $game_map.events[$1.to_i].name : "" } # Event Name
  221.      text.gsub! (/\\NM\[(\d+)\]/i) { $1.to_i > 0 ? $data_enemies[$1.to_i].name : "" } # Monster Name
  222.      text.gsub! (/\\NI\[(\d+)\]/i) { $1.to_i > 0 ? $data_items[$1.to_i].name : "" }   # Item Name
  223.      text.gsub! (/\\NW\[(\d+)\]/i) { $1.to_i > 0 ? $data_weapons[$1.to_i].name : "" } # Weapon Name
  224.      text.gsub! (/\\NA\[(\d+)\]/i) { $1.to_i > 0 ? $data_armors[$1.to_i].name : "" } # Armor Name
  225.      text.gsub! (/\\PI\[(\d+)\]/i) { $1.to_i > 0 ? $data_items[$1.to_i].price.to_s : "" } # Item Price
  226.      text.gsub! (/\\PW\[(\d+)\]/i) { $1.to_i > 0 ? $data_weapons[$1.to_i].price.to_s : "" } # Weapon Price
  227.      text.gsub! (/\\PA\[(\d+)\]/i) { $1.to_i > 0 ? $data_armors[$1.to_i].price.to_s : "" } # Armor Price
  228.      text.gsub! (/\\V\[([0-9]+)\]/i) { $game_variables[$1.to_i] }   # Variable
  229.      return text
  230.    end
  231.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  232.    # * Extract Code
  233.    #    code : the code to extract
  234.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  235.    def extract_code (code)
  236.      case code
  237.      when "\x02"
  238.        @word_letter_count += 1
  239.        @word_width += 24
  240.      when "\x03" then @format_text.bitmap.font.bold = true    # Bold
  241.      when "\x04" then @format_text.bitmap.font.italic = true  # Italic
  242.      when "\x05" then @format_text.bitmap.font.shadow = true  # Shadow
  243.      when "\x07" then @format_text.bitmap.font.bold = false   # Bold
  244.      when "\x08" then @format_text.bitmap.font.italic = false # Italic
  245.      when "\x09" then @format_text.bitmap.font.shadow = false # Shadow
  246.      end
  247.    end
  248.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  249.    # * Argument Codes
  250.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  251.    def no_args_codes
  252.      return ["\x03",  "\x04", "\x05", "\x06", "\x07",  "\x08", "\x09", "\x10"]
  253.    end
  254.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  255.    # * Argument Codes
  256.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  257.    def args_codes
  258.      return ["\x01", "\x02", "\x11", "\x12"]
  259.    end
  260.  end
  261.  
  262.  #============================================================================
  263.  # ** Artist 2
  264.  #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  265.  #  This is an artist class designed to recognize some special message codes.
  266.  #============================================================================
  267.  
  268.  class Artist_SpecialCodes
  269.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  270.    # * Draw
  271.    #    f            : Formatted Text Object
  272.    #    justify_text : boolean value on whether to justify text
  273.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  274.    def draw (f, justify_text = true)
  275.      @f = f
  276.      @justify_text = justify_text
  277.      @highlight = -1
  278.      @underline = false
  279.      # Calculates the necessary distance between lines
  280.      line_distance = @f.bitmap.height.to_f / @f.lines.size.to_f
  281.      @line_distance = [@f.bitmap.font.size + 4, line_distance].min
  282.      # For all lines in the lines array
  283.      for i in 0...@f.lines.size
  284.        # Compose line into a single string
  285.        @text = ""
  286.        @f.lines[i].each { |char| @text += char }
  287.        @blank_space = @f.blank_width[i]
  288.        @centre = @text[/\x12<1>/] != nil
  289.        @right = @text[/\x12<2>/] != nil && !@centre
  290.        total_blank = 0
  291.        if @centre || @right
  292.          @real_bitmap = @f.bitmap.dup
  293.          @f.bitmap  = Bitmap.new (@real_bitmap.width, @line_distance)
  294.          @f.bitmap.font = @real_bitmap.font.dup
  295.          @y = 0
  296.        else
  297.          @y = i*@line_distance
  298.        end
  299.        @x = 0
  300.        # For all indices of the line array
  301.        loop do
  302.          c = @text.slice!(/./m)
  303.          break if c.nil?
  304.          interpret_string (c)
  305.        end
  306.        # Align Text
  307.        if @centre || @right
  308.          blank = (@real_bitmap.width - @x)
  309.          blank /= 2 if @centre
  310.          rect = Rect.new (0, 0, @real_bitmap.width, @line_distance)
  311.          @real_bitmap.blt (blank, i*@line_distance, @f.bitmap, rect)
  312.          @real_bitmap.font = @f.bitmap.font.dup
  313.          @f.bitmap.dispose
  314.          @f.bitmap = @real_bitmap
  315.        end
  316.      end
  317.      return @f.bitmap
  318.    end
  319.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  320.    # * Get Text Color
  321.    #     n : Text color number  (0-31)
  322.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  323.    def text_color(n)
  324.      x = 64 + (n % 8) * 8
  325.      y = 96 + (n / 8) * 8
  326.      windowskin = Cache.system ("Window")
  327.      return windowskin.get_pixel(x, y)
  328.    end
  329.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  330.    # * Draw Icon
  331.    #     icon_index : Icon number
  332.    #     x,y        : draw spot coordinates
  333.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  334.    def draw_icon(icon_index, x, y)
  335.      bitmap = Cache.system("Iconset")
  336.      rect = Rect.new(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24)
  337.      @f.bitmap.blt(x, y, bitmap, rect)
  338.    end
  339.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  340.    # * Interpret Character
  341.    #    char : the char to decode
  342.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  343.    def interpret_string (char)
  344.      case char
  345.      when "\x01" # Colour
  346.        @text.slice! (/<(#?[\dABCDEF]+)>/i)
  347.        if $1.include? ("#")
  348.          r, g, b = $1[1, 2].to_i (16), $1[3, 2].to_i (16), $1[5, 2].to_i (16)
  349.          @f.bitmap.font.color = Color.new (r, g, b)
  350.        else
  351.          @f.bitmap.font.color = text_color ($1.to_i)
  352.        end
  353.      when "\x02" # Icon
  354.        @text.slice! (/<(\d+)>/)
  355.        draw_icon ($1.to_i, @x, @y)
  356.        @x += 24
  357.        @x += @justify_text && !@centre && !@right ? @blank_space : 0
  358.      when "\x03" then @f.bitmap.font.bold = true    # Bold ON
  359.      when "\x04" then @f.bitmap.font.italic = true  # Italic ON
  360.      when "\x05" then @f.bitmap.font.shadow = true  # Shadow ON
  361.      when "\x06" then @underline = true             # Underline ON
  362.      when "\x07" then @f.bitmap.font.bold = false   # Bold OFF
  363.      when "\x08" then @f.bitmap.font.italic = false # Italic OFF
  364.      when "\x09" then @f.bitmap.font.shadow = false # Shadow OFF
  365.      when "\x10" then @underline = false           # Underline OFF
  366.      when "\x11" # Highlight
  367.        @text.slice! (/<(-?\d+)>/)
  368.        @highlight = $1.to_i
  369.      when "\x12" # Centre or Right
  370.        @text.slice! (/<\d>/)
  371.      when "\n"   # Draw nothing when blank space
  372.      else
  373.        draw_character (char)
  374.      end
  375.    end
  376.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  377.    # * Draw Character
  378.    #    string : the string to draw
  379.    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  380.    def draw_character (string)
  381.      tw = @f.bitmap.text_size (string).width
  382.      ls = @justify_text && !@centre && !@right ? @blank_space : 0
  383.      hl_rect = Rect.new (@x, @y, tw + ls, @line_distance)
  384.      # Draw Highlight
  385.      if @highlight.between? (0, 31)
  386.        colour = text_color (@highlight)
  387.        colour.alpha = 120
  388.        contents.fill_rect (hl_rect, colour)
  389.      end
  390.      # Draw Underline
  391.      if @underline
  392.        y = @y + @line_distance - 2
  393.        @f.bitmap.fill_rect (@x, y, hl_rect.width, 2, @f.bitmap.font.color)
  394.      end
  395.      # Draws the string located at each index
  396.      @f.bitmap.draw_text (@x, @y, tw, @line_distance, string)
  397.      # Keeps track of the position we are in in pixels
  398.      @x += tw + ls
  399.    end
  400.  end
  401. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement