require 'stringio' module RRTF # This class represents a colour within a RTF document. class Colour # Attribute accessor. attr_reader :red, :green, :blue # Format: HEX RGB with '#' prefix def self.from_string(str) if str =~ /\#[0-9a-f]{6}/i m = str.match /([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/i self.new(m[1].hex, m[2].hex, m[3].hex) else RTFError.fire("Unreconized string colour format '#{str}'.") end end # This is the constructor for the Colour class. # # ==== Parameters # red:: The intensity setting for red in the colour. Must be an # integer between 0 and 255. # green:: The intensity setting for green in the colour. Must be an # integer between 0 and 255. # blue:: The intensity setting for blue in the colour. Must be an # integer between 0 and 255. # # ==== Exceptions # RTFError:: Generated whenever an invalid intensity setting is # specified for the red, green or blue values. def initialize(red, green, blue) if !red.kind_of?(Integer) || red < 0 || red > 255 RTFError.fire("Invalid red intensity setting ('#{red}') specified "\ "for a Colour object.") end if !green.kind_of?(Integer) || green < 0 || green > 255 RTFError.fire("Invalid green intensity setting ('#{green}') "\ "specified for a Colour object.") end if !blue.kind_of?(Integer) || blue < 0 || blue > 255 RTFError.fire("Invalid blue intensity setting ('#{blue}') "\ "specified for a Colour object.") end @red = red @green = green @blue = blue end # This method overloads the comparison operator for the Colour class. # # ==== Parameters # object:: A reference to the object to be compared with. def ==(object) object.instance_of?(Colour) and object.red == @red and object.green == @green and object.blue == @blue end # This method returns a textual description for a Colour object. # # ==== Parameters # indent:: The number of spaces to prefix to the lines created by the # method. Defaults to zero. def to_s(indent=0) prefix = indent > 0 ? ' ' * indent : '' "#{prefix}Colour (#{@red}/#{@green}/#{@blue})" end # This method generates the RTF text for a Colour object. # # ==== Parameters # indent:: The number of spaces to prefix to the lines created by the # method. Defaults to zero. def to_rtf(indent=0) prefix = indent > 0 ? ' ' * indent : '' "#{prefix}\\red#{@red}\\green#{@green}\\blue#{@blue};" end def to_decimal(options = {}) if options["reverse_bytes"] (@blue * 65536) + (@green * 256) + @red else (@red * 65536) + (@green * 256) + @blue end # if end end # End of the Colour class. # This class represents a table of colours used within a RTF document. This # class need not be directly instantiated as it will be used internally by, # and can be obtained from a Document object. class ColourTable # This is the constructor for the ColourTable class. # # ==== Parameters # *colours:: An array of zero or more colours that make up the colour # table entries. def initialize(*colours) @colours = [] colours.each {|colour| add(colour)} end # This method fetches a count of the number of colours within a colour # table. def size @colours.size end # This method adds a new colour to a ColourTable object. If the colour # already exists within the table or is not a Colour object then this # method does nothing. # # ==== Parameters # colour:: The colour to be added to the table. def add(colour) if colour.instance_of?(Colour) @colours.push(colour) if @colours.index(colour).nil? end self end # This method iterates over the contents of a ColourTable object. This # iteration does not include the implicit default colour entry. def each if block_given? @colours.each {|colour| yield colour} end end # This method overloads the array dereference operator for the ColourTable # class. It is not possible to dereference the implicit default colour # using this method. An invalid index will return a nil value. # # ==== Parameters # index:: The index of the colour to be retrieved. def [](index) @colours[index] end # This method retrieves the index of a specified colour within the table. # If the colour doesn't exist within the table then nil is returned. It # should be noted that the index of a colour will be one more than its # order of entry to account for the implicit default colour entry. # # ==== Parameters # colour:: The colour to retrieve the index of. def index(colour) index = @colours.index(colour) index.nil? ? index : index + 1 end # This method generates a textual description for a ColourTable object. # # ==== Parameters # indent:: The number of spaces to prefix to the lines generated by the # method. Defaults to zero. def to_s(indent=0) prefix = indent > 0 ? ' ' * indent : '' text = StringIO.new text << "#{prefix}Colour Table (#{@colours.size} colours)" @colours.each {|colour| text << "\n#{prefix} #{colour}"} text.string end # This method generates the RTF text for a ColourTable object. # # ==== Parameters # indent:: The number of spaces to prefix to the lines generated by the # method. Defaults to zero. def to_rtf(indent=0) prefix = indent > 0 ? ' ' * indent : '' text = StringIO.new text << "#{prefix}{\\colortbl\n#{prefix};" @colours.each {|colour| text << "\n#{prefix}#{colour.to_rtf}"} text << "\n#{prefix}}" text.string end alias << add end # End of the ColourTable class. end # End of the RTF module.