diff --git a/README.md b/README.md index 586a0ac..b3c7f64 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ See the `custom_config` sample found [here](https://github.com/andymeneely/squib {include:file:samples/custom_config.rb} -# Squib Principles and Patterns +# Squib Best Practices and Patterns I am eating my own dogfood and using Squib for prototyping my own games. From that experience, here are some pieces of advice. They are really just re-hashing of common Ruby community and good software engineering practices. @@ -212,6 +212,10 @@ By default, Squib assumes Git. But it's not dogmatic about it. Tracking your pro For me, I tend to ignore any auto-generated files in my output folder, but version control everything else. I also try to keep my graphics vector files, so the files stay small. Version control is intended for source code, so large binary files don't usually get checked in unless absolutely necessary. +## Decks with multiple orientations or sizes + +If you want to make a deck that has some portrait and some landscape cards, I recommend you use multiple `Squib::Deck`s. The pixel size of a given card is designed to not change thorughout the life of a `Squib::Deck`. To work with landscape cards, there is a `rotate` option on `save_png` so your print-on-demand PNGs can still be in portrait. + # Development Squib is currently in pre-release alpha, so the API is still maturing. If you are using Squib, however, I'd love to hear about it! Feel free to [file a bug or feature request](https://github.com/andymeneely/squib/issues). diff --git a/lib/squib/api/save.rb b/lib/squib/api/save.rb index b49a27b..afcdd23 100644 --- a/lib/squib/api/save.rb +++ b/lib/squib/api/save.rb @@ -7,10 +7,11 @@ module Squib # @option opts [String] dir (_output) the directory for the output to be sent to. Will be created if it doesn't exist. # @option opts [Symbol] format (:png) the format that this will be rendered too. Options `:pdf, :png`. Array of both is allowed: `[:pdf, :png]` # @option opts [String] prefix (card_) the prefix of the file name to be printed + # @option opts [Boolean] rotate (false) PNG saving only. If true, the saved cards will be rotated 90 degrees clockwise. Intended to rendering landscape instead of portrait. # @return self # @api public def save(opts = {}) - opts = needs(opts, [:range, :creatable_dir, :formats, :prefix]) + opts = needs(opts, [:range, :creatable_dir, :formats, :prefix, :rotate]) save_png(opts) if opts[:format].include? :png save_pdf(opts) if opts[:format].include? :pdf self @@ -24,17 +25,19 @@ module Squib # @option opts [Enumerable] range (:all) the range of cards over which this will be rendered. See {file:README.md#Specifying_Ranges Specifying Ranges} # @option opts [String] dir (_output) the directory for the output to be sent to. Will be created if it doesn't exist. # @option opts [String] prefix (card_) the prefix of the file name to be printed. + # @option opts [Boolean] rotate (false) if true, the saved cards will be rotated 90 degrees clockwise. Intended to rendering landscape instead of portrait. # @return [nil] Returns nothing # @api public def save_png(opts = {}) - opts = needs(opts,[:range, :creatable_dir, :prefix]) + opts = needs(opts,[:range, :creatable_dir, :prefix, :rotate]) @progress_bar.start("Saving PNGs to #{opts[:dir]}/#{opts[:prefix]}*") do |bar| opts[:range].each do |i| - @cards[i].save_png(i, opts[:dir], opts[:prefix]) + @cards[i].save_png(i, opts[:dir], opts[:prefix], opts[:rotate]) bar.increment end end end end -end \ No newline at end of file +end + diff --git a/lib/squib/constants.rb b/lib/squib/constants.rb index 0f1a5e7..10ffa1e 100644 --- a/lib/squib/constants.rb +++ b/lib/squib/constants.rb @@ -20,6 +20,7 @@ module Squib :prefix => "card_", :progress_bar => false, :range => :all, + :rotate => false, :sheet => 0, :spacing => 0, :str => '', diff --git a/lib/squib/graphics/save_images.rb b/lib/squib/graphics/save_images.rb index 4635f8b..7852193 100644 --- a/lib/squib/graphics/save_images.rb +++ b/lib/squib/graphics/save_images.rb @@ -3,8 +3,30 @@ module Squib # :nodoc: # @api private - def save_png(i, dir, prefix) - cairo_context.target.write_to_png("#{dir}/#{prefix}#{i}.png") + def save_png(i, dir, prefix, rotate) + if rotate + surface = rotated_image + else + surface = @cairo_surface + end + write_png(surface, i, dir, prefix) + end + + # :nodoc: + # @api private + def rotated_image + rotated_cc = Cairo::Context.new(Cairo::ImageSurface.new(@height, @width) ) + rotated_cc.translate(@height * 0.5, @width * 0.5) + rotated_cc.rotate(0.5 * Math::PI) + rotated_cc.translate(@width * -0.5, @height * -0.5) + rotated_cc.set_source(@cairo_surface) + rotated_cc.paint + rotated_cc.target + end + # :nodoc: + # @api private + def write_png(surface, i, dir, prefix) + surface.write_to_png("#{dir}/#{prefix}#{i}.png") end end diff --git a/samples/portrait-landscape.rb b/samples/portrait-landscape.rb new file mode 100644 index 0000000..837b7b8 --- /dev/null +++ b/samples/portrait-landscape.rb @@ -0,0 +1,23 @@ +require 'squib' + +# For decks with both landscape and portrait orientations, +# we recommend using two separate decks. +# For print-on-demand, we can rotate all of the images in the final step. + +# Normal cards +Squib::Deck.new(width: 825, height: 1125) do + background color: '#aaa' + + text str: "This is portrait" + + save_png prefix: "portrait_" +end + +# Money cards are landscape +Squib::Deck.new(width: 1125, height: 825) do + background color: '#aaa' + + text str: "This is landscape" + + save_png prefix: "landscape_", rotate: true +end \ No newline at end of file