parent
c42fbef8fa
commit
e974880e03
|
|
@ -4,8 +4,9 @@ Squib follows [semantic versioning](http://semver.org).
|
||||||
## v0.6.0 / Unreleased
|
## v0.6.0 / Unreleased
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
* Upgraded roo (Excel parsing) to 2.0.0. Nothing major for Squib users, just keeping up with the times.
|
* Added `data` field to `svg` to allow for manipulating SVG XML data directly. Works nicely with my new `game_icons` [gem](https://github.com/andymeneely/game_icons) (#65)
|
||||||
* Added `stroke_width` and `stroke_color` to the `text` method to outlines text. (#51)
|
* Added `stroke_width` and `stroke_color` to the `text` method to outlines text. (#51)
|
||||||
|
* Upgraded roo (Excel parsing) to 2.0.0. Nothing major for Squib users, just keeping up with the times.
|
||||||
|
|
||||||
Bugs:
|
Bugs:
|
||||||
* Fixed global text hinting (#63)
|
* Fixed global text hinting (#63)
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ module Squib
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Renders an entire svg file at the given location. Uses the SVG-specified units and DPI to determine the pixel width and height.
|
# Renders an entire svg file at the given location. Uses the SVG-specified units and DPI to determine the pixel width and height. If neither data nor file are specified for a given card, this method does nothing.
|
||||||
#
|
#
|
||||||
# See {file:samples/load-images.rb samples/load-images.rb} and {file:samples/tgc-overlay.rb samples/tgc-overlay.rb} as examples.
|
# See {file:samples/load-images.rb samples/load-images.rb} and {file:samples/tgc-overlay.rb samples/tgc-overlay.rb} as examples.
|
||||||
# @example
|
# @example
|
||||||
|
|
@ -42,6 +42,7 @@ 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 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] ('') 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 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 data [String] (nil) render from an SVG XML string. Overrides file if both are specified (a warning is shown) . 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 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 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}. Supports Unit Conversion, see {file:README.md#Units Units}.
|
# @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.md#Units Units}.
|
||||||
|
|
@ -56,12 +57,13 @@ module Squib
|
||||||
# @return [nil] Returns nil
|
# @return [nil] Returns nil
|
||||||
# @api public
|
# @api public
|
||||||
def svg(opts = {})
|
def svg(opts = {})
|
||||||
p = needs(opts,[:range, :files, :svgid, :force_svgid, :x, :y, :width, :height, :layout, :alpha, :blend, :angle, :mask])
|
p = needs(opts,[:range, :files, :svgdata, :svgid, :force_svgid, :x, :y, :width, :height,
|
||||||
|
:layout, :alpha, :blend, :angle, :mask])
|
||||||
Dir.chdir(img_dir) do
|
Dir.chdir(img_dir) do
|
||||||
@progress_bar.start('Loading SVG(s)', p[:range].size) do |bar|
|
@progress_bar.start('Loading SVG(s)', p[:range].size) do |bar|
|
||||||
p[:range].each do |i|
|
p[:range].each do |i|
|
||||||
unless p[:force_id][i] && p[:id][i].to_s.empty?
|
unless p[:force_id][i] && p[:id][i].to_s.empty?
|
||||||
@cards[i].svg(p[:file][i], p[:id][i], p[:x][i], p[:y][i],
|
@cards[i].svg(p[:file][i], p[:data][i], p[:id][i], p[:x][i], p[:y][i],
|
||||||
p[:width][i], p[:height][i], p[:alpha][i], p[:blend][i], p[:angle][i],p[:mask][i])
|
p[:width][i], p[:height][i], p[:alpha][i], p[:blend][i], p[:angle][i],p[:mask][i])
|
||||||
end
|
end
|
||||||
bar.increment
|
bar.increment
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ module Squib
|
||||||
# TODO: add input validation here. We need the key for example.
|
# TODO: add input validation here. We need the key for example.
|
||||||
rule = {type: :svg}.merge(opts)
|
rule = {type: :svg}.merge(opts)
|
||||||
rule[:draw] = Proc.new do |card, x,y|
|
rule[:draw] = Proc.new do |card, x,y|
|
||||||
card.svg(rule[:file], rule[:id], x, y, rule[:width], rule[:height],
|
card.svg(rule[:file], rule[:data], rule[:id], x, y, rule[:width], rule[:height],
|
||||||
rule[:alpha], rule[:blend], rule[:angle], rule[:mask])
|
rule[:alpha], rule[:blend], rule[:angle], rule[:mask])
|
||||||
end
|
end
|
||||||
@rules[opts[:key]] = rule
|
@rules[opts[:key]] = rule
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ module Squib
|
||||||
:cx2 => 0,
|
:cx2 => 0,
|
||||||
:cy1 => 0,
|
:cy1 => 0,
|
||||||
:cy2 => 0,
|
:cy2 => 0,
|
||||||
|
:data => nil,
|
||||||
:default_font => 'Arial 36',
|
:default_font => 'Arial 36',
|
||||||
:dir => '_output',
|
:dir => '_output',
|
||||||
:dx => 0, # delta
|
:dx => 0, # delta
|
||||||
|
|
@ -107,6 +108,7 @@ module Squib
|
||||||
:str => :str,
|
:str => :str,
|
||||||
:stroke_color => :stroke_color,
|
:stroke_color => :stroke_color,
|
||||||
:stroke_width => :stroke_width,
|
:stroke_width => :stroke_width,
|
||||||
|
:svgdata => :data,
|
||||||
:svgid => :id,
|
:svgid => :id,
|
||||||
:valign => :valign,
|
:valign => :valign,
|
||||||
:width => :width,
|
:width => :width,
|
||||||
|
|
|
||||||
|
|
@ -41,10 +41,12 @@ module Squib
|
||||||
|
|
||||||
# :nodoc:
|
# :nodoc:
|
||||||
# @api private
|
# @api private
|
||||||
def svg(file, id, x, y, width, height, alpha, blend, angle, mask)
|
def svg(file, data, id, x, y, width, height, alpha, blend, angle, mask)
|
||||||
Squib.logger.debug {"Rendering: #{file}, id: #{id} @#{x},#{y} #{width}x#{height}, alpha: #{alpha}, blend: #{blend}, angle: #{angle}, mask: #{mask}"}
|
Squib.logger.debug {"Rendering: #{file}, id: #{id} @#{x},#{y} #{width}x#{height}, alpha: #{alpha}, blend: #{blend}, angle: #{angle}, mask: #{mask}"}
|
||||||
return if file.nil? or file.eql? ''
|
Squib.logger.warn 'Both an SVG file and SVG data were specified' unless file.to_s.empty? or data.to_s.empty?
|
||||||
svg = RSVG::Handle.new_from_file(file)
|
return if (file.nil? or file.eql? '') and data.nil? # nothing specified
|
||||||
|
data = File.read(file) if data.to_s.empty?
|
||||||
|
svg = RSVG::Handle.new_from_data(data)
|
||||||
width = svg.width if width == :native
|
width = svg.width if width == :native
|
||||||
height = svg.height if height == :native
|
height = svg.height if height == :native
|
||||||
scale_width = width.to_f / svg.width.to_f
|
scale_width = width.to_f / svg.width.to_f
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ Squib::Deck.new do
|
||||||
text(str: embed_text, font: 'Sans 21',
|
text(str: embed_text, font: 'Sans 21',
|
||||||
x: 400, y: 320, width: 180, height: 300,
|
x: 400, y: 320, width: 180, height: 300,
|
||||||
align: :center, ellipsize: false, justify: false, hint: :magenta) do |embed|
|
align: :center, ellipsize: false, justify: false, hint: :magenta) do |embed|
|
||||||
embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
|
embed.svg key: ':tool:', width: 28, height: 28, data: File.read('spanner.svg')
|
||||||
embed.svg key: ':health:', width: 28, height: 28, file: 'glass-heart.svg'
|
embed.svg key: ':health:', width: 28, height: 28, file: 'glass-heart.svg'
|
||||||
embed.png key: ':purse:', width: 28, height: 28, file: 'shiny-purse.png'
|
embed.png key: ':purse:', width: 28, height: 28, file: 'shiny-purse.png'
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,20 @@ Squib::Deck.new(width: 825, height: 1125, cards: 1) do
|
||||||
# Squib prepends a #-sign if one is not specified
|
# Squib prepends a #-sign if one is not specified
|
||||||
svg file: 'spanner.svg', id: 'backdrop', x: 50, y: 450, width: 125, height: 125
|
svg file: 'spanner.svg', id: 'backdrop', x: 50, y: 450, width: 125, height: 125
|
||||||
|
|
||||||
|
# We can also load SVGs as a string of XML
|
||||||
|
svg data: File.read('spanner.svg'), x: 50, y: 600, width: 75, height: 75
|
||||||
|
|
||||||
|
# The svg data field works nicely with modifying the SVG XML on-the-fly.
|
||||||
|
# To run this one, do `gem install game_icons` and uncomment the following
|
||||||
|
#
|
||||||
|
# require 'game_icons'
|
||||||
|
# svg data: GameIcons.get('angler-fish').recolor(fg: '#ccc', bg: '#333').string,
|
||||||
|
# x: 150, y: 600, width: 75, height: 75
|
||||||
|
#
|
||||||
|
# More examples at https://github.com/andymeneely/game_icons
|
||||||
|
# (or `gem install game_icons`) to get & manipulate art from game-icons.net
|
||||||
|
# Nokogiri (already included in Squib) is also great for XML manipulation.
|
||||||
|
|
||||||
# WARNING! If you choose to use the SVG ID, the x-y coordinates are still
|
# WARNING! If you choose to use the SVG ID, the x-y coordinates are still
|
||||||
# relative to the SVG page. See this example in an SVG editor
|
# relative to the SVG page. See this example in an SVG editor
|
||||||
svg file: 'offset.svg', id: 'thing', x: 0, y: 0, width: 600, height: 600
|
svg file: 'offset.svg', id: 'thing', x: 0, y: 0, width: 600, height: 600
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ describe Squib::Deck, 'images' do
|
||||||
it 'calls Card#svg, Dir, and progress bar' do
|
it 'calls Card#svg, Dir, and progress bar' do
|
||||||
card = instance_double(Squib::Card)
|
card = instance_double(Squib::Card)
|
||||||
progress = double(Squib::Progress)
|
progress = double(Squib::Progress)
|
||||||
expect(card).to receive(:svg).with('foo', '#bar', 0, 1, 20, 30, 0.5, :overlay, 0.75, nil).once
|
expect(card).to receive(:svg).with('foo', nil, '#bar', 0, 1, 20, 30, 0.5, :overlay, 0.75, nil).once
|
||||||
expect(Dir).to receive(:chdir).with('.').and_yield.once
|
expect(Dir).to receive(:chdir).with('.').and_yield.once
|
||||||
expect(progress).to receive(:start).and_yield(progress).once
|
expect(progress).to receive(:start).and_yield(progress).once
|
||||||
expect(progress).to receive(:increment).once
|
expect(progress).to receive(:increment).once
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,12 @@ cairo: scale([0.9765625, 0.9765625])
|
||||||
cairo: render_rsvg_handle([RSVG::Handle, "#backdrop"])
|
cairo: render_rsvg_handle([RSVG::Handle, "#backdrop"])
|
||||||
cairo: restore([])
|
cairo: restore([])
|
||||||
cairo: save([])
|
cairo: save([])
|
||||||
|
cairo: translate([50, 600])
|
||||||
|
cairo: rotate([0])
|
||||||
|
cairo: scale([0.5859375, 0.5859375])
|
||||||
|
cairo: render_rsvg_handle([RSVG::Handle, nil])
|
||||||
|
cairo: restore([])
|
||||||
|
cairo: save([])
|
||||||
cairo: translate([0, 0])
|
cairo: translate([0, 0])
|
||||||
cairo: rotate([0])
|
cairo: rotate([0])
|
||||||
cairo: scale([0.8021390374331551, 0.8032128514056225])
|
cairo: scale([0.8021390374331551, 0.8032128514056225])
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ describe Squib::Card do
|
||||||
allow(Cairo::Context).to receive(:new).and_return(context)
|
allow(Cairo::Context).to receive(:new).and_return(context)
|
||||||
allow(Cairo::ImageSurface).to receive(:from_png).and_return(png)
|
allow(Cairo::ImageSurface).to receive(:from_png).and_return(png)
|
||||||
allow(Cairo::ImageSurface).to receive(:new).and_return(png)
|
allow(Cairo::ImageSurface).to receive(:new).and_return(png)
|
||||||
allow(RSVG::Handle).to receive(:new_from_file).and_return(svg)
|
allow(RSVG::Handle).to receive(:new_from_data).and_return(svg)
|
||||||
allow(deck).to receive(:dir).and_return('_output')
|
allow(deck).to receive(:dir).and_return('_output')
|
||||||
allow(deck).to receive(:count_format).and_return('%02d')
|
allow(deck).to receive(:count_format).and_return('%02d')
|
||||||
allow(deck).to receive(:prefix).and_return('card_')
|
allow(deck).to receive(:prefix).and_return('card_')
|
||||||
|
|
@ -58,8 +58,8 @@ describe Squib::Card do
|
||||||
expect(context).to receive(:restore).once
|
expect(context).to receive(:restore).once
|
||||||
|
|
||||||
card = Squib::Card.new(deck, 100, 150)
|
card = Squib::Card.new(deck, 100, 150)
|
||||||
# svg(file, id, x, y, width, height, alpha, blend, angle)
|
# svg(file, data, id, x, y, width, height, alpha, blend, angle)
|
||||||
card.svg('foo.png', 'id', 37, 38, :native, :native, 0.9, :none, 0.0, nil)
|
card.svg(nil, '<svg></svg>', 'id', 37, 38, :native, :native, 0.9, :none, 0.0, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets blend when needed' do
|
it 'sets blend when needed' do
|
||||||
|
|
@ -68,7 +68,7 @@ describe Squib::Card do
|
||||||
expect(context).to receive(:operator=).with(:overlay).once
|
expect(context).to receive(:operator=).with(:overlay).once
|
||||||
|
|
||||||
card = Squib::Card.new(deck, 100, 150)
|
card = Squib::Card.new(deck, 100, 150)
|
||||||
card.svg('foo.png', nil, 37, 38, :native, :native, 0.9, :overlay, 0.0, nil)
|
card.svg(nil, '<svg></svg>', nil, 37, 38, :native, :native, 0.9, :overlay, 0.0, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets width & height when needed' do
|
it 'sets width & height when needed' do
|
||||||
|
|
@ -78,7 +78,7 @@ describe Squib::Card do
|
||||||
expect(context).to receive(:scale).with(2.0, 3.0).once
|
expect(context).to receive(:scale).with(2.0, 3.0).once
|
||||||
|
|
||||||
card = Squib::Card.new(deck, 100, 150)
|
card = Squib::Card.new(deck, 100, 150)
|
||||||
card.svg('foo.png', nil, 37, 38, 200, 300, 0.9, :none, 0.0, nil)
|
card.svg(nil, '<svg></svg>', nil, 37, 38, 200, 300, 0.9, :none, 0.0, nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,5 +43,6 @@ Gem::Specification.new do |spec|
|
||||||
spec.add_development_dependency 'coveralls'
|
spec.add_development_dependency 'coveralls'
|
||||||
spec.add_development_dependency 'byebug'
|
spec.add_development_dependency 'byebug'
|
||||||
spec.add_development_dependency 'launchy'
|
spec.add_development_dependency 'launchy'
|
||||||
|
spec.add_development_dependency 'game_icons'
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,10 @@
|
||||||
"name": "rake run[custom_config]",
|
"name": "rake run[custom_config]",
|
||||||
"shell_cmd": "rake run[custom_config]",
|
"shell_cmd": "rake run[custom_config]",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "rake run[load_images]",
|
||||||
|
"shell_cmd": "rake run[load_images]",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "rspec spec/samples/samples_regression_spec.rb",
|
"name": "rspec spec/samples/samples_regression_spec.rb",
|
||||||
"shell_cmd": "rspec spec/samples/samples_regression_spec.rb",
|
"shell_cmd": "rspec spec/samples/samples_regression_spec.rb",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue