Dziennik Zadań
Aktualny czas: 05-09-26, 17:52 Witaj! Przejdź do zakładki Logowanie lub Rejestracja

To była dobra przygoda. Dziękujemy!
Po wielu wspólnych latach Ultima Forum przechodzi w tryb archiwalny.
Zostawiamy je tutaj takim, jakie stworzyliśmy je razem,
z tysiącami postów, projektów, porad, skryptów i wspomnień.
Dziękujemy każdemu, kto był częścią Ultimy.


Wątek zamknięty 
[VX] Dziennik Zadań
Yoroiookami Offline
*


Liczba postów: 985
Dołączył: 01-05-13

Pomógł: 137



Post: #3
RE: Dziennik Zadań

#========================================================================
#  Paragraph Formatter (VX)
#  Version: 1.1
#  Author: modern algebra (rmrk.net)
#  Date: March 4, 2008
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Apology:
#    The idea behind this script is to easily separate a long string into a paragraph that fits in to
#     the dimensions you specify.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Instructions:
#    For ease of use of people who are not neccesarily interested in writing their own algorithm,
#    I have included a facade which you can use simply by this code:
#
#           bitmap.draw_paragraph (x, y, width, height, string)
#
#    where x & y are the x & y coordinates on the specified bitmap, and width and height are the
#    maximum dimensions of the paragraph and string is the text you want to display in
#    paragraph formatter
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  How it works:
#    The paragrapher expects two objects when initialized, a Formatter and an Artist. The idea
#    behind the formatter is that it is expected to take the initial specifications and convert it to a
#    Formatted Text object. Then, the Artist class is expected to interpret the Formatted Text
#    object and draw the paragraph. For details on how each specific algorithm works,  visit the
#    comments above and inside them. It is not necessary to use the default Formatter, Artist, or
#    Formatted Text objects.
#========================================================================

#======================================================================
# ** Bitmap
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Facade for easy application of the Paragraph Formatter
#======================================================================

class Bitmap
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Get Formatter
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def paragraph_formatter
    @p_formatter = $game_system.default_formatter.new if @p_formatter.nil?
    return @p_formatter
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Set Formatter
  #     formatter : The uninitialized formatter class you would like to use
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def paragraph_formatter= (formatter)
    @p_formatter = formatter.new
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Get Artist
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def paragraph_artist
    @p_artist = $game_system.default_artist.new if @p_artist.nil?
    return @p_artist
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Set Artist
  #     artist : The uninitialized artist class you would like to use
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def paragraph_artist= (artist)
    @p_artist = artist.new
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * The Facade, which uses default Formatter and Artist to draw the formatted text directly
  #  to a bitmap, such as self.contents
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def draw_paragraph (x, y, max_width, max_height, string)
    bitmap = Bitmap.new (max_width, max_height)
    bitmap.font = self.font
    pg = Paragrapher.new(paragraph_formatter, paragraph_artist)
    bitmap = pg.paragraph (string, bitmap)
    blt (x, y, bitmap, bitmap.rect)
    # Dispose of the proxy bitmap
    bitmap.dispose
  end
end

#========================================================================
# ** Game_System
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of changes:
#     new instance variables - default_formatter, default_artist
#     aliased methods - initialize
#========================================================================

class Game_System
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Public Instance Variables
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  attr_accessor :default_formatter
  attr_accessor :default_artist
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Object Initialization
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias ma_paragraph_formatter_init initialize
  def initialize
    # Run original method
    ma_paragraph_formatter_init
    # Initialize original default format and artist classes
    @default_formatter = Paragrapher::Formatter_2
    @default_artist = Paragrapher::Artist
  end
end

