lib/rabbit/image/base.rb in rabbit-3.0.0 vs lib/rabbit/image/base.rb in rabbit-3.0.1

- old
+ new

@@ -1,54 +1,102 @@ +# Copyright (C) 2004-2020 Sutou Kouhei <kou@cozmixng.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + require "gdk_pixbuf2" -require "rabbit/utils" require "rabbit/image-data-loader" +require "rabbit/properties" module Rabbit module ImageManipulable class Base extend ModuleLoader - attr_reader :width, :height, :original_width, :original_height + attr_reader :filename + attr_reader :properties + attr_reader :original_width + attr_reader :original_height attr_reader :animation def initialize(filename, props) @filename = filename - @props = normalize_props(props) + @properties = Properties.new(props) + initialize_keep_ratio @animation = nil @animation_iterator = nil @animation_timeout = nil update_size @original_width = @width @original_height = @height end def [](key) - @props[normalize_prop_key(key)] + @properties[key] end def []=(key, value) - @props[normalize_prop_key(key)] = value + @properties[key] = value end - def keep_ratio - self["keep_ratio"] + def keep_ratio? + @properties.keep_ratio end + # For backward compatibility + alias_method :keep_ratio, :keep_ratio? def keep_ratio=(value) - self["keep_ratio"] = value + @properties.keep_ratio = value end def pixbuf @pixbuf end + def width + (relative_clip_width&.resolve(@width) || @width) - + (relative_clip_x&.resolve(@width) || 0) + end + + def height + (relative_clip_height&.resolve(@height) || @height) - + (relative_clip_y&.resolve(@height) || 0) + end + + def relative_clip_x + @properties.get_relative_size("relative_clip_x", @filename) + end + + def relative_clip_y + @properties.get_relative_size("relative_clip_y", @filename) + end + + def relative_clip_width + @properties.get_relative_size("relative_clip_width", @filename) + end + + def relative_clip_height + @properties.get_relative_size("relative_clip_height", @filename) + end + def resize(w, h) if w.nil? and h.nil? return - elsif keep_ratio + elsif keep_ratio? if w and h.nil? h = (original_height * w.to_f / original_width).ceil elsif w.nil? and h w = (original_width * h.to_f / original_height).ceil end @@ -63,40 +111,32 @@ @height = h end end def draw(canvas, x, y, params={}) - default_params = { - :width => width, - :height => height, - } + default_params = default_draw_params(x, y) target_pixbuf = pixbuf if @animation_iterator @animation_iterator.advance target_pixbuf = @animation_iterator.pixbuf update_animation_timeout(canvas) end canvas.draw_pixbuf(target_pixbuf, x, y, default_params.merge(params)) end private - def normalize_props(props) - normalized_props = {} - (props || {}).each do |key, value| - normalized_props[normalize_prop_key(key)] = value + def initialize_keep_ratio + return unless @properties["keep_ratio"].nil? + # For backward compatibility + keep_scale = @properties["keep_scale"] + if keep_scale.nil? + @properties["keep_ratio"] = true + else + @properties["keep_ratio"] = keep_scale end - keep_ratio_key = normalize_prop_key("keep_ratio") - unless normalized_props.has_key?(keep_ratio_key) - normalized_props[keep_ratio_key] = true - end - normalized_props end - def normalize_prop_key(key) - key.to_s.gsub(/-/, "_") - end - def load_data(data) loader = ImageDataLoader.new(data) begin loader.load rescue ImageLoadError @@ -125,9 +165,40 @@ canvas.redraw @animation_timeout = nil # update_animation_timeout(canvas) GLib::Source::REMOVE end + end + end + + def default_draw_params(x, y) + _relative_clip_x = relative_clip_x + _relative_clip_y = relative_clip_y + _relative_clip_width = relative_clip_width + _relative_clip_height = relative_clip_height + if _relative_clip_x or + _relative_clip_y or + _relative_clip_width or + _relative_clip_height + clip_x = _relative_clip_x&.resolve(@width) || 0 + clip_y = _relative_clip_y&.resolve(@height) || 0 + clip_width = _relative_clip_width&.resolve(@width) || @width + clip_height = _relative_clip_height&.resolve(@height) || @height + uncliped_width = width - (clip_width - clip_x) + @width + uncliped_height = height - (clip_height - clip_y) + @height + { + width: uncliped_width, + height: uncliped_height, + clip_x: x + clip_x, + clip_y: y + clip_y, + clip_width: clip_width, + clip_height: clip_height, + } + else + { + width: width, + height: height, + } end end end end end