From 77a694f797078c002e4f976ee5c447ef5afefd11 Mon Sep 17 00:00:00 2001 From: Andy Meneely Date: Mon, 16 Mar 2020 16:38:13 -0400 Subject: [PATCH] partway through the conversion --- docs/args/transform.rst | 2 +- docs/dsl/svg.rst | 7 +- lib/squib/api/image.rb | 49 ----- lib/squib/api/save.rb | 14 +- lib/squib/args/arg_loader.rb | 3 +- lib/squib/args/input_file.rb | 50 +++-- lib/squib/args/paint.rb | 60 +++--- lib/squib/args/scale_box.rb | 75 ++++--- lib/squib/args/sheet.rb | 295 +++++++++++++-------------- lib/squib/args/showcase_special.rb | 64 +++--- lib/squib/args/svg_special.rb | 52 ++--- lib/squib/args/transform.rb | 102 +++++---- lib/squib/deck.rb | 4 +- lib/squib/dsl/png.rb | 56 +++++ lib/squib/dsl/showcase.rb | 43 ++++ lib/squib/dsl/svg.rb | 62 ++++++ spec/args/box_spec.rb | 11 +- spec/args/scale_box_spec.rb | 2 +- spec/args/sheet_spec.rb | 24 ++- spec/args/svg_special_spec.rb | 1 + spec/args/transform_spec.rb | 9 +- spec/docs/options_documented_spec.rb | 5 +- 22 files changed, 541 insertions(+), 449 deletions(-) delete mode 100644 lib/squib/api/image.rb create mode 100644 lib/squib/dsl/png.rb create mode 100644 lib/squib/dsl/showcase.rb create mode 100644 lib/squib/dsl/svg.rb diff --git a/docs/args/transform.rst b/docs/args/transform.rst index fe5c761..0273716 100644 --- a/docs/args/transform.rst +++ b/docs/args/transform.rst @@ -40,7 +40,7 @@ crop_height Height of the cropped image. Supports :doc:`/units`. -flip_horiztonal +flip_horizontal default: ``false`` Flip this image about its center horizontally (i.e. left becomes right and vice versa). diff --git a/docs/dsl/svg.rst b/docs/dsl/svg.rst index dff487d..feab207 100644 --- a/docs/dsl/svg.rst +++ b/docs/dsl/svg.rst @@ -19,11 +19,6 @@ file .. include:: /args/xy.rst -range - default: ``all`` - - the range of cards over which this will be rendered. See :doc:`/arrays` - data default: ``nil`` @@ -106,7 +101,7 @@ crop_height ive): Height of the cropped image. Supports :doc:`/units` -flip_horiztonal +flip_horizontal default: ``false`` Flip this image about its center horizontally (i.e. left becomes right and vice versa). diff --git a/lib/squib/api/image.rb b/lib/squib/api/image.rb deleted file mode 100644 index 569661f..0000000 --- a/lib/squib/api/image.rb +++ /dev/null @@ -1,49 +0,0 @@ -require_relative '../args/card_range' -require_relative '../args/paint' -require_relative '../args/scale_box' -require_relative '../args/transform' -require_relative '../args/input_file' -require_relative '../args/svg_special' - -module Squib - class Deck - - # DSL method. See http://squib.readthedocs.io - def png(opts = {}) - Dir.chdir(img_dir) do - range = Args::CardRange.new(opts[:range], deck_size: size) - paint = Args::Paint.new(custom_colors).load!(opts, expand_by: size, layout: layout) - box = Args::ScaleBox.new(self).load!(opts, expand_by: size, layout: layout, dpi: dpi) - trans = Args::Transform.new(self).load!(opts, expand_by: size, layout: layout, dpi: dpi) - ifile = Args::InputFile.new.load!(opts, expand_by: size, layout: layout, dpi: dpi) - @progress_bar.start('Loading PNG(s)', range.size) do |bar| - range.each do |i| - @cards[i].png(ifile[i].file, box[i], paint[i], trans[i]) - bar.increment - end - end - end - end - - # DSL method. See http://squib.readthedocs.io - def svg(opts = {}) - Dir.chdir(img_dir) do - range = Args::CardRange.new(opts[:range], deck_size: size) - paint = Args::Paint.new(custom_colors).load!(opts, expand_by: size, layout: layout) - box = Args::ScaleBox.new(self).load!(opts, expand_by: size, layout: layout, dpi: dpi) - trans = Args::Transform.new(self).load!(opts, expand_by: size, layout: layout, dpi: dpi) - ifile = Args::InputFile.new.load!(opts, expand_by: size, layout: layout, dpi: dpi) - svg_args = Args::SvgSpecial.new.load!(opts, expand_by: size, layout: layout, dpi: dpi) - @progress_bar.start('Loading SVG(s)', range.size) do |bar| - range.each do |i| - if svg_args.render?(i) - @cards[i].svg(ifile[i].file, svg_args[i], box[i], paint[i], trans[i]) - end - bar.increment - end - end - end - end - - end -end diff --git a/lib/squib/api/save.rb b/lib/squib/api/save.rb index bee6157..a2a5ca2 100644 --- a/lib/squib/api/save.rb +++ b/lib/squib/api/save.rb @@ -21,7 +21,7 @@ module Squib # DSL method. See http://squib.readthedocs.io def save_pdf(opts = {}) range = Args::CardRange.new(opts[:range], deck_size: size) - sheet = Args::Sheet.new(custom_colors, { file: 'output.pdf' }).load!(opts, expand_by: size, layout: layout, dpi: dpi) + sheet = Args::Sheet.new({ file: 'output.pdf' }).extract!(opts, self) sprue_file = Args::SprueFile.new.load!(opts, expand_by: size) if sprue_file.sprue.nil? @@ -50,7 +50,7 @@ module Squib def save_sheet(opts = {}) range = Args::CardRange.new(opts[:range], deck_size: size) batch = Args::SaveBatch.new.load!(opts, expand_by: size, layout: layout, dpi: dpi) - sheet = Args::Sheet.new(custom_colors, { margin: 0 }, size).load!(opts, expand_by: size, layout: layout, dpi: dpi) + sheet = Args::Sheet.new({ margin: 0 }).extract! opts, self sprue_file = Args::SprueFile.new.load!(opts, expand_by: size) if sprue_file.sprue.nil? @@ -63,19 +63,11 @@ module Squib end end - # DSL method. See http://squib.readthedocs.io - def showcase(opts = {}) - range = Args::CardRange.new(opts[:range], deck_size: size) - showcase = Args::ShowcaseSpecial.new.load!(opts, expand_by: size, layout: layout, dpi: dpi) - sheet = Args::Sheet.new(custom_colors, { file: 'showcase.png' }).load!(opts, expand_by: size, layout: layout, dpi: dpi) - render_showcase(range, sheet, showcase) - end - # DSL method. See http://squib.readthedocs.io def hand(opts = {}) range = Args::CardRange.new(opts[:range], deck_size: size) hand = Args::HandSpecial.new(height).load!(opts, expand_by: size, layout: layout, dpi: dpi) - sheet = Args::Sheet.new(custom_colors, { file: 'hand.png', trim_radius: 0 }).load!(opts, expand_by: size, layout: layout, dpi: dpi) + sheet = Args::Sheet.new({ file: 'hand.png', trim_radius: 0 }).extract!(opts, self) render_hand(range, sheet, hand) end diff --git a/lib/squib/args/arg_loader.rb b/lib/squib/args/arg_loader.rb index 28b0be8..5dbb4d9 100644 --- a/lib/squib/args/arg_loader.rb +++ b/lib/squib/args/arg_loader.rb @@ -5,9 +5,10 @@ require 'ostruct' # Intended to be used a a mix-in, # For example use see Box as an example module Squib::Args::ArgLoader - + # wrapper for compatibility def extract!(args, deck) + @deck = deck load!(args, expand_by: deck.size, layout: deck.layout, dpi: deck.dpi) end diff --git a/lib/squib/args/input_file.rb b/lib/squib/args/input_file.rb index eb0d94f..a84b6e7 100644 --- a/lib/squib/args/input_file.rb +++ b/lib/squib/args/input_file.rb @@ -1,37 +1,35 @@ require_relative 'arg_loader' -module Squib - # @api private - module Args - - class InputFile - include ArgLoader - - def initialize(dsl_method_default = {}) - @dsl_method_default = dsl_method_default - end +module Squib::Args + module_function def extract_input_file(opts, deck, dsl_method_default = {}) + InputFile.new(dsl_method_default).extract!(opts, deck) + end - def self.parameters - { file: nil, - sheet: 0, - } - end + class InputFile + include ArgLoader - def self.expanding_parameters - parameters.keys # all of them - end + def initialize(dsl_method_default = {}) + @dsl_method_default = dsl_method_default + end - def self.params_with_units - [] # none of them - end + def self.parameters + { file: nil, + sheet: 0, + } + end - def validate_file(arg, _i) - return nil if arg.nil? - raise "File #{File.expand_path(arg)} does not exist!" unless File.exists?(arg) - File.expand_path(arg) - end + def self.expanding_parameters + parameters.keys # all of them + end + def self.params_with_units + [] # none of them end + def validate_file(arg, _i) + return nil if arg.nil? + raise "File #{File.expand_path(arg)} does not exist!" unless File.exists?(arg) + File.expand_path(arg) + end end end diff --git a/lib/squib/args/paint.rb b/lib/squib/args/paint.rb index c44aa1f..63085be 100644 --- a/lib/squib/args/paint.rb +++ b/lib/squib/args/paint.rb @@ -2,43 +2,41 @@ require 'cairo' require_relative 'arg_loader' require_relative 'color_validator' -module Squib - # @api private - module Args - class Paint - include ArgLoader - include ColorValidator - - def self.parameters - { alpha: 1.0, - blend: :none, - mask: nil, - } - end - - - def self.expanding_parameters - parameters.keys # all of them are expandable - end +module Squib::Args + module_function def extract_paint(opts, deck) + Paint.new(deck.custom_colors).extract!(opts, deck) + end + class Paint + include ArgLoader + include ColorValidator - def self.params_with_units - [] - end + def initialize(custom_colors) + @custom_colors = custom_colors + end - def initialize(custom_colors) - @custom_colors = custom_colors - end + def self.parameters + { alpha: 1.0, + blend: :none, + mask: nil, + } + end - def validate_alpha(arg, _i) - raise 'alpha must respond to to_f' unless arg.respond_to? :to_f - arg.to_f - end + def self.expanding_parameters + parameters.keys # all of them are expandable + end - def validate_mask(arg, _i) - colorify(arg, @custom_colors) - end + def self.params_with_units + [] + end + def validate_alpha(arg, _i) + raise 'alpha must respond to to_f' unless arg.respond_to? :to_f + arg.to_f + end + def validate_mask(arg, _i) + colorify(arg, @custom_colors) end + end end diff --git a/lib/squib/args/scale_box.rb b/lib/squib/args/scale_box.rb index 46c7d84..045fac5 100644 --- a/lib/squib/args/scale_box.rb +++ b/lib/squib/args/scale_box.rb @@ -1,53 +1,50 @@ require_relative 'arg_loader' -module Squib - # @api private - module Args - - class ScaleBox - include ArgLoader +module Squib::Args + module_function def extract_scale_box(opts, deck) + ScaleBox.new.extract!(opts, deck) + end - def initialize(deck) - @deck = deck - end + class ScaleBox + include ArgLoader - def self.parameters - { x: 0, y: 0, - width: :native, height: :native - } - end + def self.parameters + { + x: 0, y: 0, + width: :native, height: :native + } + end - def self.expanding_parameters - parameters.keys # all of them - end + def self.expanding_parameters + parameters.keys # all of them + end - def self.params_with_units - parameters.keys # all of them - end + def self.params_with_units + parameters.keys # all of them + end - def validate_width(arg, i) - return @deck.width if arg.to_s == 'deck' - return :native if arg.to_s == 'native' - return arg if arg.respond_to? :to_f - if arg.to_s == 'scale' - raise 'if width is :scale, height must be a number' unless height[i].respond_to? :to_f - return arg - end - raise 'width must be a number, :scale, :native, or :deck' + def validate_width(arg, i) + return @deck.width if arg.to_s == 'deck' + return :native if arg.to_s == 'native' + return arg if arg.respond_to? :to_f + if arg.to_s == 'scale' + raise 'if width is :scale, height must be a number' unless height[i].respond_to? :to_f + return arg end + raise 'width must be a number, :scale, :native, or :deck' + end - def validate_height(arg, i) - return @deck.height if arg.to_s == 'deck' - return :native if arg.to_s == 'native' - return arg if arg.respond_to? :to_f - if arg.to_s == 'scale' - raise 'if height is \'scale\', width must be a number' unless width[i].respond_to? :to_f - return arg - end - raise 'height must be a number, :scale, :native, or :deck' + def validate_height(arg, i) + return @deck.height if arg.to_s == 'deck' + return :native if arg.to_s == 'native' + return arg if arg.respond_to? :to_f + if arg.to_s == 'scale' + raise 'if height is \'scale\', width must be a number' unless width[i].respond_to? :to_f + return arg end - + raise 'height must be a number, :scale, :native, or :deck' end end + end diff --git a/lib/squib/args/sheet.rb b/lib/squib/args/sheet.rb index 3090a4f..4b2b4a9 100644 --- a/lib/squib/args/sheet.rb +++ b/lib/squib/args/sheet.rb @@ -3,170 +3,167 @@ require_relative 'arg_loader' require_relative 'color_validator' require_relative 'dir_validator' -module Squib - # @api private - module Args - - class Sheet - include ArgLoader - include ColorValidator - include DirValidator - - def initialize(custom_colors = {}, dsl_method_defaults = {}, deck_size = 1, dpi = 300) - @custom_colors = custom_colors - @dsl_method_defaults = dsl_method_defaults - @deck_size = deck_size - @dpi = dpi - end +module Squib::Args + module_function def extract_sheet(opts, deck, dsl_method_defaults = {}) + Sheet.new(dsl_method_defaults).extract! opts, deck + end - def self.parameters - { - count_format: '%02d', - crop_margin_bottom: 0, - crop_margin_left: 0, - crop_margin_right: 0, - crop_margin_top: 0, - crop_marks: false, - crop_stroke_color: :black, - crop_stroke_dash: '', - crop_stroke_width: 1.5, - dir: '_output', - file: 'sheet.png', - fill_color: :white, - gap: 0, - height: 2550, - margin: 75, - prefix: 'sheet_', - rows: :infinite, - columns: 5, - trim_radius: 0, - trim: 0, - width: 3300, - range: :all, - rtl: false, - } - end + class Sheet + include ArgLoader + include ColorValidator + include DirValidator - def self.expanding_parameters - [] # none of them - end + def initialize(dsl_method_defaults = {}) + @dsl_method_defaults = dsl_method_defaults + end - def self.params_with_units - [ :crop_margin_bottom, :crop_margin_left, :crop_margin_right, - :crop_margin_top, :gap, :height, :margin, :trim_radius, :trim, - :width - ] - end + def self.parameters + { + count_format: '%02d', + crop_margin_bottom: 0, + crop_margin_left: 0, + crop_margin_right: 0, + crop_margin_top: 0, + crop_marks: false, + crop_stroke_color: :black, + crop_stroke_dash: '', + crop_stroke_width: 1.5, + dir: '_output', + file: 'sheet.png', + fill_color: :white, + gap: 0, + height: 2550, + margin: 75, + prefix: 'sheet_', + rows: :infinite, + columns: 5, + trim_radius: 0, + trim: 0, + width: 3300, + range: :all, + rtl: false, + } + end - def validate_crop_stroke_dash(arg) - arg.to_s.split.collect do |x| - UnitConversion.parse(x, @dpi).to_f - end - end + def self.expanding_parameters + [] # none of them + end - def validate_crop_marks(arg) - arg.to_s.downcase.to_sym unless arg == false - end + def self.params_with_units + [ :crop_margin_bottom, :crop_margin_left, :crop_margin_right, + :crop_margin_top, :gap, :height, :margin, :trim_radius, :trim, + :width + ] + end - def validate_fill_color(arg) - colorify(arg, @custom_colors) + def validate_crop_stroke_dash(arg) + arg.to_s.split.collect do |x| + UnitConversion.parse(x, @deck.dpi).to_f end + end - def validate_dir(arg) - ensure_dir_created(arg) - end + def validate_crop_marks(arg) + arg.to_s.downcase.to_sym unless arg == false + end - def validate_columns(arg) - raise 'columns must be an integer' unless arg.respond_to? :to_i - arg.to_i - end + def validate_fill_color(arg) + colorify(arg, @deck.custom_colors) + end - def validate_rows(arg) - raise 'columns must be an integer' unless columns.respond_to? :to_i - count = if range == :all - @deck_size - else - count = range.to_a.length - end - return 1 if count <= columns - return arg if arg.respond_to? :to_i - (count.to_f / columns.to_f).ceil - end + def validate_dir(arg) + ensure_dir_created(arg) + end - def full_filename(i=nil) - if i.nil? - "#{dir}/#{file}" - else - "#{dir}/#{prefix}#{count_format % i}.png" - end - end + def validate_columns(arg) + raise 'columns must be an integer' unless arg.respond_to? :to_i + arg.to_i + end - def crop_coords(x, y, deck_w, deck_h) - case crop_marks - when false - [] - when :full - [ - { - # Vertical, Left - x1: x + trim + crop_margin_left, y1: 0, - x2: x + trim + crop_margin_left, y2: height - margin + 1 - }, - { - # Vertical, Right - x1: x + deck_w - trim - crop_margin_right, y1: 0, - x2: x + deck_w - trim - crop_margin_right, y2: height - margin + 1 - }, - { - # Horizontal, Top - x1: 0 , y1: y + trim + crop_margin_top, - x2: width - margin + 1, y2: y + trim + crop_margin_top - }, - { - # Horizontal, Bottom - x1: 0 , y1: y + deck_h - trim - crop_margin_bottom, - x2: width - margin + 1, y2: y + deck_h - trim - crop_margin_bottom - }, - ] - else # e.g. :margin - [ - { # Vertical, Upper-left - x1: x + trim + crop_margin_left, y1: 0, - x2: x + trim + crop_margin_left, y2: margin - 1 - }, - { # Vertical , Upper-right - x1: x + deck_w - trim - crop_margin_right, y1: 0, - x2: x + deck_w - trim - crop_margin_right, y2: margin - 1 - }, - { # Vertical , Lower-left - x1: x + trim + crop_margin_left, y1: height, - x2: x + trim + crop_margin_left, y2: height - margin + 1 - }, - { # Vertical , Lower-right - x1: x + deck_w - trim - crop_margin_right, y1: height, - x2: x + deck_w - trim - crop_margin_right, y2: height - margin + 1 - }, - { # Horizontal, Upper-left - x1: 0 , y1: y + trim + crop_margin_top, - x2: margin - 1, y2: y + trim + crop_margin_top - }, - { # Horizontal, Upper-Right - x1: width , y1: y + trim + crop_margin_top, - x2: width - margin + 1, y2: y + trim + crop_margin_top - }, - { # Horizontal, Lower-Left - x1: 0 , y1: y + deck_h - trim - crop_margin_bottom, - x2: margin - 1, y2: y + deck_h - trim - crop_margin_bottom - }, - { # Horizontal, Lower-Right - x1: width, y1: y + deck_h - trim - crop_margin_bottom, - x2: width - margin + 1, y2: y + deck_h - trim - crop_margin_bottom - }, - ] - end + def validate_rows(arg) + raise 'columns must be an integer' unless columns.respond_to? :to_i + count = if range == :all + @deck.size + else + count = range.to_a.length + end + return 1 if count <= columns + return arg if arg.respond_to? :to_i + (count.to_f / columns.to_f).ceil + end + + def full_filename(i=nil) + if i.nil? + "#{dir}/#{file}" + else + "#{dir}/#{prefix}#{count_format % i}.png" end + end + def crop_coords(x, y, deck_w, deck_h) + case crop_marks + when false + [] + when :full + [ + { + # Vertical, Left + x1: x + trim + crop_margin_left, y1: 0, + x2: x + trim + crop_margin_left, y2: height - margin + 1 + }, + { + # Vertical, Right + x1: x + deck_w - trim - crop_margin_right, y1: 0, + x2: x + deck_w - trim - crop_margin_right, y2: height - margin + 1 + }, + { + # Horizontal, Top + x1: 0 , y1: y + trim + crop_margin_top, + x2: width - margin + 1, y2: y + trim + crop_margin_top + }, + { + # Horizontal, Bottom + x1: 0 , y1: y + deck_h - trim - crop_margin_bottom, + x2: width - margin + 1, y2: y + deck_h - trim - crop_margin_bottom + }, + ] + else # e.g. :margin + [ + { # Vertical, Upper-left + x1: x + trim + crop_margin_left, y1: 0, + x2: x + trim + crop_margin_left, y2: margin - 1 + }, + { # Vertical , Upper-right + x1: x + deck_w - trim - crop_margin_right, y1: 0, + x2: x + deck_w - trim - crop_margin_right, y2: margin - 1 + }, + { # Vertical , Lower-left + x1: x + trim + crop_margin_left, y1: height, + x2: x + trim + crop_margin_left, y2: height - margin + 1 + }, + { # Vertical , Lower-right + x1: x + deck_w - trim - crop_margin_right, y1: height, + x2: x + deck_w - trim - crop_margin_right, y2: height - margin + 1 + }, + { # Horizontal, Upper-left + x1: 0 , y1: y + trim + crop_margin_top, + x2: margin - 1, y2: y + trim + crop_margin_top + }, + { # Horizontal, Upper-Right + x1: width , y1: y + trim + crop_margin_top, + x2: width - margin + 1, y2: y + trim + crop_margin_top + }, + { # Horizontal, Lower-Left + x1: 0 , y1: y + deck_h - trim - crop_margin_bottom, + x2: margin - 1, y2: y + deck_h - trim - crop_margin_bottom + }, + { # Horizontal, Lower-Right + x1: width, y1: y + deck_h - trim - crop_margin_bottom, + x2: width - margin + 1, y2: y + deck_h - trim - crop_margin_bottom + }, + ] + end end end + end diff --git a/lib/squib/args/showcase_special.rb b/lib/squib/args/showcase_special.rb index 6975b1c..2209cb2 100644 --- a/lib/squib/args/showcase_special.rb +++ b/lib/squib/args/showcase_special.rb @@ -2,40 +2,40 @@ require 'cairo' require_relative 'arg_loader' require_relative 'dir_validator' -module Squib - # @api private - module Args - - class ShowcaseSpecial - include ArgLoader - include DirValidator - - def self.parameters - { - scale: 0.85, - trim: 0, - trim_radius: 38, - offset: 1.1, - reflect_offset: 15, - reflect_percent: 0.25, - reflect_strength: 0.2, - face: :left, - } - end - - def self.expanding_parameters - [] # none of them - end - - def self.params_with_units - [ :reflect_offset ] - end - - def face_right? - @face.to_s.strip.downcase == 'right' - end +module Squib::Args + module_function def extract_showcase_special(opts, deck) + ShowcaseSpecial.new.extract! opts, deck + end + + class ShowcaseSpecial + include ArgLoader + include DirValidator + + def self.parameters + { + scale: 0.85, + trim: 0, + trim_radius: 38, + offset: 1.1, + reflect_offset: 15, + reflect_percent: 0.25, + reflect_strength: 0.2, + face: :left, + } + end + + def self.expanding_parameters + [] # none of them + end + + def self.params_with_units + [ :reflect_offset ] + end + def face_right? + @face.to_s.strip.downcase == 'right' end end + end diff --git a/lib/squib/args/svg_special.rb b/lib/squib/args/svg_special.rb index e44b4f3..c354438 100644 --- a/lib/squib/args/svg_special.rb +++ b/lib/squib/args/svg_special.rb @@ -1,37 +1,37 @@ require_relative 'arg_loader' -module Squib - # @api private - module Args - - class SvgSpecial - include ArgLoader - - def self.parameters - { data: nil, id: nil, force_id: false } - end +module Squib::Args + module_function def extract_svg_special(opts, deck) + SvgSpecial.new.extract! opts, deck + end + + class SvgSpecial + include ArgLoader - def self.expanding_parameters - parameters.keys # all of them - end + def self.parameters + { data: nil, id: nil, force_id: false } + end - def self.params_with_units - [] - end + def self.expanding_parameters + parameters.keys # all of them + end - def validate_id(arg, _i) - return nil if arg.to_s.empty? - arg = '#' << arg unless arg.start_with? '#' - arg - end + def self.params_with_units + [] + end - # Only render if we have an ID specified, or we are forcing an ID - def render?(i) - return false if force_id[i] && id[i].to_s.empty? - return true - end + def validate_id(arg, _i) + return nil if arg.to_s.empty? + arg = '#' << arg unless arg.start_with? '#' + arg + end + # Only render if we have an ID specified, or we are forcing an ID + def render?(i) + return false if force_id[i] && id[i].to_s.empty? + return true end end + end diff --git a/lib/squib/args/transform.rb b/lib/squib/args/transform.rb index bb0ca42..c051989 100644 --- a/lib/squib/args/transform.rb +++ b/lib/squib/args/transform.rb @@ -1,61 +1,55 @@ require_relative 'arg_loader' -module Squib - # @api private - module Args - - class Transform - include ArgLoader - - def initialize(deck = nil) - @deck = deck - end - - def self.parameters - { angle: 0, - crop_x: 0, - crop_y: 0, - crop_width: :native, - crop_height: :native, - crop_corner_radius: nil, - crop_corner_x_radius: 0, - crop_corner_y_radius: 0, - flip_vertical: false, - flip_horizontal: false, - } - end - - def self.expanding_parameters - parameters.keys # all of them - end - - def self.params_with_units - parameters.keys - [:flip_vertical, :flip_horizontal] - end - - def validate_crop_width(arg, _i) - return arg if @deck.nil? - return @deck.width if arg == :deck - arg - end - - def validate_crop_height(arg, _i) - return arg if @deck.nil? - return @deck.height if arg == :deck - arg - end - - def validate_crop_corner_x_radius(arg, i) - return crop_corner_radius[i] unless crop_corner_radius[i].nil? - arg - end - - def validate_crop_corner_y_radius(arg, i) - return crop_corner_radius[i] unless crop_corner_radius[i].nil? - arg - end +module Squib::Args + module_function def extract_transform(opts, deck) + Transform.new.extract!(opts, deck) + end + + class Transform + include ArgLoader + + def self.parameters + { angle: 0, + crop_x: 0, + crop_y: 0, + crop_width: :native, + crop_height: :native, + crop_corner_radius: nil, + crop_corner_x_radius: 0, + crop_corner_y_radius: 0, + flip_vertical: false, + flip_horizontal: false, + } + end + + def self.expanding_parameters + parameters.keys # all of them + end + + def self.params_with_units + parameters.keys - [:flip_vertical, :flip_horizontal] + end + + def validate_crop_width(arg, _i) + return arg if @deck.nil? + return @deck.width if arg == :deck + arg + end + def validate_crop_height(arg, _i) + return arg if @deck.nil? + return @deck.height if arg == :deck + arg end + def validate_crop_corner_x_radius(arg, i) + return crop_corner_radius[i] unless crop_corner_radius[i].nil? + arg + end + + def validate_crop_corner_y_radius(arg, i) + return crop_corner_radius[i] unless crop_corner_radius[i].nil? + arg + end end end diff --git a/lib/squib/deck.rb b/lib/squib/deck.rb index e318f00..8a58324 100644 --- a/lib/squib/deck.rb +++ b/lib/squib/deck.rb @@ -105,7 +105,6 @@ module Squib require_relative 'dsl/background' require_relative 'api/data' require_relative 'api/groups' - require_relative 'api/image' require_relative 'api/save' require_relative 'api/settings' require_relative 'api/shapes' @@ -117,6 +116,9 @@ module Squib ################### require_relative 'dsl/background' require_relative 'dsl/grid' + require_relative 'dsl/png' + require_relative 'dsl/showcase' + require_relative 'dsl/svg' end end diff --git a/lib/squib/dsl/png.rb b/lib/squib/dsl/png.rb new file mode 100644 index 0000000..b7d1042 --- /dev/null +++ b/lib/squib/dsl/png.rb @@ -0,0 +1,56 @@ +require_relative '../errors_warnings/warn_unexpected_params' +require_relative '../args/card_range' +require_relative '../args/paint' +require_relative '../args/scale_box' +require_relative '../args/transform' +require_relative '../args/input_file' + +module Squib + class Deck + def png(opts = {}) + DSL::PNG.new(self, __callee__).run(opts) + end + end + + module DSL + class PNG + include WarnUnexpectedParams + attr_reader :dsl_method, :deck + + def initialize(deck, dsl_method) + @deck = deck + @dsl_method = dsl_method + end + + def self.accepted_params + %i( + file + x y width height + alpha blend mask angle + crop_x crop_y crop_width crop_height + crop_corner_radius crop_corner_x_radius crop_corner_y_radius + flip_horizontal flip_vertical + range layout + ) + end + + def run(opts) + warn_if_unexpected opts + Dir.chdir(deck.img_dir) do + range = Args.extract_range opts, deck + paint = Args.extract_paint opts, deck + box = Args.extract_scale_box opts, deck + trans = Args.extract_transform opts, deck + ifile = Args.extract_input_file opts, deck + deck.progress_bar.start('Loading PNG(s)', range.size) do |bar| + range.each do |i| + deck.cards[i].png(ifile[i].file, box[i], paint[i], trans[i]) + bar.increment + end + end + end + + end + end + end +end diff --git a/lib/squib/dsl/showcase.rb b/lib/squib/dsl/showcase.rb new file mode 100644 index 0000000..3a8d67a --- /dev/null +++ b/lib/squib/dsl/showcase.rb @@ -0,0 +1,43 @@ +require_relative '../errors_warnings/warn_unexpected_params' +require_relative '../args/card_range' +require_relative '../args/showcase_special' +require_relative '../args/sheet' + +module Squib + class Deck + def showcase(opts = {}) + DSL::Showcase.new(self, __callee__).run(opts) + end + end + + module DSL + class Showcase + include WarnUnexpectedParams + attr_reader :dsl_method, :deck + + def initialize(deck, dsl_method) + @deck = deck + @dsl_method = dsl_method + end + + def self.accepted_params + %i( + file dir + trim trim_radius + scale offset fill_color + reflect_offset reflect_strength reflect_percent + face margin + range + ) + end + + def run(opts) + warn_if_unexpected opts + range = Args.extract_range opts, deck + showcase = Args.extract_showcase_special opts, deck + sheet = Args.extract_sheet opts, deck, { file: 'showcase.png' } + deck.render_showcase(range, sheet, showcase) + end + end + end +end diff --git a/lib/squib/dsl/svg.rb b/lib/squib/dsl/svg.rb new file mode 100644 index 0000000..2707a9e --- /dev/null +++ b/lib/squib/dsl/svg.rb @@ -0,0 +1,62 @@ +require_relative '../errors_warnings/warn_unexpected_params' +require_relative '../args/card_range' +require_relative '../args/paint' +require_relative '../args/scale_box' +require_relative '../args/transform' +require_relative '../args/input_file' +require_relative '../args/svg_special' + +module Squib + class Deck + def svg(opts = {}) + DSL::SVG.new(self, __callee__).run(opts) + end + end + + module DSL + class SVG + include WarnUnexpectedParams + attr_reader :dsl_method, :deck + + def initialize(deck, dsl_method) + @deck = deck + @dsl_method = dsl_method + end + + def self.accepted_params + %i( + file + x y width height + blend mask + crop_x crop_y crop_width crop_height + crop_corner_radius crop_corner_x_radius crop_corner_y_radius + flip_horizontal flip_vertical angle + id force_id data + range layout + ) + end + + def run(opts) + warn_if_unexpected opts + Dir.chdir(deck.img_dir) do + range = Args.extract_range opts, deck + paint = Args.extract_paint opts, deck + box = Args.extract_scale_box opts, deck + trans = Args.extract_transform opts, deck + ifile = Args.extract_input_file opts, deck + svg_args = Args.extract_svg_special opts, deck + deck.progress_bar.start('Loading PNG(s)', range.size) do |bar| + range.each do |i| + if svg_args.render?(i) + deck.cards[i].svg(ifile[i].file, svg_args[i], box[i], paint[i], + trans[i]) + end + bar.increment + end + end + end + + end + end + end +end diff --git a/spec/args/box_spec.rb b/spec/args/box_spec.rb index 75113ab..9a2428a 100644 --- a/spec/args/box_spec.rb +++ b/spec/args/box_spec.rb @@ -107,18 +107,19 @@ describe Squib::Args::Box do end context 'validation' do + let(:deck) { OpenStruct.new(width: 123, height: 456, size: 1) } + it 'replaces with deck width and height' do args = { width: :deck, height: :deck } - deck = OpenStruct.new(width: 123, height: 456) - box = Squib::Args::Box.new(deck) - box.load!(args, expand_by: 1) + box = Squib::Args::Box.new + box.extract! args, deck expect(box).to have_attributes(width: [123], height: [456]) end it 'has radius override x_radius and y_radius' do args = { x_radius: 1, y_radius: 2, radius: 3 } - box.load!(args, expand_by: 2) - expect(box).to have_attributes(x_radius: [3, 3], y_radius: [3, 3]) + box.extract! args, deck + expect(box).to have_attributes(x_radius: [3], y_radius: [3]) end end diff --git a/spec/args/scale_box_spec.rb b/spec/args/scale_box_spec.rb index 0f79bea..8ca1b16 100644 --- a/spec/args/scale_box_spec.rb +++ b/spec/args/scale_box_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' require 'squib/args/scale_box' describe Squib::Args::ScaleBox do - subject(:box) { Squib::Args::ScaleBox.new({}) } + subject(:box) { Squib::Args::ScaleBox.new } context 'unit conversion' do it 'converts units on all args' do diff --git a/spec/args/sheet_spec.rb b/spec/args/sheet_spec.rb index 7a40129..0e3d205 100644 --- a/spec/args/sheet_spec.rb +++ b/spec/args/sheet_spec.rb @@ -2,58 +2,60 @@ require 'spec_helper' require 'squib/args/sheet' describe Squib::Args::Sheet do + let(:deck) { OpenStruct.new(size: 4, custom_colors: {}) } context 'dsl overrides' do - subject(:sheet) { Squib::Args::Sheet.new({}, { file: 'foo' }) } + subject(:sheet) { Squib::Args::Sheet.new({ file: 'foo' }) } it 'works when specified' do - sheet.load!({}) # go right to defaults + opts = {} + sheet.extract! opts, deck # go right to defaults expect(sheet.file).to eq('foo') # dsl method default override end end context 'rows and colums' do - subject(:sheet) { Squib::Args::Sheet.new({}, {}, 4) } + subject(:sheet) { Squib::Args::Sheet.new } it 'does nothing on a perfect fit' do opts = { columns: 2, rows: 2 } - sheet.load! opts + sheet.extract! opts, deck expect(sheet).to have_attributes(columns: 2, rows: 2) end it 'keeps both if specified' do opts = { columns: 1, rows: 1 } - sheet.load! opts + sheet.extract! opts, deck expect(sheet).to have_attributes(columns: 1, rows: 1) end it 'computes properly on non-integer' do opts = { columns: 1, rows: :infinite } - sheet.load! opts + sheet.extract! opts, deck expect(sheet).to have_attributes(columns: 1, rows: 4) end it 'computes properly on unspecified rows' do opts = { columns: 1 } - sheet.load! opts + sheet.extract! opts, deck expect(sheet).to have_attributes(columns: 1, rows: 4) end it 'computes properly on unspecified, too-big column' do opts = {} - sheet.load! opts + sheet.extract! opts, deck expect(sheet).to have_attributes(columns: 5, rows: 1) end it 'fails on a non-integer column' do opts = { columns: :infinite } - expect { sheet.load!(opts) }.to raise_error('columns must be an integer') + expect { sheet.extract!(opts, deck) }.to raise_error('columns must be an integer') end end context 'crop marks' do - subject(:sheet) { Squib::Args::Sheet.new({}, {}, 4) } + subject(:sheet) { Squib::Args::Sheet.new } it 'computes crop marks properly' do opts = { @@ -65,7 +67,7 @@ describe Squib::Args::Sheet do crop_margin_right: 40, crop_margin_bottom: 50, } - expect(sheet.load!(opts).crop_coords(3,4, 300, 400)).to eq( + expect(sheet.extract!(opts, deck).crop_coords(3,4, 300, 400)).to eq( [ {:x1=>43, :y1=>0, :x2=>43, :y2=>74}, {:x1=>253, :y1=>0, :x2=>253, :y2=>74}, {:x1=>43, :y1=>1100, :x2=>43, :y2=>1026}, diff --git a/spec/args/svg_special_spec.rb b/spec/args/svg_special_spec.rb index dc03812..c67215a 100644 --- a/spec/args/svg_special_spec.rb +++ b/spec/args/svg_special_spec.rb @@ -1,5 +1,6 @@ require 'spec_helper' require 'squib/args/box' +require 'squib/args/svg_special' describe Squib::Args::SvgSpecial do subject(:svgargs) { Squib::Args::SvgSpecial.new } diff --git a/spec/args/transform_spec.rb b/spec/args/transform_spec.rb index 7bd3fa4..f0baa73 100644 --- a/spec/args/transform_spec.rb +++ b/spec/args/transform_spec.rb @@ -8,15 +8,16 @@ describe Squib::Args::Box do context 'validation' do it 'replaces with deck width and height' do args = { crop_width: :deck, crop_height: :deck } - deck = OpenStruct.new(width: 123, height: 456) - trans = Squib::Args::Transform.new(deck) - trans.load!(args, expand_by: 1) + deck = OpenStruct.new(width: 123, height: 456, size: 1) + trans = Squib::Args::Transform.new + trans.extract! args, deck expect(trans).to have_attributes(crop_width: [123], crop_height: [456]) end it 'has radius override x_radius and y_radius' do args = { crop_corner_x_radius: 1, crop_corner_y_radius: 2, crop_corner_radius: 3 } - trans.load!(args, expand_by: 2) + deck = OpenStruct.new(width: 123, height: 456, size: 2) + trans.extract! args, deck expect(trans).to have_attributes(crop_corner_x_radius: [3, 3], crop_corner_y_radius: [3, 3]) end diff --git a/spec/docs/options_documented_spec.rb b/spec/docs/options_documented_spec.rb index d1b121d..bd9d674 100644 --- a/spec/docs/options_documented_spec.rb +++ b/spec/docs/options_documented_spec.rb @@ -5,8 +5,9 @@ describe Squib::DSL do Squib::DSL.constants.each do |m| it "accepted params for #{m} are in the docs" do - accepted_params = Squib::DSL.const_get(m).accepted_params - expect(accepted_params).to eq(documented_options(m)) + accepted_params = Squib::DSL.const_get(m).accepted_params.sort + documented_opts = documented_options(m).sort + expect(accepted_params).to eq(documented_opts) end end