#======================================================================
# ** Paragrapher
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Module containing the objects for the Paragrapher
#======================================================================
module Paragrapher
  #===================================================================
  # Allows the 'Paragrapher.new' command outside of the module to be used
  # rather than having to use 'Paragrapher::Paragrapher.new'
  #===================================================================
  class << self
    def new(*args, &block)
      return Paragrapher.new(*args, &block)
    end
  end
  
  #===================================================================
  # * The Paragrapher class
  #===================================================================
  class Paragrapher
    def initialize(formatter, artist)
      @formatter = formatter
      @artist = artist
    end
    
    def paragraph(string, *specifications)
      f = @formatter.format(string, *specifications)
      return @artist.draw(f)
    end
  end
  
  #===================================================================
  # * The Formatter class
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  #  This class converts a string into a formatted text object, which is then
  #  passed on to the Artist class
  #===================================================================
  class Formatter
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Format
    #     string         : the string to be formatted
    #     specifications : the desired width of the paragraph, or the bitmap
    #-------------------------------------------------------------------------------------------------------------------
    #  This works on a very simple algorithm. Basically, it just formats the
    #  text by going through each word in the string. If a word
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def format(string, specifications)
      # Initializes Formatted_Text object
      f = Formatted_Text.new
      # Checks whether specifications is a bitmap or a number. It then sets
      # max_width and f.bitmap accordingly
      if specifications.is_a? (Bitmap)
        f.bitmap = specifications
        max_width = specifications.width
      elsif specifications.is_a? (Fixnum) || specifications.is_a? (Float)
        max_width = specifications
        f.bitmap = Bitmap.new (max_width, 32)
      else
        # Error Catching: Bad Specifications
        bitmap = Bitmap.new (200, 64)
        f = format ('Specifications Error', bitmap)
        p 'Specifications Error: Please Pass Fixnum, Float or Bitmap'
        return f
      end
      # Breaks the given string into an array of all it's characters
      temp_word_array = string.scan (/./)
      position = 0
      line_break = 0
      # Initializes f.lines
      f.lines = []
      f.blank_width = []
      for i in 0...temp_word_array.size
        character = temp_word_array[i]
        # Error catching
        if character == "\n"
          p 'This formatter does not recognize line breaks'
          character = " "
        end
        # If at a new word
        if character == " " || i == temp_word_array.size - 1
          # Take into account the last character of the string
          if i == temp_word_array.size - 1
            i += 1
          end
          # If this word fits on the current line
          if f.bitmap.text_size (string[line_break, i-line_break]).width <= max_width
            position = i
          else
            line = temp_word_array[line_break, position-line_break]
            # Adds the first lines to f.lines
            f.lines.push (line)
            # Calculates the blank space left to cover in the line
            line_blank = max_width - f.bitmap.text_size(string[line_break,position-line_break]).width
            # Calculates the necessary distance between letters to make up for
            # line_blank and adds that value to the f.blank_width array
            f.blank_width.push (line_blank.to_f / (line.size.to_f-1.0))
            # Keeps track of the position in the array of each line
            line_break = position + 1
            position = i
          end
        end
      end
      # Adds the last line to f.lines
      f.lines.push (temp_word_array[line_break, temp_word_array.size - line_break])
      # Since the last line is drawn normally, blank_width should be 0
      f.blank_width.push (0)
      if specifications.class == Fixnum
        # Sets up the bitmap if it was unspecified.
        f.bitmap = Bitmap.new(max_width, f.lines.size*32)
      end
      # Returns the Formatted_Text object
      return f
    end
  end
  
  #===================================================================
  # * Formatter 2 (Using Zeriab's Algorithm)
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  #  This algorithm was written by Zeriab for fonts which have characters of the same width.
  #  This is like Courier New, UMEGothic and fonts of that sort. This algorithm attaches a
  #  cost to each line based on the amount of white space at the end of that line. It will
  #  display the way of writing the text with the lowest total cost. In prcatice, this will mean
  #  that it will, as much as possible, reduce the spacing between letters in a line and make
  #  the spacing more consistent for each line of the paragraph
  #===================================================================
  class Formatter_2
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Format
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def format (string, specifications)
      f = Formatted_Text.new
      f.lines, f.blank_width, word_lengths, words = [], [], [], []
      tracker = 0
      for i in 0...string.size
        if string[i,1] == " " || i == string.size - 1
          if i == string.size - 1
            i += 1
          end
          word_lengths.push (i - tracker)
          words.push (string[tracker, i - tracker])
          tracker = i + 1
        end
      end
      if specifications.class == Bitmap
        max_width = specifications.width
        f.bitmap = specifications
      elsif specifications.class == Fixnum || specifications.class == Float
        max_width = specifications
        f.bitmap = Bitmap.new (1,1)
      else
        # Error Catching: Bad specification
        bitmap = Bitmap.new (200, 64)
        f = format ('Specifications Error', bitmap)
        p 'Specifications Error: Please Pass Fixnum, Float or Bitmap'
        return f
      end
      tw = f.bitmap.text_size('a').width
      max_width = [max_width / tw, 180].min
      # Error Catching: Word too long
      if word_lengths.max > max_width
        f = format ('Too long' , specifications)
        p 'One or more words is too long for specified width'
        return f
      end
      position = line_break (word_lengths, max_width)
      lines = give_lines (position, position.size - 1, words)
      max_width *= tw
      for i in 0...lines.size
        line = lines[i]
        f.lines.push (line.scan (/./))
        if i == lines.size - 1
          f.blank_width.push (0)
        else
          text_width = line.size * tw
          extra_space = max_width - text_width
          f.blank_width.push (extra_space.to_f / (line.size.to_f - 1.0))
        end
      end
      if f.bitmap != specifications
        f.bitmap = Bitmap.new (max_width, f.lines.size*32)
      end
      return f
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Line Break (written by Zeriab)
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def line_break(word_lengths, max_length)
       return false  if max_length > 180
       word_lengths.unshift(nil)
       extra_spaces = Table.new(word_lengths.size,word_lengths.size)
       line_prices = Table.new(word_lengths.size,word_lengths.size)
       word_price = []
       position = []
       inf = max_length*max_length + 1
       for i in 1...word_lengths.size
         extra_spaces[i,i] = max_length - word_lengths[i]
         for j in (i+1)..[word_lengths.size-1, max_length/2+i+1].min
            extra_spaces[i,j] = extra_spaces[i,j-1] - word_lengths[j]-1
         end
       end
       for i in 1...word_lengths.size
         for j in i..[word_lengths.size-1, max_length/2+i+1].min
            if extra_spaces[i,j] < 0
              line_prices[i,j] = inf
            elsif j == word_lengths.size-1 and extra_spaces[i,j] >= 0
              line_prices[i,j] = 0
            else
              line_prices[i,j] = extra_spaces[i,j]*extra_spaces[i,j]
            end
        end
       end
       word_price[0] = 0
       for j in 1...word_lengths.size
         word_price[j] = inf
         for ik in 1..j
            i = j - ik + 1
            break  if line_prices[i,j] == inf
            if word_price[i-1] + line_prices[i,j] < word_price[j]
              word_price[j] = word_price[i-1] + line_prices[i,j]
              position[j] = i
            end
         end
       end
       return position
    end
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Give_Lines (written by Zeriab)
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def give_lines(position,last_index,words)
       first_index = position[last_index]
       word_array = []
       if first_index != 1
         word_array = give_lines(position, first_index - 1,words)
       end
       str = ""
       for x in first_index..last_index
         str += ' '  if x != first_index
         str += words[x-1]
       end
       word_array << str
       return word_array
    end
  end

  #===================================================================
  # * The Artist class
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  #  Interprets a Formatted Text object and draws the paragraph encoded
  #===================================================================
  class Artist
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Draw
    #     f : Formatted Text Object
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def draw (f)
      # Calculates the necessary distance between lines
      line_distance = f.bitmap.height.to_f / f.lines.size.to_f
      line_distance = [f.bitmap.font.size  + 10, line_distance].min
      # For all lines in the lines array
      for i in 0...f.lines.size
        blank_space = f.blank_width[i]
        position = 0
        # For all indices of the line array
        for j in 0...f.lines[i].size
          word = f.lines[i][j]
          ws = f.bitmap.text_size (word)
          position += blank_space if j != 0
          # Adds blank_space and position, and draws the string located at each index
          f.bitmap.draw_text (position, line_distance*i,ws.width+1,ws.height+1,word)
          # Keeps track of the position we are in in pixels
          position += ws.width
        end
      end
      return f.bitmap
    end
  end
  
  #===================================================================
  # * The Formatted_Text class containing the results of the formatter
  #===================================================================
  class Formatted_Text
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # * Public Instance Variables
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    attr_accessor :lines       # An array of strings, each a line of the paragraph
    attr_accessor :blank_width # The amount of white space between each letter
    attr_accessor :bitmap      # The bitmap drawn to
  end
