#-- # $Id: redact.rb 73 2005-09-21 16:20:52Z tilman $ # # Copyright (c) 2005 Tilman Sauerbeck (tilman at code-monkey de) # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. require "eet" require "imlib2" require "redact/part" require "redact/program" class Object # :nodoc: undef :id end class String def to_embryo(collection) unless strip.length > 0 raise(Redact::RedactError, "invalid embryo code") end s = strip.dup {"part" => collection.parts, "program" => collection.programs}.each do |entity, ary| s.gsub!(/#{entity.upcase}:\"(.*?)\"/) do |m| found = ary.find { |(k, p)| p.name == $1 } if found.nil? raise(Redact::RedactError, "#{entity} not found - #{$1}") else found.last.id end end end s end end module Redact VERSION = "0.1.5" class RedactError < StandardError; end class Edje attr_reader :collections, :data, :collection_dir, :image_dir, :font_dir def initialize clear end def clear @font_dir = FontDirectory.new @image_dir = ImageDirectory.new @collection_dir = CollectionDirectory.new @collections = Hash.new do |h, k| c = Collection.new(k, h.size) @collection_dir << CollectionDirectoryEntry.new(c) h[k] = c end @data = DataHash.new end def collection(name) # :yields: collection c = @collections[name] block_given? ? (yield c) : c end protected def to_eet_name "Edje_File" end def to_eet_properties {"compiler" => ["redact"], "version" => [2], "feature_ver" => [1], "font_dir" => [@font_dir, :sub], "image_dir" => [@image_dir, :sub], "collection_dir" => [@collection_dir, :sub], "data" => [@data]} end end class DataHash < Hash # :nodoc: def [](key) super.value end def []=(key, value) super(key, HashEntry.new(key, value)) end end class HashEntry # :nodoc: attr_reader :key, :value def initialize(key, value) @key = key.to_str.dup.freeze @value = value.to_str.dup.freeze end protected def to_eet_name "Edje_Data" end end class FontDirectory < Array # :nodoc: protected def to_eet_name "Edje_Font_Directory" end def to_eet_properties {"entries" => [self]} end end class FontDirectoryEntry # :nodoc: attr_reader :save_as, :filename, :alias def initialize(fn_alias, filename) @save_as = fn_alias.to_str.dup.freeze @filename = filename.to_str.dup.freeze @alias = "Edje." + fn_alias.sub(/.[^.]+$/, "").freeze end protected def to_eet_name "Edje_Font_Directory_Entry" end def to_eet_properties {"entry" => [@alias]} end end class ImageDirectory < Array # :nodoc: def <<(entry) super entry.id = size - 1 end protected def to_eet_name "Edje_Image_Directory" end def to_eet_properties {"entries" => [self]} end end class ImageDirectoryEntry # :nodoc: attr_reader :filename, :image, :id def initialize(im_alias, filename) @alias = im_alias.to_str.dup.freeze @filename = filename.to_str.dup.freeze @image = Imlib2::Image.load(@filename) @id = -1 @source_type = 1 # COMP @source_param = 1 # COMP end def id=(id) if id < 0 raise(ArgumentError, "invalid ID - #{id}") elsif @id != -1 raise(RedactError, "ID already set") else @id = id end end protected def to_eet_name "Edje_Image_Directory_Entry" end def to_eet_properties {"entry" => [@alias], "source_type" => [@source_type], "source_param" => [@source_param], "id" => [@id]} end end class CollectionDirectory < Array # :nodoc: protected def to_eet_name "Edje_Part_Collection_Directory" end def to_eet_properties {"entries" => [self]} end end class CollectionDirectoryEntry # :nodoc: def initialize(col) @name = col.name.to_str.dup.freeze @id = col.id end protected def to_eet_name "Edje_Part_Collection_Directory_Entry" end def to_eet_properties {"entry" => [@name], "id" => [@id]} end end class Collection attr_reader :name, :id, :data, :min, :max, :parts, :programs, :script def initialize(name, id) @name = name.to_str.dup.freeze @id = id @min = [0, 0] @max = [0, 0] @data = DataHash.new @parts = {} @programs = {} @script = nil end def script=(v) v = v.to_str @script = (File.exist?(v) ? File.read(v) : v).dup end def part(name, type = :invalid) # :yields: part p = @parts[name] if p.nil? klass = case type when :rect Part when :swallow SwallowPart when :text TextPart when :image ImagePart else raise(ArgumentError, "invalid part type - #{type.to_s}") end p = klass.new(self, @parts.size, name) @parts[name] = p end block_given? ? (yield p) : p end def program(name, type = :invalid) # :yields: program p = @programs[name] if p.nil? klass = case type when :base Program when :set_state SetStateProgram when :stop_program StopProgramProgram when :emit_signal EmitSignalProgram when :exec_script ExecScriptProgram else raise(ArgumentError, "invalid program type - #{type.to_s}") end p = klass.new(self, @programs.size, name) @programs[name] = p end block_given? ? (yield p) : p end def set_size(w, h) set_min(w, h) set_max(w, h) end def set_min(w, h) @min = [w, h] end def set_max(w, h) @max = [w, h] end def has_embryo?(search_programs = true) if !@script.nil? && @script.to_str.strip.length > 0 true elsif search_programs p = @programs.find do |(k, p)| p.is_a?(ExecScriptProgram) end !p.nil? end end protected def to_eet_name "Edje_Part_Collection" end def to_eet_properties # sort parts and programs by id, since edje doesn't sort # them on load parts = @parts.to_a.map { |(key, value)| value }.sort programs = @programs.to_a.map { |(key, value)| value }.sort {"id" => [@id], "parts" => [parts], "programs" => [programs], "data" => [@data], "prop.min.w" => [@min[0]], "prop.min.h" => [@min[1]], "prop.max.w" => [@max[0]], "prop.max.h" => [@max[1]]} end end EDJE = Redact::Edje.new end