diff --git a/CHANGELOG.md b/CHANGELOG.md index c5b49cf..7ac812b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,11 @@ # Squib CHANGELOG +* Unit conversion! Now you can write "2in" and it will convert based on the current dpi. `save_pdf` not supported (yet). * `png` now supports resizing, but warns you about it since it's non-ideal. Documented in yard, tested. * Added sample `unicode.rb` to show lots of game-related unicode characters ## v0.0.6 -* Added a `csv` command that works just like `xslx`. Uses Ruby's CSV inside, with some extra checking and warnings. +* Added a `csv` command that works just like `xslx`. Uses Ruby's CSV inside, with some extra checking and warnings. * Custom layouts now support loading & merging multiple Yaml files! Updated README, docs, and sample to document it. * Built-in layouts! Currently we support `hand.yml` and `playing-card.yml`. Documented in the `layouts.rb` sample. * `text` now returns the ink extent rectangle of the rendered text. Updated docs and sample to document it. diff --git a/README.md b/README.md index a74ea83..f629c2e 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,15 @@ # Squib [![Gem Version](https://badge.fury.io/rb/squib.svg)](https://rubygems.org/gems/squib) [![Build Status](https://secure.travis-ci.org/andymeneely/squib.svg?branch=master)](https://travis-ci.org/andymeneely/squib) [![Dependency Status](https://gemnasium.com/andymeneely/squib.svg)](https://gemnasium.com/andymeneely/squib) [![Coverage Status](https://img.shields.io/coveralls/andymeneely/squib.svg)](https://coveralls.io/r/andymeneely/squib) [![Inline docs](http://inch-ci.org/github/andymeneely/squib.png?branch=master)](http://inch-ci.org/github/andymeneely/squib) -Squib is a Ruby [DSL](http://en.wikipedia.org/wiki/Domain-specific_language) for prototyping card and board games. With Squib, you just write a little bit of Ruby and you can compile your game's data and images into a series of images ready for print-and-play or even print-on-demand. Squib is very data-driven - think of it like [nanDeck](http://www.nand.it/nandeck/) done "the Ruby way". Squib supports: +Squib is a Ruby [DSL](http://en.wikipedia.org/wiki/Domain-specific_language) for prototyping card and board games. Write a little bit of Ruby, define your deck's stats, and you can compile your game into a series of images ready for print-and-play or even print-on-demand. Squib is very data-driven and built with DRY (Don't Repeat Yourself) in mind. Think of it like [nanDeck](http://www.nand.it/nandeck/) done "the Ruby way". Squib supports: * A concise set of rules for laying out your cards * Loading PNGs and SVGs using [Cairo](http://cairographics.org/) * Complex text rendering using [Pango](http://www.pango.org/) * Reading `xlsx` and `csv` files +* Rendering to individual PNGs or PDF sheets +* Flexible, data-driven layouts in Yaml * Basic shape drawing -* Rendering decks to PNGs and PDFs -* Data-driven layouts * Unit conversion +* Obsessively and fanatically tested by its author * Plus the full power of Ruby! Check this out. @@ -137,9 +138,9 @@ Most public `Deck` methods allow a `range` to be specified as a first parameter. {include:file:samples/ranges.rb} -## Pixels and Other Units +## Units -By default, Squib thinks in pixels. This decision was made so that we can have pixel-perfect layouts without automatically scaling everything, even though working in units is sometimes easier. To convert, we provide the `Deck#inch` method, as shown in `samples/units.rb` found [here](https://github.com/andymeneely/squib/tree/master/samples/units.rb) +By default, Squib thinks in pixels. This decision was made so that we can have pixel-perfect layouts without automatically scaling everything, even though working in units is sometimes easier. We provide some conversion methods, including looking for strings that end in "in" and "cm" and computing based on the current DPI. Example is in `samples/units.rb` found [here](https://github.com/andymeneely/squib/tree/master/samples/units.rb) {include:file:samples/units.rb} diff --git a/lib/squib/api/image.rb b/lib/squib/api/image.rb index 583d338..4d2fcea 100644 --- a/lib/squib/api/image.rb +++ b/lib/squib/api/image.rb @@ -9,10 +9,10 @@ module Squib # # @option opts range [Enumerable, :all] (:all) the range of cards over which this will be rendered. See {file:README.md#Specifying_Ranges Specifying Ranges} # @option opts file [String] ((empty)) file(s) to read in. If it's a single file, then it's use for every card in range. If the parameter is an Array of files, then each file is looked up for each card. If any of them are nil or '', nothing is done. See {file:README.md#Specifying_Files Specifying Files}. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} - # @option opts x [Integer] (0) the x-coordinate to place. Supports Arrays, see {file:README#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} - # @option opts y [Integer] (0) the y-coordinate to place. Supports Arrays, see {file:README#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} - # @option opts width [Integer] (:native) the pixel width that the image should scale to. Scaling PNGs is not recommended for professional-looking cards. When set to `:native`, uses the DPI and units of the loaded SVG document. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} - # @option opts height [Integer] (:native) the pixel width that the image should scale to. Scaling PNGs is not recommended for professional-looking cards. When set to `:native`, uses the DPI and units of the loaded SVG document. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} + # @option opts x [Integer] (0) the x-coordinate to place. Supports Arrays, see {file:README#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts y [Integer] (0) the y-coordinate to place. Supports Arrays, see {file:README#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts width [Integer] (:native) the pixel width that the image should scale to. Scaling PNGs is not recommended for professional-looking cards. When set to `:native`, uses the DPI and units of the loaded SVG document. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts height [Integer] (:native) the pixel width that the image should scale to. Scaling PNGs is not recommended for professional-looking cards. When set to `:native`, uses the DPI and units of the loaded SVG document. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}. Supports Unit Conversion, see {file:README#Units Units}. # @option opts layout [String, Symbol] (nil) entry in the layout to use as defaults for this command. See {file:README.md#Custom_Layouts Custom Layouts}. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts alpha [Decimal] (1.0) the alpha-transparency percentage used to blend this image. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts blend [:none, :multiply, :screen, :overlay, :darken, :lighten, :color_dodge, :color_burn, :hard_light, :soft_light, :difference, :exclusion, :hsl_hue, :hsl_saturation, :hsl_color, :hsl_luminosity] (:none) the composite blend operator used when applying this image. See Blend Modes at http://cairographics.org/operators. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} @@ -43,10 +43,10 @@ module Squib # @option opts file [String] ('') file(s) to read in. If it's a single file, then it's use for every card in range. If the parameter is an Array of files, then each file is looked up for each card. If any of them are nil or '', nothing is done. See {file:README.md#Specifying_Files Specifying Files}. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts id [String] (nil) if set, then only render the SVG element with the given id. Prefix '#' is optional. Note: the x-y coordinates are still relative to the SVG document's page. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts force_id [Boolean] (false) if set, then this svg will not be rendered at all if the id is empty or nil. If not set, the entire SVG is rendered. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} - # @option opts x [Integer] (0) the x-coordinate to place. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} - # @option opts y [Integer] (0) the y-coordinate to place. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} - # @option opts width [Integer] (:native) the pixel width that the image should scale to. SVG scaling is done with vectors, so the scaling should be smooth. When set to `:native`, uses the DPI and units of the loaded SVG document. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} - # @option opts height [Integer] (:native) the pixel width that the image should scale to. SVG scaling is done with vectors, so the scaling should be smooth. When set to `:native`, uses the DPI and units of the loaded SVG document. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} + # @option opts x [Integer] (0) the x-coordinate to place. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts y [Integer] (0) the y-coordinate to place. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts width [Integer] (:native) the pixel width that the image should scale to. SVG scaling is done with vectors, so the scaling should be smooth. When set to `:native`, uses the DPI and units of the loaded SVG document. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts height [Integer] (:native) the pixel width that the image should scale to. SVG scaling is done with vectors, so the scaling should be smooth. When set to `:native`, uses the DPI and units of the loaded SVG document. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}. Supports Unit Conversion, see {file:README#Units Units}. # @option opts layout [String, Symbol] (nil) entry in the layout to use as defaults for this command. See {file:README.md#Custom_Layouts Custom Layouts}. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts alpha [Decimal] (1.0) the alpha-transparency percentage used to blend this image. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # @option opts blend [:none, :multiply, :screen, :overlay, :darken, :lighten, :color_dodge, :color_burn, :hard_light, :soft_light, :difference, :exclusion, :hsl_hue, :hsl_saturation, :hsl_color, :hsl_luminosity] (:none) the composite blend operator used when applying this image. See Blend Modes at http://cairographics.org/operators. Supports Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} diff --git a/lib/squib/api/shapes.rb b/lib/squib/api/shapes.rb index a6b3679..9650b18 100644 --- a/lib/squib/api/shapes.rb +++ b/lib/squib/api/shapes.rb @@ -9,16 +9,16 @@ module Squib # Options support Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # # @option opts range [Enumerable, :all] (:all) the range of cards over which this will be rendered. See {file:README.md#Specifying_Ranges Specifying Ranges} - # @option opts x [Integer] (0) the x-coordinate to place - # @option opts y [Integer] (0) the y-coordinate to place - # @option opts width [Integer] the width of the rectangle. - # @option opts height [Integer] the height of the rectangle. - # @option opts x_radius [Integer] (0) the radius of the rounded corner horiztonally. Zero is a non-rounded corner. - # @option opts y_radius [Integer] (0) the radius of the rounded corner vertically. Zero is a non-rounded corner. - # @option opts radius [Integer] (nil) when set, overrides both x_radius and y_radius + # @option opts x [Integer] (0) the x-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts y [Integer] (0) the y-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts width [Integer] the width of the rectangle. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts height [Integer] the height of the rectangle. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts x_radius [Integer] (0) the radius of the rounded corner horiztonally. Zero is a non-rounded corner. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts y_radius [Integer] (0) the radius of the rounded corner vertically. Zero is a non-rounded corner. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts radius [Integer] (nil) when set, overrides both x_radius and y_radius. Supports Unit Conversion, see {file:README#Units Units}. # @option opts fill_color [String] ('#0000') the color with which to fill the rectangle # @option opts stroke_color [String] (:black) the color with which to stroke the outside of the rectangle - # @option opts stroke_width [Decimal] (2.0) the width of the outside stroke + # @option opts stroke_width [Decimal] (2.0) the width of the outside stroke. Supports Unit Conversion, see {file:README#Units Units}. # @option opts layout [String, Symbol] (nil) entry in the layout to use as defaults for this command. See {file:README.md#Custom_Layouts Custom Layouts} # @return [nil] intended to be void # @api public @@ -41,12 +41,12 @@ module Squib # Options support Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # # @option opts range [Enumerable, :all] (:all) the range of cards over which this will be rendered. See {file:README.md#Specifying_Ranges Specifying Ranges} - # @option opts x [Integer] (0) the x-coordinate to place - # @option opts y [Integer] (0) the y-coordinate to place - # @option opts radius [Integer] (100) radius of the circle + # @option opts x [Integer] (0) the x-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts y [Integer] (0) the y-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts radius [Integer] (100) radius of the circle. Supports Unit Conversion, see {file:README#Units Units}. # @option opts fill_color [String] ('#0000') the color with which to fill the rectangle # @option opts stroke_color [String] (:black) the color with which to stroke the outside of the rectangle - # @option opts stroke_width [Decimal] (2.0) the width of the outside stroke + # @option opts stroke_width [Decimal] (2.0) the width of the outside stroke. Supports Unit Conversion, see {file:README#Units Units}. # @return [nil] intended to be void # @api public def circle(opts = {}) @@ -67,15 +67,15 @@ module Squib # Options support Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion} # # @option opts range [Enumerable, :all] (:all) the range of cards over which this will be rendered. See {file:README.md#Specifying_Ranges Specifying Ranges} - # @option opts x1 [Integer] (0) the x-coordinate to place - # @option opts y1 [Integer] (0) the y-coordinate to place - # @option opts x2 [Integer] (50) the x-coordinate to place - # @option opts y2 [Integer] (50) the y-coordinate to place - # @option opts x3 [Integer] (0) the x-coordinate to place - # @option opts y3 [Integer] (50) the y-coordinate to place + # @option opts x1 [Integer] (0) the x-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts y1 [Integer] (0) the y-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts x2 [Integer] (50) the x-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts y2 [Integer] (50) the y-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts x3 [Integer] (0) the x-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts y3 [Integer] (50) the y-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. # @option opts fill_color [String] ('#0000') the color with which to fill the triangle # @option opts stroke_color [String] (:black) the color with which to stroke the outside of the triangle - # @option opts stroke_width [Decimal] (2.0) the width of the outside stroke + # @option opts stroke_width [Decimal] (2.0) the width of the outside stroke. Supports Unit Conversion, see {file:README#Units Units}. # @return [nil] intended to be void # @api public def triangle(opts = {}) @@ -96,12 +96,12 @@ module Squib # triangle :x1 => 0, :y1 => 0, :x2 => 50, :y2 => 50 # # @option opts range [Enumerable, :all] (:all) the range of cards over which this will be rendered. See {file:README.md#Specifying_Ranges Specifying Ranges} - # @option opts x1 [Integer] (0) the x-coordinate to place - # @option opts y1 [Integer] (0) the y-coordinate to place - # @option opts x2 [Integer] (50) the x-coordinate to place - # @option opts y2 [Integer] (50) the y-coordinate to place + # @option opts x1 [Integer] (0) the x-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts y1 [Integer] (0) the y-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts x2 [Integer] (50) the x-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts y2 [Integer] (50) the y-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. # @option opts stroke_color [String] (:black) the color with which to stroke the line - # @option opts stroke_width [Decimal] (2.0) the width of the outside stroke + # @option opts stroke_width [Decimal] (2.0) the width of the outside stroke. Supports Unit Conversion, see {file:README#Units Units}. # @return [nil] intended to be void # @api public def line(opts = {}) diff --git a/lib/squib/api/text.rb b/lib/squib/api/text.rb index f9d4e98..bbd4358 100644 --- a/lib/squib/api/text.rb +++ b/lib/squib/api/text.rb @@ -20,12 +20,12 @@ module Squib # This [description](http://www.pygtk.org/pygtk2reference/class-pangofontdescription.html) is also quite good. # See the {file:samples/text-options.rb samples/text.rb} as well. # @option opts font_size [Integer] (nil) an override of font string description, for scaling the font according to the size of the string - # @option opts x [Integer] (0) the x-coordinate to place - # @option opts y [Integer] (0) the y-coordinate to place + # @option opts x [Integer] (0) the x-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts y [Integer] (0) the y-coordinate to place. Supports Unit Conversion, see {file:README#Units Units}. # @option opts color [String] (:black) the color the font will render to. See {file:README.md#Specifying_Colors Specifying Colors} # @option opts markup: [Boolean] (false) Enable markup parsing of `str` using the HTML-like Pango Markup syntax, defined [here](http://ruby-gnome2.sourceforge.jp/hiki.cgi?pango-markup) and [here](https://developer.gnome.org/pango/stable/PangoMarkupFormat.html). - # @option opts width [Integer, :native] (:native) the width of the box the string will be placed in. Stretches to the content by default. - # @option opts height [Integer, :native] the height of the box the string will be placed in. Stretches to the content by default. + # @option opts width [Integer, :native] (:native) the width of the box the string will be placed in. Stretches to the content by default.. Supports Unit Conversion, see {file:README#Units Units}. + # @option opts height [Integer, :native] the height of the box the string will be placed in. Stretches to the content by default. Supports Unit Conversion, see {file:README#Units Units}. # @option opts layout [String, Symbol] (nil) entry in the layout to use as defaults for this command. See {file:README.md#Custom_Layouts Custom Layouts} # @option opts wrap [:none, :word, :char, :word_char, true, false] (:word_char) When height is set, determines the behavior of how the string wraps. The `:word_char` option will break at words, but then fall back to characters when the word cannot fit. # # Options are `:none, :word, :char, :word_char`. Also: `true` is the same as `:word_char`, `false` is the same as `:none`. Default `:word_char` diff --git a/lib/squib/api/units.rb b/lib/squib/api/units.rb index 5efb14b..498a3ed 100644 --- a/lib/squib/api/units.rb +++ b/lib/squib/api/units.rb @@ -10,7 +10,20 @@ module Squib # @return [Decimal] the number of pixels, according to the deck's DPI # @api public def inches(n) - @dpi * n + @dpi * n.to_f + end + + @@INCHES_IN_CM = 0.393700787 + # Given cm, returns the number of pixels according to the deck's DPI. + # + # @example + # cm(1) # 750 (for default Deck::dpi of 300) + # + # @param n [Decimal], the number of centimeters + # @return [Decimal] the number of pixels, according to the deck's DPI + # @api public + def cm(n) + @dpi * @@INCHES_IN_CM * n.to_f end end diff --git a/lib/squib/constants.rb b/lib/squib/constants.rb index f8834bc..717f861 100644 --- a/lib/squib/constants.rb +++ b/lib/squib/constants.rb @@ -106,4 +106,30 @@ module Squib :y3 => :y3, :y_radius => :y_radius, } + + # These parameters are considered for unit conversion + # + # For example + # text str: 'Hello, World', x: '1in' + # + # key: the internal name of the param (e.g. :circle_radius) + # value: the user-facing API key (e.g. radius: '1in') + UNIT_CONVERSION_PARAMS = { + :circle_radius => :radius, + :height => :height, + :rect_radius => :radius, + :spacing => :spacing, + :stroke_width => :stroke_width, + :width => :width, + :x => :x, + :x1 => :x1, + :x2 => :x2, + :x3 => :x3, + :x_radius => :x_radius, + :y => :y, + :y1 => :y1, + :y2 => :y2, + :y3 => :y3, + :y_radius => :y_radius, + } end diff --git a/lib/squib/input_helpers.rb b/lib/squib/input_helpers.rb index 1fa7aca..c2da542 100644 --- a/lib/squib/input_helpers.rb +++ b/lib/squib/input_helpers.rb @@ -1,4 +1,5 @@ require 'squib/constants' +require 'squib/api/units' module Squib # :nodoc: @@ -27,6 +28,7 @@ module Squib opts = svgidify(opts) if params.include? :svgid opts = formatify(opts) if params.include? :formats opts = rotateify(opts) if params.include? :rotate + opts = convert_units(opts, params) opts end module_function :needs @@ -188,7 +190,29 @@ module Squib Squib.logger.debug {"After rotateify: #{opts}"} opts end - module_function :svgidify + module_function :rotateify + + @@INCHES_IN_CM = 0.393700787 + # Convert units + # :nodoc: + # @api private + def convert_units(opts, needed_params) + Squib::UNIT_CONVERSION_PARAMS.each_pair do |param_name, api_param| + if needed_params.include? param_name + opts[api_param].each_with_index do |arg, i| + case arg.to_s + when /in$/ #ends with "in" + opts[api_param][i] = arg[0..-2].to_f * @dpi + when /cm$/ #ends with "cm" + opts[api_param][i] = arg[0..-2].to_f * @dpi * @@INCHES_IN_CM + end + end + end + end + Squib.logger.debug {"After convert_units: #{opts}"} + return opts + end + module_function :convert_units end end diff --git a/samples/units.rb b/samples/units.rb index 00b92eb..a7dab90 100644 --- a/samples/units.rb +++ b/samples/units.rb @@ -1,12 +1,28 @@ require 'squib' -Squib::Deck.new(width: 825, height: 1125) do - background color: :white +Squib::Deck.new do + background color: '#ddd' - bleed = inches(0.125) - cut_width = inches(2.5) + # We can use our DSL-method to use inches + # Computed using @dpi (set to 300 by default) + bleed = inches(0.125) + cut_width = inches(2.5) cut_height = inches(3.5) - rect x: bleed, y: bleed, width: cut_width, height: cut_height, radius: 25 + rect x: bleed, y: bleed, radius: 25, + width: cut_width, height: cut_height + + # We can also use cm this way + cm(2) + + # Or we can use a string ending with cm or in + # (even cleaner in Yaml since we don't need quotes!) + safe_margin = '0.25in' + safe_width = '2.25in' + safe_height = '3.25in' + rect x: safe_margin, y: safe_margin, + width: safe_width, height: safe_height, radius: 25 + + rect x: '4cm', y: '4 cm', width: 100, height: 100 save prefix: 'units_', format: :png end diff --git a/spec/data/samples/text_options.rb.txt b/spec/data/samples/text_options.rb.txt index 199cea0..b82a66a 100644 --- a/spec/data/samples/text_options.rb.txt +++ b/spec/data/samples/text_options.rb.txt @@ -721,7 +721,7 @@ cairo: move_to([65, 700]) pango: font_description=([]) pango: text=(["This is left-justified text.\nWhat do you know about tweetle beetles? well... \nWhen tweetle beetles fight, it's called a tweetle beetle battle. And when they battle in a puddle, it's a tweetle beetle puddle battle. AND when tweetle beetles battle with paddles in a puddle, they call it a tweetle beetle puddle paddle battle. AND... When beetles battle beetles in a puddle paddle battle and the beetle battle puddle is a puddle in a bottle... ..they call this a tweetle beetle bottle puddle paddle battle muddle. AND... When beetles fight these battles in a bottle with their paddles and the bottle's on a poodle and the poodle's eating noodles... ...they call this a muddle puddle tweetle poodle beetle noodle bottle paddle battle."]) pango: width=([691200.0]) -pango: height=([307200]) +pango: height=([307200.0]) pango: wrap=([#]) pango: ellipsize=([#]) pango: alignment=([#]) @@ -740,7 +740,7 @@ cairo: move_to([65, 700]) pango: font_description=([]) pango: text=(["This is left-justified text.\nWhat do you know about tweetle beetles? well... \nWhen tweetle beetles fight, it's called a tweetle beetle battle. And when they battle in a puddle, it's a tweetle beetle puddle battle. AND when tweetle beetles battle with paddles in a puddle, they call it a tweetle beetle puddle paddle battle. AND... When beetles battle beetles in a puddle paddle battle and the beetle battle puddle is a puddle in a bottle... ..they call this a tweetle beetle bottle puddle paddle battle muddle. AND... When beetles fight these battles in a bottle with their paddles and the bottle's on a poodle and the poodle's eating noodles... ...they call this a muddle puddle tweetle poodle beetle noodle bottle paddle battle."]) pango: width=([691200.0]) -pango: height=([307200]) +pango: height=([307200.0]) pango: wrap=([#]) pango: ellipsize=([#]) pango: alignment=([#]) @@ -759,7 +759,7 @@ cairo: move_to([65, 700]) pango: font_description=([]) pango: text=(["This is left-justified text.\nWhat do you know about tweetle beetles? well... \nWhen tweetle beetles fight, it's called a tweetle beetle battle. And when they battle in a puddle, it's a tweetle beetle puddle battle. AND when tweetle beetles battle with paddles in a puddle, they call it a tweetle beetle puddle paddle battle. AND... When beetles battle beetles in a puddle paddle battle and the beetle battle puddle is a puddle in a bottle... ..they call this a tweetle beetle bottle puddle paddle battle muddle. AND... When beetles fight these battles in a bottle with their paddles and the bottle's on a poodle and the poodle's eating noodles... ...they call this a muddle puddle tweetle poodle beetle noodle bottle paddle battle."]) pango: width=([691200.0]) -pango: height=([307200]) +pango: height=([307200.0]) pango: wrap=([#]) pango: ellipsize=([#]) pango: alignment=([#]) diff --git a/spec/data/samples/units.rb.txt b/spec/data/samples/units.rb.txt index b9ee00c..929bc09 100644 --- a/spec/data/samples/units.rb.txt +++ b/spec/data/samples/units.rb.txt @@ -1,5 +1,5 @@ cairo: save([]) -cairo: set_source_color([#]) +cairo: set_source_color([#]) cairo: paint([]) cairo: restore([]) cairo: save([]) @@ -11,4 +11,22 @@ cairo: rounded_rectangle([37.5, 37.5, 750.0, 1050.0, 25, 25]) cairo: set_source_color([#]) cairo: fill([]) cairo: restore([]) +cairo: save([]) +cairo: rounded_rectangle([75.0, 75.0, 675.0, 975.0, 25, 25]) +cairo: set_source_color([#]) +cairo: set_line_width([2.0]) +cairo: stroke([]) +cairo: rounded_rectangle([75.0, 75.0, 675.0, 975.0, 25, 25]) +cairo: set_source_color([#]) +cairo: fill([]) +cairo: restore([]) +cairo: save([]) +cairo: rounded_rectangle([472.4409444, 472.4409444, 100, 100, 0, 0]) +cairo: set_source_color([#]) +cairo: set_line_width([2.0]) +cairo: stroke([]) +cairo: rounded_rectangle([472.4409444, 472.4409444, 100, 100, 0, 0]) +cairo: set_source_color([#]) +cairo: fill([]) +cairo: restore([]) surface: write_to_png(["_output/units_0.png"]) diff --git a/spec/graphics/graphics_save_doc_spec.rb b/spec/graphics/graphics_save_doc_spec.rb index e8c287b..8043ea7 100644 --- a/spec/graphics/graphics_save_doc_spec.rb +++ b/spec/graphics/graphics_save_doc_spec.rb @@ -25,7 +25,7 @@ describe Squib::Deck, '#save_pdf' do args = { file: 'foo.pdf', dir: '_out', margin: 75, gap: 5, trim: 37 } deck = Squib::Deck.new(cards: num_cards, width: 825, height: 1125) mock_squib_logger(@old_logger) do - expect(Squib.logger).to receive(:debug).thrice + expect(Squib.logger).to receive(:debug).at_least(:once) expect(Cairo::Context).to receive(:new).and_return(@context).exactly(num_cards + 1).times expect(deck).to receive(:dirify) { |arg| arg } #don't create the dir @@ -49,7 +49,7 @@ describe Squib::Deck, '#save_pdf' do args = { range: 2..4, file: 'foo.pdf', dir: '_out', margin: 75, gap: 5, trim: 37 } deck = Squib::Deck.new(cards: num_cards, width: 825, height: 1125) mock_squib_logger(@old_logger) do - expect(Squib.logger).to receive(:debug).thrice + expect(Squib.logger).to receive(:debug).at_least(:once) expect(Cairo::Context).to receive(:new).and_return(@context).exactly(4).times expect(deck).to receive(:dirify) { |arg| arg } #don't create the dir diff --git a/spec/input_helpers_spec.rb b/spec/input_helpers_spec.rb index 585417f..202ad1b 100644 --- a/spec/input_helpers_spec.rb +++ b/spec/input_helpers_spec.rb @@ -4,7 +4,7 @@ require 'squib/input_helpers' class DummyDeck include Squib::InputHelpers - attr_accessor :layout, :cards, :custom_colors + attr_accessor :layout, :cards, :custom_colors, :width, :height, :dpi end describe Squib::InputHelpers do @@ -18,6 +18,9 @@ describe Squib::InputHelpers do } @deck.cards = %w(a b) @deck.custom_colors = {} + @deck.width = 100 + @deck.height = 200 + @deck.dpi = 300 end context '#layoutify' do @@ -135,4 +138,42 @@ describe Squib::InputHelpers do end end + context '#convert_units' do + it 'does not touch arrays integers' do + args = {x: [156]} + needed_params = [:x] + opts = @deck.send(:convert_units, args, needed_params) + expect(opts).to eq({ :x => [156] }) + end + + it 'does not touch arrays floats' do + args = {x: [156.2]} + needed_params = [:x] + opts = @deck.send(:convert_units, args, needed_params) + expect(opts).to eq({ :x => [156.2] }) + end + + it 'converts array of all inches' do + args = {x: ['1in', '2in']} + needed_params = [:x] + opts = @deck.send(:convert_units, args, needed_params) + expect(opts).to eq({:x => [300.0, 600.0] }) #assume 300dpi default + end + + it 'converts array of some inches' do + args = {x: [156, '2in']} + needed_params = [:x] + opts = @deck.send(:convert_units, args, needed_params) + expect(opts).to eq({:x => [156.0, 600.0]}) #assume 300dpi default + end + + it 'converts centimeters' do + args = {x: ['2cm']} + needed_params = [:x] + opts = @deck.send(:convert_units, args, needed_params) + expect(opts).to eq({:x => [236.2204722] }) #assume 300dpi default + end + + end + end