end

Jest jeszcze taki formatter (oryginalny), ale miał problem z polskimi znakami i takie tam. :zmienny:

[Obrazek: mt4dzY7.png]
[Obrazek: k5KQGOe.png]
11-04-17 20:31
Znajdź wszystkie posty użytkownika
"Pomógł" przyznał(a):
Wątek zamknięty 


Wiadomości w tym wątku
Dziennik Zadań - Yoroiookami - 11-04-17, 18:44
RE: Dziennik Zadań - AlmostNoRuby - 11-04-17, 20:17
RE: Dziennik Zadań - Yoroiookami - 11-04-17 20:31
RE: Dziennik Zadań - AlmostNoRuby - 12-04-17, 15:11
RE: Dziennik Zadań - Yoroiookami - 12-04-17, 15:29
RE: Dziennik Zadań - AlmostNoRuby - 12-04-17, 19:28
RE: Dziennik Zadań - Yoroiookami - 12-04-17, 22:19
RE: Dziennik Zadań - AlmostNoRuby - 13-04-17, 11:32

Skocz do:


Użytkownicy przeglądający ten wątek: 1 gości

Kontakt | Ultima Forum | Wróć do góry | Wróć do forów | Wersja bez grafiki | RSS
Powered By MyBB. © 2013 MyBB Group. All Rights Reserved.
Skórka by Ayene.