squib 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +62 -14
- data/Gemfile +1 -1
- data/README.md +16 -10
- data/RELEASE TODO.md +2 -1
- data/Rakefile +11 -0
- data/lib/squib/api/data.rb +3 -3
- data/lib/squib/api/image.rb +7 -5
- data/lib/squib/api/save.rb +31 -2
- data/lib/squib/api/settings.rb +1 -1
- data/lib/squib/api/shapes.rb +86 -0
- data/lib/squib/api/text.rb +6 -2
- data/lib/squib/api/text_embed.rb +7 -5
- data/lib/squib/args/typographer.rb +22 -16
- data/lib/squib/card.rb +5 -5
- data/lib/squib/conf.rb +111 -0
- data/lib/squib/constants.rb +11 -31
- data/lib/squib/deck.rb +15 -48
- data/lib/squib/graphics/cairo_context_wrapper.rb +3 -1
- data/lib/squib/graphics/gradient_regex.rb +1 -0
- data/lib/squib/graphics/hand.rb +43 -0
- data/lib/squib/graphics/image.rb +5 -3
- data/lib/squib/graphics/save_doc.rb +1 -1
- data/lib/squib/graphics/shapes.rb +74 -0
- data/lib/squib/graphics/showcase.rb +5 -2
- data/lib/squib/graphics/text.rb +18 -7
- data/lib/squib/input_helpers.rb +2 -2
- data/lib/squib/version.rb +1 -1
- data/samples/csv_import.rb +3 -5
- data/samples/custom-config.yml +0 -1
- data/samples/custom_config.rb +1 -1
- data/samples/draw_shapes.rb +11 -0
- data/samples/embed_text.rb +1 -1
- data/samples/hand.rb +24 -0
- data/samples/load_images.rb +14 -0
- data/samples/sample.csv +3 -3
- data/samples/text_options.rb +4 -0
- data/spec/api/api_data_spec.rb +19 -0
- data/spec/api/api_image_spec.rb +1 -1
- data/spec/api/api_settings_spec.rb +18 -0
- data/spec/api/api_text_spec.rb +3 -3
- data/spec/conf_spec.rb +29 -0
- data/spec/data/conf/basic.yml +0 -0
- data/spec/data/conf/empty.yml +1 -0
- data/spec/data/samples/csv_import.rb.txt +4 -38
- data/spec/data/samples/custom_config.rb.txt +4 -0
- data/spec/data/samples/draw_shapes.rb.txt +57 -0
- data/spec/data/samples/hand.rb.txt +514 -0
- data/spec/data/samples/load_images.rb.txt +6 -0
- data/spec/data/samples/text_options.rb.txt +81 -0
- data/spec/data/xlsx/basic.xlsx +0 -0
- data/spec/data/xlsx/formulas.xlsx +0 -0
- data/spec/graphics/graphics_images_spec.rb +49 -48
- data/spec/graphics/graphics_shapes_spec.rb +43 -41
- data/spec/graphics/graphics_text_spec.rb +25 -11
- data/spec/samples/_diffs/gitkeep.txt +0 -0
- data/spec/samples/expected/autoscale_00.png +0 -0
- data/spec/samples/expected/autoscale_01.png +0 -0
- data/spec/samples/expected/autoscale_02.png +0 -0
- data/spec/samples/expected/backend_00.png +0 -0
- data/spec/samples/expected/backend_00.svg +78 -0
- data/spec/samples/expected/backend_01.png +0 -0
- data/spec/samples/expected/backend_01.svg +78 -0
- data/spec/samples/expected/basic_00.png +0 -0
- data/spec/samples/expected/basic_01.png +0 -0
- data/spec/samples/expected/basic_02.png +0 -0
- data/spec/samples/expected/cairo_access_00.png +0 -0
- data/spec/samples/expected/cairo_access_01.png +0 -0
- data/spec/samples/expected/card_00.png +0 -0
- data/spec/samples/expected/card_01.png +0 -0
- data/spec/samples/expected/colors_00.png +0 -0
- data/spec/samples/expected/config_disable_text_00.png +0 -0
- data/spec/samples/expected/config_text_00.png +0 -0
- data/spec/samples/expected/custom-config_00.png +0 -0
- data/spec/samples/expected/embed_00.png +0 -0
- data/spec/samples/expected/embed_multi_00.png +0 -0
- data/spec/samples/expected/embed_multi_01.png +0 -0
- data/spec/samples/expected/embed_multi_02.png +0 -0
- data/spec/samples/expected/embed_multisheet_00.png +0 -0
- data/spec/samples/expected/gitkeep.txt +0 -0
- data/spec/samples/expected/gradient_00.png +0 -0
- data/spec/samples/expected/hand.png +0 -0
- data/spec/samples/expected/hand_pretty.png +0 -0
- data/spec/samples/expected/landscape_00.png +0 -0
- data/spec/samples/expected/layout2_00.png +0 -0
- data/spec/samples/expected/layout_00.png +0 -0
- data/spec/samples/expected/layout_builtin_hand_00.png +0 -0
- data/spec/samples/expected/layout_builtin_playing_card_00.png +0 -0
- data/spec/samples/expected/load_images_00.png +0 -0
- data/spec/samples/expected/portrait_00.png +0 -0
- data/spec/samples/expected/ranges_00.png +0 -0
- data/spec/samples/expected/ranges_01.png +0 -0
- data/spec/samples/expected/ranges_02.png +0 -0
- data/spec/samples/expected/sample_csv_00.png +0 -0
- data/spec/samples/expected/sample_csv_01.png +0 -0
- data/spec/samples/expected/sample_excel_00.png +0 -0
- data/spec/samples/expected/sample_excel_01.png +0 -0
- data/spec/samples/expected/sample_excel_02.png +0 -0
- data/spec/samples/expected/save_sheet_00.png +0 -0
- data/spec/samples/expected/save_sheet_01.png +0 -0
- data/spec/samples/expected/save_sheet_range_00.png +0 -0
- data/spec/samples/expected/save_sheet_range_01.png +0 -0
- data/spec/samples/expected/save_single_sheet_00.png +0 -0
- data/spec/samples/expected/saves_notrim_01.png +0 -0
- data/spec/samples/expected/shape_00.png +0 -0
- data/spec/samples/expected/showcase.png +0 -0
- data/spec/samples/expected/showcase2.png +0 -0
- data/spec/samples/expected/showcase_individual_00.png +0 -0
- data/spec/samples/expected/showcase_individual_01.png +0 -0
- data/spec/samples/expected/showcase_individual_02.png +0 -0
- data/spec/samples/expected/showcase_individual_03.png +0 -0
- data/spec/samples/expected/text_00.png +0 -0
- data/spec/samples/expected/text_01.png +0 -0
- data/spec/samples/expected/text_02.png +0 -0
- data/spec/samples/expected/tgc_sample_00.png +0 -0
- data/spec/samples/expected/units_00.png +0 -0
- data/spec/samples/samples_regression_spec.rb +7 -5
- data/spec/samples/sanity.html.erb +28 -0
- data/spec/samples/sanity.rb +70 -0
- data/spec/spec_helper.rb +15 -1
- data/squib.gemspec +3 -1
- data/squib.sublime-project +27 -40
- metadata +177 -4
@@ -4,6 +4,7 @@ require 'squib/graphics/gradient_regex'
|
|
4
4
|
module Squib
|
5
5
|
module Graphics
|
6
6
|
# Wrapper class for the Cairo context. Private.
|
7
|
+
# @api private
|
7
8
|
class CairoContextWrapper
|
8
9
|
extend Forwardable
|
9
10
|
|
@@ -22,7 +23,8 @@ module Squib
|
|
22
23
|
:show_pango_layout, :rounded_rectangle, :set_line_width, :stroke, :fill,
|
23
24
|
:set_source, :scale, :render_rsvg_handle, :circle, :triangle, :line_to,
|
24
25
|
:operator=, :show_page, :clip, :transform, :mask, :create_pango_layout,
|
25
|
-
:antialias=, :curve_to, :matrix, :matrix=, :identity_matrix
|
26
|
+
:antialias=, :curve_to, :matrix, :matrix=, :identity_matrix, :pango_layout_path,
|
27
|
+
:stroke_preserve, :target, :new_path, :fill_preserve, :close_path
|
26
28
|
|
27
29
|
# :nodoc:
|
28
30
|
# @api private
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'squib/graphics/cairo_context_wrapper'
|
2
|
+
|
3
|
+
module Squib
|
4
|
+
class Deck
|
5
|
+
|
6
|
+
# Draw cards in a fan.
|
7
|
+
# @api private
|
8
|
+
def render_hand(range, radius, angle_range, trim, trim_radius, margin,
|
9
|
+
fill_color, dir, file)
|
10
|
+
cards = range.collect { |i| @cards[i] }
|
11
|
+
center_x = width / 2.0
|
12
|
+
center_y = radius + height
|
13
|
+
out_size = 3.0 * center_y
|
14
|
+
angle_delta = (angle_range.last - angle_range.first) / cards.size
|
15
|
+
cxt = Cairo::Context.new(Cairo::RecordingSurface.new(0, 0, out_size, out_size))
|
16
|
+
cxt.translate(out_size / 2.0, out_size / 2.0)
|
17
|
+
cxt.rotate(angle_range.first)
|
18
|
+
cxt.translate(-width, -width)
|
19
|
+
cards.each_with_index do |card, i|
|
20
|
+
cxt.translate(center_x, center_y)
|
21
|
+
cxt.rotate(angle_delta)
|
22
|
+
cxt.translate(-center_x, -center_y)
|
23
|
+
card.use_cairo do |card_cxt|
|
24
|
+
cxt.rounded_rectangle(trim, trim,
|
25
|
+
width - (2 * trim), height - (2 * trim),
|
26
|
+
trim_radius, trim_radius)
|
27
|
+
cxt.clip
|
28
|
+
cxt.set_source(card_cxt.target)
|
29
|
+
cxt.paint
|
30
|
+
cxt.reset_clip
|
31
|
+
end
|
32
|
+
end
|
33
|
+
x, y, w, h = cxt.target.ink_extents # I love Ruby assignment ;)
|
34
|
+
png_cxt = Squib::Graphics::CairoContextWrapper.new(Cairo::Context.new(Cairo::ImageSurface.new(w + 2*margin, h + 2*margin)))
|
35
|
+
png_cxt.set_source_squibcolor(fill_color)
|
36
|
+
png_cxt.paint
|
37
|
+
png_cxt.translate(-x + margin, -y + margin)
|
38
|
+
png_cxt.set_source(cxt.target)
|
39
|
+
png_cxt.paint
|
40
|
+
png_cxt.target.write_to_png("#{dir}/#{file}")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/squib/graphics/image.rb
CHANGED
@@ -41,10 +41,12 @@ module Squib
|
|
41
41
|
|
42
42
|
# :nodoc:
|
43
43
|
# @api private
|
44
|
-
def svg(file, id, x, y, width, height, alpha, blend, angle, mask)
|
44
|
+
def svg(file, data, id, x, y, width, height, alpha, blend, angle, mask)
|
45
45
|
Squib.logger.debug {"Rendering: #{file}, id: #{id} @#{x},#{y} #{width}x#{height}, alpha: #{alpha}, blend: #{blend}, angle: #{angle}, mask: #{mask}"}
|
46
|
-
|
47
|
-
|
46
|
+
Squib.logger.warn 'Both an SVG file and SVG data were specified' unless file.to_s.empty? or data.to_s.empty?
|
47
|
+
return if (file.nil? or file.eql? '') and data.nil? # nothing specified
|
48
|
+
data = File.read(file) if data.to_s.empty?
|
49
|
+
svg = RSVG::Handle.new_from_data(data)
|
48
50
|
width = svg.width if width == :native
|
49
51
|
height = svg.height if height == :native
|
50
52
|
scale_width = width.to_f / svg.width.to_f
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Squib
|
2
|
+
# @api private
|
2
3
|
class Card
|
3
4
|
|
4
5
|
# :nodoc:
|
@@ -32,6 +33,34 @@ module Squib
|
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
36
|
+
# Ellipse drawing taken from looking at the control points in Inkscape
|
37
|
+
# Think of it like a rectangle. Curves go from mid-points of the sides
|
38
|
+
# of the rectangle. Control points are at 1/4 and 3/4 of the side.
|
39
|
+
# :nodoc:
|
40
|
+
# @api private
|
41
|
+
def ellipse(x, y, w, h, fill_color, stroke_color, stroke_width)
|
42
|
+
use_cairo do |cc|
|
43
|
+
cc.move_to(x, y + 0.5*h) # start west
|
44
|
+
cc.curve_to(x, y + 0.25*h, # west to north
|
45
|
+
x + 0.25*w, y,
|
46
|
+
x + 0.5*w, y)
|
47
|
+
cc.curve_to(x + 0.75*w, y, # north to east
|
48
|
+
x + w, y + 0.25*h,
|
49
|
+
x + w, y + 0.5*h)
|
50
|
+
cc.curve_to(x + w, y + 0.75*h, # east to south
|
51
|
+
x + 0.75*w, y + h,
|
52
|
+
x + 0.5*w, y + h)
|
53
|
+
cc.curve_to(x + 0.25*w, y + h, # south to west
|
54
|
+
x, y + 0.75*h,
|
55
|
+
x, y + 0.5*h)
|
56
|
+
cc.set_source_squibcolor(stroke_color)
|
57
|
+
cc.set_line_width(stroke_width)
|
58
|
+
cc.stroke_preserve
|
59
|
+
cc.set_source_squibcolor(fill_color)
|
60
|
+
cc.fill
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
35
64
|
# :nodoc:
|
36
65
|
# @api private
|
37
66
|
def triangle(x1, y1, x2, y2, x3, y3, fill_color, stroke_color, stroke_width)
|
@@ -74,5 +103,50 @@ module Squib
|
|
74
103
|
end
|
75
104
|
end
|
76
105
|
|
106
|
+
# :nodoc:
|
107
|
+
# @api private
|
108
|
+
def star(x, y, n, angle, inner_radius, outer_radius, fill_color, stroke_color, stroke_width)
|
109
|
+
use_cairo do |cc|
|
110
|
+
cc.translate(x, y)
|
111
|
+
cc.rotate(angle)
|
112
|
+
cc.translate(-x, -y)
|
113
|
+
cc.move_to(x + outer_radius, y) #i = 0, so cos(0)=1 and sin(0)=0
|
114
|
+
theta = Math::PI / n.to_f # i.e. (2*pi) / (2*n)
|
115
|
+
0.upto(2 * n) do |i|
|
116
|
+
radius = i.even? ? outer_radius : inner_radius
|
117
|
+
cc.line_to(x + radius * Math::cos(i * theta),
|
118
|
+
y + radius * Math::sin(i * theta))
|
119
|
+
end
|
120
|
+
cc.close_path
|
121
|
+
cc.set_source_squibcolor(stroke_color)
|
122
|
+
cc.set_line_width(stroke_width)
|
123
|
+
cc.fill_preserve
|
124
|
+
cc.set_source_squibcolor(fill_color)
|
125
|
+
cc.stroke
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# :nodoc:
|
130
|
+
# @api private
|
131
|
+
def polygon(x, y, n, angle, radius, fill_color, stroke_color, stroke_width)
|
132
|
+
use_cairo do |cc|
|
133
|
+
cc.translate(x, y)
|
134
|
+
cc.rotate(angle)
|
135
|
+
cc.translate(-x, -y)
|
136
|
+
cc.move_to(x + radius, y) # i = 0, so cos(0)=1 and sin(0)=0
|
137
|
+
theta = (2 * Math::PI) / n.to_f
|
138
|
+
0.upto(n) do |i|
|
139
|
+
cc.line_to(x + radius * Math::cos(i * theta),
|
140
|
+
y + radius * Math::sin(i * theta))
|
141
|
+
end
|
142
|
+
cc.close_path
|
143
|
+
cc.set_source_squibcolor(stroke_color)
|
144
|
+
cc.set_line_width(stroke_width)
|
145
|
+
cc.fill_preserve
|
146
|
+
cc.set_source_squibcolor(fill_color)
|
147
|
+
cc.stroke
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
77
151
|
end
|
78
152
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'squib/graphics/cairo_context_wrapper'
|
2
|
+
|
1
3
|
module Squib
|
2
4
|
class Deck
|
3
5
|
|
@@ -16,8 +18,9 @@ module Squib
|
|
16
18
|
out_width = range.size * ((@width - 2*trim) * scale * offset) + 2*margin
|
17
19
|
out_height = reflect_offset + (1.0 + reflect_percent) * (@height - 2*trim) + 2*margin
|
18
20
|
out_cc = Cairo::Context.new(Cairo::ImageSurface.new(out_width, out_height))
|
19
|
-
|
20
|
-
|
21
|
+
wrapper = Squib::Graphics::CairoContextWrapper.new(out_cc)
|
22
|
+
wrapper.set_source_squibcolor(fill_color)
|
23
|
+
wrapper.paint
|
21
24
|
|
22
25
|
cards = range.collect { |i| @cards[i] }
|
23
26
|
cards.each_with_index do |card, i|
|
data/lib/squib/graphics/text.rb
CHANGED
@@ -6,8 +6,8 @@ module Squib
|
|
6
6
|
|
7
7
|
# :nodoc:
|
8
8
|
# @api private
|
9
|
-
def draw_text_hint(cc,x,y,layout, color
|
10
|
-
color = @deck.text_hint if color.eql? 'off' and not @deck.text_hint.to_s.eql? 'off'
|
9
|
+
def draw_text_hint(cc, x, y, layout, color)
|
10
|
+
color = @deck.text_hint if color.to_s.eql? 'off' and not @deck.text_hint.to_s.eql? 'off'
|
11
11
|
return if color.to_s.eql? 'off' or color.nil?
|
12
12
|
# when w,h < 0, it was never set. extents[1] are ink extents
|
13
13
|
w = layout.width / Pango::SCALE
|
@@ -78,7 +78,7 @@ module Squib
|
|
78
78
|
|
79
79
|
def set_font_rendering_opts!(layout)
|
80
80
|
font_options = Cairo::FontOptions.new
|
81
|
-
font_options.antialias = ANTIALIAS_OPTS[(@deck.antialias
|
81
|
+
font_options.antialias = Conf::ANTIALIAS_OPTS[(@deck.antialias || 'gray').downcase]
|
82
82
|
font_options.hint_metrics = 'on' # TODO make this configurable
|
83
83
|
font_options.hint_style = 'full' # TODO make this configurable
|
84
84
|
layout.context.font_options = font_options
|
@@ -127,7 +127,7 @@ module Squib
|
|
127
127
|
while (key = next_embed(embed.rules.keys, clean_str)) != nil
|
128
128
|
rule = embed.rules[key]
|
129
129
|
spacing = rule[:width] * Pango::SCALE
|
130
|
-
index = clean_str.index(key)
|
130
|
+
index = clean_str.index(key)
|
131
131
|
index = clean_str[0..index].bytesize #convert to byte index (bug #57)
|
132
132
|
str = str.sub(key, "<span size=\"#{ZERO_WIDTH_CHAR_SIZE}\">a<span letter_spacing=\"#{spacing.to_i}\">a</span>a</span>")
|
133
133
|
layout.markup = str
|
@@ -143,12 +143,22 @@ module Squib
|
|
143
143
|
return draw_calls
|
144
144
|
end
|
145
145
|
|
146
|
+
def stroke_outline!(cc, layout, stroke_width, stroke_color)
|
147
|
+
if stroke_width > 0
|
148
|
+
cc.set_source_squibcolor(stroke_color)
|
149
|
+
cc.set_line_width(stroke_width)
|
150
|
+
cc.pango_layout_path(layout)
|
151
|
+
cc.stroke
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
146
155
|
# :nodoc:
|
147
156
|
# @api private
|
148
157
|
def text(embed,str, font, font_size, color,
|
149
158
|
x, y, width, height,
|
150
159
|
markup, justify, wrap, ellipsize,
|
151
|
-
spacing, align, valign, hint, angle
|
160
|
+
spacing, align, valign, hint, angle,
|
161
|
+
stroke_color, stroke_width)
|
152
162
|
Squib.logger.debug {"Placing '#{str}'' with font '#{font}' @ #{x}, #{y}, color: #{color}, angle: #{angle} etc."}
|
153
163
|
extents = nil
|
154
164
|
str = str.to_s
|
@@ -164,7 +174,7 @@ module Squib
|
|
164
174
|
layout.font_description = font_desc
|
165
175
|
layout.text = str
|
166
176
|
if markup
|
167
|
-
str =
|
177
|
+
str = @deck.typographer.process(layout.text)
|
168
178
|
layout.markup = str
|
169
179
|
end
|
170
180
|
|
@@ -185,6 +195,7 @@ module Squib
|
|
185
195
|
|
186
196
|
cc.update_pango_layout(layout)
|
187
197
|
cc.show_pango_layout(layout)
|
198
|
+
stroke_outline!(cc, layout, stroke_width, stroke_color)
|
188
199
|
begin
|
189
200
|
embed_draws.each { |ed| ed[:draw].call(self, ed[:x], ed[:y] + vertical_start) }
|
190
201
|
rescue Exception => e
|
@@ -194,7 +205,7 @@ module Squib
|
|
194
205
|
puts "=================="
|
195
206
|
raise e
|
196
207
|
end
|
197
|
-
draw_text_hint(cc, x, y, layout, hint
|
208
|
+
draw_text_hint(cc, x, y, layout, hint)
|
198
209
|
extents = { width: layout.extents[1].width / Pango::SCALE,
|
199
210
|
height: layout.extents[1].height / Pango::SCALE }
|
200
211
|
end
|
data/lib/squib/input_helpers.rb
CHANGED
@@ -130,8 +130,8 @@ module Squib
|
|
130
130
|
def colorify(opts, nillable=false, key=:color)
|
131
131
|
opts[key].each_with_index do |color, i|
|
132
132
|
unless nillable && color.nil?
|
133
|
-
if
|
134
|
-
color =
|
133
|
+
if custom_colors.key? color.to_s
|
134
|
+
color = custom_colors[color.to_s]
|
135
135
|
end
|
136
136
|
opts[key][i] = color
|
137
137
|
end
|
data/lib/squib/version.rb
CHANGED
data/samples/csv_import.rb
CHANGED
@@ -5,15 +5,13 @@ Squib::Deck.new(cards: 2) do
|
|
5
5
|
|
6
6
|
# Outputs a hash of arrays with the header names as keys
|
7
7
|
data = csv file: 'sample.csv'
|
8
|
-
|
9
|
-
text str: data['Name'], x: 250, y: 55, font: 'Arial 54'
|
8
|
+
text str: data['Type'], x: 250, y: 55, font: 'Arial 54'
|
10
9
|
text str: data['Level'], x: 65, y: 65, font: 'Arial 72'
|
11
|
-
|
10
|
+
|
11
|
+
save format: :png, prefix: 'sample_csv_'
|
12
12
|
|
13
13
|
# You can also specify the sheet, starting at 0
|
14
14
|
data = xlsx file: 'sample.xlsx', sheet: 2
|
15
|
-
|
16
|
-
save format: :png, prefix: 'sample_csv_'
|
17
15
|
end
|
18
16
|
|
19
17
|
# CSV is also a Squib-module-level function, so this also works:
|
data/samples/custom-config.yml
CHANGED
data/samples/custom_config.rb
CHANGED
@@ -4,7 +4,7 @@ Squib::Deck.new(config: 'custom-config.yml') do
|
|
4
4
|
# Custom color defined in our config
|
5
5
|
background color: :foo
|
6
6
|
|
7
|
-
# Hints
|
7
|
+
# Hints can be turned on in the config file
|
8
8
|
text str: 'The Title', x: 0, y: 78, width: 825,
|
9
9
|
font: 'Arial 72', align: :center
|
10
10
|
|
data/samples/draw_shapes.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'squib'
|
2
2
|
|
3
3
|
Squib::Deck.new do
|
4
|
+
background color: :white
|
4
5
|
rect x: 300, y: 300, width: 400, height: 400,
|
5
6
|
fill_color: :blue, stroke_color: :red, stroke_width: 50.0
|
6
7
|
|
@@ -20,5 +21,15 @@ Squib::Deck.new do
|
|
20
21
|
stroke_width: 12.0, stroke_color: :cyan,
|
21
22
|
fill_color: :burgundy
|
22
23
|
|
24
|
+
ellipse x: 50, y: 925, width: 200, height: 100,
|
25
|
+
stroke_width: 5.0, stroke_color: :cyan,
|
26
|
+
fill_color: :burgundy
|
27
|
+
|
28
|
+
star x: 300, y: 1000, n: 5, inner_radius: 10, outer_radius: 25,
|
29
|
+
fill_color: :burgundy, stroke_color: :cyan, stroke_width: 3
|
30
|
+
|
31
|
+
polygon x: 500, y: 1000, n: 5, radius: 25, angle: Math::PI / 2,
|
32
|
+
fill_color: :burgundy, stroke_color: :cyan, stroke_width: 2
|
33
|
+
|
23
34
|
save_png prefix: 'shape_'
|
24
35
|
end
|
data/samples/embed_text.rb
CHANGED
@@ -61,7 +61,7 @@ Squib::Deck.new do
|
|
61
61
|
text(str: embed_text, font: 'Sans 21',
|
62
62
|
x: 400, y: 320, width: 180, height: 300,
|
63
63
|
align: :center, ellipsize: false, justify: false, hint: :magenta) do |embed|
|
64
|
-
embed.svg key: ':tool:', width: 28, height: 28,
|
64
|
+
embed.svg key: ':tool:', width: 28, height: 28, data: File.read('spanner.svg')
|
65
65
|
embed.svg key: ':health:', width: 28, height: 28, file: 'glass-heart.svg'
|
66
66
|
embed.png key: ':purse:', width: 28, height: 28, file: 'shiny-purse.png'
|
67
67
|
end
|
data/samples/hand.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'squib'
|
2
|
+
|
3
|
+
Squib::Deck.new(cards: 8, layout: 'playing-card.yml') do
|
4
|
+
background color: :cyan
|
5
|
+
rect x: 37, y: 37, width: 750, height: 1050, fill_color: :black, radius: 25
|
6
|
+
rect x: 75, y: 75, width: 675, height: 975, fill_color: :white, radius: 20
|
7
|
+
text str: ('A'..'Z').to_a, layout: :bonus_ul, font: 'Sans bold 100'
|
8
|
+
|
9
|
+
# Defaults are sensible
|
10
|
+
hand #saves to _output/hand.png
|
11
|
+
|
12
|
+
# Here's a prettier version:
|
13
|
+
# - Each card is trimmed with rounded corners
|
14
|
+
# - Zero radius means cards rotate about the bottom of the card
|
15
|
+
# - Cards are shown in reverse order
|
16
|
+
hand trim: 37.5, trim_radius: 25,
|
17
|
+
radius: 0,
|
18
|
+
range: 7.downto(0),
|
19
|
+
file: 'hand_pretty.png'
|
20
|
+
|
21
|
+
# Tip: you can have the top card be on the left by reversing the range
|
22
|
+
# angle_range: (Math::PI / 4)..(Math::PI / -4)
|
23
|
+
end
|
24
|
+
|
data/samples/load_images.rb
CHANGED
@@ -17,6 +17,20 @@ Squib::Deck.new(width: 825, height: 1125, cards: 1) do
|
|
17
17
|
# Squib prepends a #-sign if one is not specified
|
18
18
|
svg file: 'spanner.svg', id: 'backdrop', x: 50, y: 450, width: 125, height: 125
|
19
19
|
|
20
|
+
# We can also load SVGs as a string of XML
|
21
|
+
svg data: File.read('spanner.svg'), x: 50, y: 600, width: 75, height: 75
|
22
|
+
|
23
|
+
# The svg data field works nicely with modifying the SVG XML on-the-fly.
|
24
|
+
# To run this one, do `gem install game_icons` and uncomment the following
|
25
|
+
#
|
26
|
+
# require 'game_icons'
|
27
|
+
# svg data: GameIcons.get('angler-fish').recolor(fg: '#ccc', bg: '#333').string,
|
28
|
+
# x: 150, y: 600, width: 75, height: 75
|
29
|
+
#
|
30
|
+
# More examples at https://github.com/andymeneely/game_icons
|
31
|
+
# (or `gem install game_icons`) to get & manipulate art from game-icons.net
|
32
|
+
# Nokogiri (already included in Squib) is also great for XML manipulation.
|
33
|
+
|
20
34
|
# WARNING! If you choose to use the SVG ID, the x-y coordinates are still
|
21
35
|
# relative to the SVG page. See this example in an SVG editor
|
22
36
|
svg file: 'offset.svg', id: 'thing', x: 0, y: 0, width: 600, height: 600
|
data/samples/sample.csv
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
Type,"
|
2
|
-
Thief,
|
3
|
-
Mastermind,
|
1
|
+
Type,"Level"
|
2
|
+
Thief,1
|
3
|
+
Mastermind,2
|
data/samples/text_options.rb
CHANGED
@@ -78,6 +78,10 @@ Squib::Deck.new(width: 825, height: 1125, cards: 3) do
|
|
78
78
|
embed.svg key: ':health:', width: 28, height: 28, file: 'glass-heart.svg'
|
79
79
|
end
|
80
80
|
|
81
|
+
text str: "Stroke n <span fgcolor=\"\#ff0000\">fill</span>",
|
82
|
+
color: :green, stroke_width: 2.0, stroke_color: :blue,
|
83
|
+
x: '1.8in', y: '3in', width: '0.85in', font: 'Sans Bold 26', markup: true
|
84
|
+
|
81
85
|
text str: "<b>Markup</b> is <i>quite</i> <s>'easy'</s> <span fgcolor=\"\#ff0000\">awesome</span>. Can't beat those \"smart\" 'quotes', now with 10--20% more en-dashes --- and em-dashes --- with explicit ellipses too...",
|
82
86
|
markup: true,
|
83
87
|
x: 50, y: 1000,
|
data/spec/api/api_data_spec.rb
CHANGED
@@ -28,4 +28,23 @@ describe Squib::Deck do
|
|
28
28
|
})
|
29
29
|
end
|
30
30
|
end
|
31
|
+
|
32
|
+
context '#xlsx' do
|
33
|
+
it 'loads basic xlsx data' do
|
34
|
+
expect(Squib.xlsx(file: xlsx_file('basic.xlsx'))).to eq({
|
35
|
+
'Name' => %w(Larry Curly Mo),
|
36
|
+
'General Number' => %w(1 2 3), #general types always get loaded as strings with no conversion
|
37
|
+
'Actual Number' => [4.0, 5.0, 6.0], #numbers get auto-converted to integers
|
38
|
+
})
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'loads xlsx with formulas' do
|
42
|
+
expect(Squib.xlsx(file: xlsx_file('formulas.xlsx'))).to eq({
|
43
|
+
'A' => %w(1 2),
|
44
|
+
'B' => %w(3 4),
|
45
|
+
'Sum' => %w(4 6),
|
46
|
+
})
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
31
50
|
end
|