squib 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +162 -133
- data/Gemfile +4 -4
- data/README.md +630 -550
- data/RELEASE TODO.md +18 -18
- data/Rakefile +99 -99
- data/lib/squib.rb +32 -32
- data/lib/squib/api/background.rb +20 -19
- data/lib/squib/api/data.rb +100 -99
- data/lib/squib/api/image.rb +90 -76
- data/lib/squib/api/save.rb +149 -103
- data/lib/squib/api/settings.rb +35 -37
- data/lib/squib/api/shapes.rb +230 -228
- data/lib/squib/api/text.rb +65 -66
- data/lib/squib/api/text_embed.rb +96 -66
- data/lib/squib/args/arg_loader.rb +138 -0
- data/lib/squib/args/box.rb +55 -0
- data/lib/squib/args/card_range.rb +32 -0
- data/lib/squib/args/color_validator.rb +12 -0
- data/lib/squib/args/coords.rb +33 -0
- data/lib/squib/args/dir_validator.rb +16 -0
- data/lib/squib/args/draw.rb +92 -0
- data/lib/squib/args/embed_adjust.rb +25 -0
- data/lib/squib/args/embed_key.rb +17 -0
- data/lib/squib/args/hand_special.rb +37 -0
- data/lib/squib/args/input_file.rb +37 -0
- data/lib/squib/args/paint.rb +44 -0
- data/lib/squib/args/paragraph.rb +115 -0
- data/lib/squib/args/save_batch.rb +60 -0
- data/lib/squib/args/scale_box.rb +53 -0
- data/lib/squib/args/sheet.rb +72 -0
- data/lib/squib/args/showcase_special.rb +38 -0
- data/lib/squib/args/svg_special.rb +37 -0
- data/lib/squib/args/transform.rb +25 -0
- data/lib/squib/args/typographer.rb +117 -117
- data/lib/squib/card.rb +67 -67
- data/lib/squib/conf.rb +117 -111
- data/lib/squib/constants.rb +178 -178
- data/lib/squib/deck.rb +113 -111
- data/lib/squib/graphics/cairo_context_wrapper.rb +99 -53
- data/lib/squib/graphics/gradient_regex.rb +46 -46
- data/lib/squib/graphics/hand.rb +42 -43
- data/lib/squib/graphics/image.rb +76 -73
- data/lib/squib/graphics/save_doc.rb +103 -137
- data/lib/squib/graphics/save_images.rb +33 -33
- data/lib/squib/graphics/shapes.rb +119 -152
- data/lib/squib/graphics/showcase.rb +85 -88
- data/lib/squib/graphics/text.rb +176 -216
- data/lib/squib/layout_parser.rb +91 -89
- data/lib/squib/layouts/economy.yml +85 -0
- data/lib/squib/layouts/fantasy.yml +101 -0
- data/lib/squib/layouts/hand.yml +62 -46
- data/lib/squib/layouts/playing-card.yml +35 -18
- data/lib/squib/project_template/config.yml +45 -40
- data/lib/squib/version.rb +10 -10
- data/samples/color_shortcuts.rb +6 -0
- data/samples/csv_import.rb +18 -18
- data/samples/custom-config.yml +5 -5
- data/samples/custom_config.rb +18 -18
- data/samples/draw_shapes.rb +45 -35
- data/samples/embed_text.rb +88 -90
- data/samples/hand.rb +24 -24
- data/samples/layouts.rb +62 -61
- data/samples/layouts_builtin.rb +51 -0
- data/samples/load_images.rb +78 -64
- data/samples/ranges.rb +64 -53
- data/samples/sample.csv +2 -2
- data/samples/text_options.rb +102 -94
- data/spec/api/api_data_spec.rb +57 -50
- data/spec/api/api_settings_spec.rb +37 -17
- data/spec/args/box_spec.rb +127 -0
- data/spec/args/draw_spec.rb +95 -0
- data/spec/args/embed_key_spec.rb +13 -0
- data/spec/args/input_file_spec.rb +21 -0
- data/spec/args/paint_spec.rb +22 -0
- data/spec/args/paragraph_spec.rb +153 -0
- data/spec/args/range_spec.rb +36 -0
- data/spec/args/save_batch_spec.rb +51 -0
- data/spec/args/scale_box_spec.rb +71 -0
- data/spec/args/sheet_spec.rb +58 -0
- data/spec/args/showcase_special_spec.rb +15 -0
- data/spec/data/samples/autoscale_font.rb.txt +84 -87
- data/spec/data/samples/basic.rb.txt +209 -203
- data/spec/data/samples/cairo_access.rb.txt +2 -2
- data/spec/data/samples/config_text_markup.rb.txt +72 -75
- data/spec/data/samples/csv_import.rb.txt +76 -80
- data/spec/data/samples/custom_config.rb.txt +48 -49
- data/spec/data/samples/draw_shapes.rb.txt +100 -42
- data/spec/data/samples/embed_text.rb.txt +283 -295
- data/spec/data/samples/excel.rb.txt +162 -171
- data/spec/data/samples/gradients.rb.txt +79 -67
- data/spec/data/samples/hand.rb.txt +538 -514
- data/spec/data/samples/hello_world.rb.txt +36 -38
- data/spec/data/samples/load_images.rb.txt +41 -5
- data/spec/data/samples/portrait-landscape.rb.txt +49 -51
- data/spec/data/samples/ranges.rb.txt +460 -429
- data/spec/data/samples/saves.rb.txt +801 -785
- data/spec/data/samples/showcase.rb.txt +5910 -5906
- data/spec/data/samples/text_options.rb.txt +1125 -981
- data/spec/data/samples/tgc_proofs.rb.txt +81 -79
- data/spec/data/samples/units.rb.txt +18 -12
- data/spec/data/xlsx/with_macros.xlsm +0 -0
- data/spec/graphics/cairo_context_wrapper_spec.rb +84 -75
- data/spec/graphics/graphics_images_spec.rb +94 -85
- data/spec/graphics/graphics_save_doc_spec.rb +67 -65
- data/spec/samples/expected/hand.png +0 -0
- data/spec/samples/expected/hand_pretty.png +0 -0
- data/spec/samples/expected/layout_00.png +0 -0
- data/spec/samples/expected/load_images_00.png +0 -0
- data/spec/samples/expected/ranges_00.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/samples_regression_spec.rb +82 -82
- data/spec/spec_helper.rb +3 -2
- data/squib.gemspec +48 -48
- data/squib.sublime-project +42 -36
- metadata +61 -33
- data/lib/squib/input_helpers.rb +0 -238
- data/spec/api/api_image_spec.rb +0 -38
- data/spec/api/api_text_spec.rb +0 -37
- data/spec/graphics/graphics_shapes_spec.rb +0 -85
- data/spec/graphics/graphics_text_spec.rb +0 -164
- data/spec/input_helpers_spec.rb +0 -238
- 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/ranges_01.png +0 -0
- data/spec/samples/expected/ranges_02.png +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'squib'
|
|
2
|
+
|
|
3
|
+
# This sample demonstrates the built-in layouts for Squib.
|
|
4
|
+
# Each card demonstrates a different built-in layout.
|
|
5
|
+
Squib::Deck.new(layout: 'fantasy.yml') do
|
|
6
|
+
background color: 'white'
|
|
7
|
+
|
|
8
|
+
set font: 'Times New Roman,Serif 32'
|
|
9
|
+
hint text: '#333' # show extents of text boxes to demo the layout
|
|
10
|
+
|
|
11
|
+
text str: 'fantasy.yml', layout: :title
|
|
12
|
+
text str: 'ur', layout: :upper_right
|
|
13
|
+
text str: 'art', layout: :art
|
|
14
|
+
text str: 'type', layout: :type
|
|
15
|
+
text str: 'tr', layout: :type_right
|
|
16
|
+
text str: 'description', layout: :description
|
|
17
|
+
text str: 'lr', layout: :lower_right
|
|
18
|
+
text str: 'll', layout: :lower_left
|
|
19
|
+
text str: 'credits', layout: :copy
|
|
20
|
+
|
|
21
|
+
rect layout: :safe
|
|
22
|
+
rect layout: :cut
|
|
23
|
+
save_png prefix: 'layouts_builtin_fantasy_'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
Squib::Deck.new(layout: 'economy.yml') do
|
|
27
|
+
background color: 'white'
|
|
28
|
+
|
|
29
|
+
set font: 'Times New Roman,Serif 32'
|
|
30
|
+
hint text: '#333' # show extents of text boxes to demo the layout
|
|
31
|
+
|
|
32
|
+
text str: 'economy.yml', layout: :title
|
|
33
|
+
text str: 'art', layout: :art
|
|
34
|
+
text str: 'description', layout: :description
|
|
35
|
+
text str: 'type', layout: :type
|
|
36
|
+
text str: 'lr', layout: :lower_right
|
|
37
|
+
text str: 'll', layout: :lower_left
|
|
38
|
+
text str: 'credits', layout: :copy
|
|
39
|
+
|
|
40
|
+
rect layout: :safe
|
|
41
|
+
rect layout: :cut
|
|
42
|
+
save_png prefix: 'layouts_builtin_economy_'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Stitch together a deck of all the above examples
|
|
46
|
+
Squib::Deck.new(cards: 2) do
|
|
47
|
+
Dir.glob('_output/layouts_builtin_*.png').each.with_index do |file, i|
|
|
48
|
+
png file: file, range: i
|
|
49
|
+
end
|
|
50
|
+
save_sheet prefix: 'layouts_builtinsheet_'
|
|
51
|
+
end
|
data/samples/load_images.rb
CHANGED
|
@@ -1,64 +1,78 @@
|
|
|
1
|
-
require 'squib'
|
|
2
|
-
|
|
3
|
-
Squib::Deck.new(width: 825, height: 1125, cards: 1) do
|
|
4
|
-
background color: '#0b7c8e'
|
|
5
|
-
rect x: 38, y: 38, width: 750, height: 1050, x_radius: 38, y_radius: 38
|
|
6
|
-
|
|
7
|
-
png file: 'shiny-purse.png', x: 620, y: 75 # no scaling is done by default
|
|
8
|
-
svg file: 'spanner.svg', x: 620, y: 218
|
|
9
|
-
|
|
10
|
-
# Can be scaled if width and height are set
|
|
11
|
-
svg file: 'spanner.svg', x: 50, y: 50, width: 250, height: 250
|
|
12
|
-
png file: 'shiny-purse.png', x: 305, y: 50, width: 250, height: 250
|
|
13
|
-
#...but PNGs will warn if it's an upscale
|
|
14
|
-
|
|
15
|
-
#
|
|
16
|
-
svg file: 'spanner.svg',
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
#
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
#
|
|
39
|
-
|
|
40
|
-
#
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
#
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
#
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
1
|
+
require 'squib'
|
|
2
|
+
|
|
3
|
+
Squib::Deck.new(width: 825, height: 1125, cards: 1) do
|
|
4
|
+
background color: '#0b7c8e'
|
|
5
|
+
rect x: 38, y: 38, width: 750, height: 1050, x_radius: 38, y_radius: 38
|
|
6
|
+
|
|
7
|
+
png file: 'shiny-purse.png', x: 620, y: 75 # no scaling is done by default
|
|
8
|
+
svg file: 'spanner.svg', x: 620, y: 218
|
|
9
|
+
|
|
10
|
+
# Can be scaled if width and height are set
|
|
11
|
+
svg file: 'spanner.svg', x: 50, y: 50, width: 250, height: 250
|
|
12
|
+
png file: 'shiny-purse.png', x: 305, y: 50, width: 250, height: 250
|
|
13
|
+
#...but PNGs will warn if it's an upscale
|
|
14
|
+
|
|
15
|
+
# Can be scaled using just width or height, if one of them is set to :scale
|
|
16
|
+
svg file: 'spanner.svg', x: 200, y: 350, width: 35, height: :scale
|
|
17
|
+
svg file: 'spanner.svg', x: 200, y: 390, width: :scale, height: 35
|
|
18
|
+
png file: 'shiny-purse.png', x: 240, y: 350, width: 35, height: :scale
|
|
19
|
+
png file: 'shiny-purse.png', x: 240, y: 390, width: :scale, height: 35
|
|
20
|
+
|
|
21
|
+
# We can also limit our rendering to a single object, if the SVG ID is set
|
|
22
|
+
svg file: 'spanner.svg', id: '#backdrop', x: 50, y: 350, width: 75, height: 75
|
|
23
|
+
# Squib prepends a #-sign if one is not specified
|
|
24
|
+
svg file: 'spanner.svg', id: 'backdrop', x: 50, y: 450, width: 125, height: 125
|
|
25
|
+
|
|
26
|
+
# We can also load SVGs as a string of XML
|
|
27
|
+
svg data: File.read('spanner.svg'), x: 50, y: 600, width: 75, height: 75
|
|
28
|
+
|
|
29
|
+
# The svg data field works nicely with modifying the SVG XML on-the-fly.
|
|
30
|
+
# To run this one, do `gem install game_icons` and uncomment the following
|
|
31
|
+
#
|
|
32
|
+
# require 'game_icons'
|
|
33
|
+
# svg data: GameIcons.get('angler-fish').recolor(fg: '#ccc', bg: '#333').string,
|
|
34
|
+
# x: 150, y: 600, width: 75, height: 75
|
|
35
|
+
#
|
|
36
|
+
# More examples at https://github.com/andymeneely/game_icons
|
|
37
|
+
# (or `gem install game_icons`) to get & manipulate art from game-icons.net
|
|
38
|
+
# Nokogiri (already included in Squib) is also great for XML manipulation.
|
|
39
|
+
|
|
40
|
+
# WARNING! If you choose to use the SVG ID, the x-y coordinates are still
|
|
41
|
+
# relative to the SVG page. See this example in an SVG editor
|
|
42
|
+
svg file: 'offset.svg', id: 'thing', x: 0, y: 0, width: 600, height: 600
|
|
43
|
+
|
|
44
|
+
# Over 15 different blending operators are supported.
|
|
45
|
+
# See http://cairographics.org/operators
|
|
46
|
+
# Alpha transparency too
|
|
47
|
+
png file: 'ball.png', x: 50, y: 700
|
|
48
|
+
png file: 'grit.png', x: 70, y: 750, blend: :color_burn, alpha: 0.75
|
|
49
|
+
|
|
50
|
+
# Images can be rotated around their upper-left corner
|
|
51
|
+
png file: 'shiny-purse.png', x: 300, y: 700, angle: 0.0 # default (no rotate)
|
|
52
|
+
png file: 'shiny-purse.png', x: 300, y: 800, angle: Math::PI / 4
|
|
53
|
+
svg file: 'spanner.svg', x: 300, y: 900, angle: Math::PI / 2 - 0.1
|
|
54
|
+
|
|
55
|
+
# Images can also be used as masks instead of being directly painted.
|
|
56
|
+
# This is particularly useful for switching directly over to black-and-white for printing
|
|
57
|
+
# Or, if you want the same image to be used but with different colors/gradients
|
|
58
|
+
svg mask: '#00ff00',
|
|
59
|
+
file: 'glass-heart.svg',
|
|
60
|
+
x: 500, y: 600, width: 200, height: 200
|
|
61
|
+
svg mask: '(0,0)(0,500) #ccc@0.0 #333@1.0',
|
|
62
|
+
file: 'glass-heart.svg',
|
|
63
|
+
x: 500, y: 800, width: 200, height: 200
|
|
64
|
+
|
|
65
|
+
# Masks are based on the alpha channel, so this is just a magenta square
|
|
66
|
+
png mask: :magenta, file: 'shiny-purse.png',
|
|
67
|
+
x: 650, y: 950
|
|
68
|
+
|
|
69
|
+
# Note that this method does nothing, even though it would normally fill up
|
|
70
|
+
# the card. force_id: true looks to the id field to be non-empty to render.
|
|
71
|
+
# This is useful if you have multiple different icons in one SVG file,
|
|
72
|
+
# but sometimes want to use none.
|
|
73
|
+
# e.g. id: [:attack, :defend, nil]
|
|
74
|
+
svg file: 'spanner.svg', width: :deck, height: :deck,
|
|
75
|
+
force_id: true, id: '' # <-- the important part
|
|
76
|
+
|
|
77
|
+
save prefix: 'load_images_', format: :png
|
|
78
|
+
end
|
data/samples/ranges.rb
CHANGED
|
@@ -1,53 +1,64 @@
|
|
|
1
|
-
require 'squib'
|
|
2
|
-
|
|
3
|
-
data = {'name' => ['Thief', 'Grifter', 'Mastermind'],
|
|
4
|
-
'type' => ['Thug', 'Thinker', 'Thinker'],
|
|
5
|
-
'level' => [1,2,3]}
|
|
6
|
-
|
|
7
|
-
Squib::Deck.new(width: 825, height: 1125, cards: 3) do
|
|
8
|
-
# Default range is :all
|
|
9
|
-
background color: :white
|
|
10
|
-
text str: data['name'], x: 250, y: 55, font: 'Arial 54'
|
|
11
|
-
text str: data['level'], x: 65, y: 40, font: 'Arial 72'
|
|
12
|
-
|
|
13
|
-
# Could be explicit about using :all, too
|
|
14
|
-
text range: :all,
|
|
15
|
-
str: data['type'], x: 40, y: 128, font: 'Arial 18',
|
|
16
|
-
width: 100, align: :center
|
|
17
|
-
|
|
18
|
-
# Ranges are inclusive, zero-based
|
|
19
|
-
text range: 0..1, str: 'Thief and Grifter only!!', x: 25, y:200
|
|
20
|
-
|
|
21
|
-
# Integers are also allowed
|
|
22
|
-
text range: 0, str: 'Thief only!', x: 25, y: 250
|
|
23
|
-
|
|
24
|
-
# Negatives go from the back of the deck
|
|
25
|
-
text range: -1, str: 'Mastermind only!', x: 25, y: 250
|
|
26
|
-
text range: -2..-1, str: 'Grifter and Mastermind only!', x: 25, y: 650
|
|
27
|
-
|
|
28
|
-
# We can use Arrays too!
|
|
29
|
-
text range: [0,2], str: 'Thief and Mastermind only!!', x: 25, y:300
|
|
30
|
-
|
|
31
|
-
# Just about everything in Squib can be given an array that
|
|
32
|
-
# corresponds to the deck's cards. This allows for each card to be styled differently
|
|
33
|
-
# This renders three cards, with three strings that had three different colors at three different locations.
|
|
34
|
-
text str: %w(red green blue),
|
|
35
|
-
color: [:red, :green, :blue],
|
|
36
|
-
x: [40, 80, 120],
|
|
37
|
-
y: [700, 750, 800]
|
|
38
|
-
|
|
39
|
-
# Useful idiom: construct a hash from card names back to its index (ID),
|
|
40
|
-
# then use a range. No need to memorize IDs, and you can add cards easily
|
|
41
|
-
id = {} ; data['name'].each_with_index{ |name,i| id[name] = i}
|
|
42
|
-
text range: id['Thief']..id['Grifter'],
|
|
43
|
-
str: 'Thief through Grifter with id lookup!!',
|
|
44
|
-
x:25, y: 400
|
|
45
|
-
|
|
46
|
-
# Useful idiom: generate arrays from a column called 'type'
|
|
47
|
-
type = {}; data['type'].each_with_index{ |t,i| (type[t] ||= []) << i}
|
|
48
|
-
text range: type['Thinker'],
|
|
49
|
-
str: 'Only for Thinkers!',
|
|
50
|
-
x:25, y: 500
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
1
|
+
require 'squib'
|
|
2
|
+
|
|
3
|
+
data = {'name' => ['Thief', 'Grifter', 'Mastermind'],
|
|
4
|
+
'type' => ['Thug', 'Thinker', 'Thinker'],
|
|
5
|
+
'level' => [1,2,3]}
|
|
6
|
+
|
|
7
|
+
Squib::Deck.new(width: 825, height: 1125, cards: 3) do
|
|
8
|
+
# Default range is :all
|
|
9
|
+
background color: :white
|
|
10
|
+
text str: data['name'], x: 250, y: 55, font: 'Arial 54'
|
|
11
|
+
text str: data['level'], x: 65, y: 40, font: 'Arial 72'
|
|
12
|
+
|
|
13
|
+
# Could be explicit about using :all, too
|
|
14
|
+
text range: :all,
|
|
15
|
+
str: data['type'], x: 40, y: 128, font: 'Arial 18',
|
|
16
|
+
width: 100, align: :center
|
|
17
|
+
|
|
18
|
+
# Ranges are inclusive, zero-based
|
|
19
|
+
text range: 0..1, str: 'Thief and Grifter only!!', x: 25, y:200
|
|
20
|
+
|
|
21
|
+
# Integers are also allowed
|
|
22
|
+
text range: 0, str: 'Thief only!', x: 25, y: 250
|
|
23
|
+
|
|
24
|
+
# Negatives go from the back of the deck
|
|
25
|
+
text range: -1, str: 'Mastermind only!', x: 25, y: 250
|
|
26
|
+
text range: -2..-1, str: 'Grifter and Mastermind only!', x: 25, y: 650
|
|
27
|
+
|
|
28
|
+
# We can use Arrays too!
|
|
29
|
+
text range: [0,2], str: 'Thief and Mastermind only!!', x: 25, y:300
|
|
30
|
+
|
|
31
|
+
# Just about everything in Squib can be given an array that
|
|
32
|
+
# corresponds to the deck's cards. This allows for each card to be styled differently
|
|
33
|
+
# This renders three cards, with three strings that had three different colors at three different locations.
|
|
34
|
+
text str: %w(red green blue),
|
|
35
|
+
color: [:red, :green, :blue],
|
|
36
|
+
x: [40, 80, 120],
|
|
37
|
+
y: [700, 750, 800]
|
|
38
|
+
|
|
39
|
+
# Useful idiom: construct a hash from card names back to its index (ID),
|
|
40
|
+
# then use a range. No need to memorize IDs, and you can add cards easily
|
|
41
|
+
id = {} ; data['name'].each_with_index{ |name,i| id[name] = i}
|
|
42
|
+
text range: id['Thief']..id['Grifter'],
|
|
43
|
+
str: 'Thief through Grifter with id lookup!!',
|
|
44
|
+
x:25, y: 400
|
|
45
|
+
|
|
46
|
+
# Useful idiom: generate arrays from a column called 'type'
|
|
47
|
+
type = {}; data['type'].each_with_index{ |t,i| (type[t] ||= []) << i}
|
|
48
|
+
text range: type['Thinker'],
|
|
49
|
+
str: 'Only for Thinkers!',
|
|
50
|
+
x:25, y: 500
|
|
51
|
+
|
|
52
|
+
# Useful idiom: draw a different number of images for different cards
|
|
53
|
+
hearts = [nil, 1, 2] #i.e. card 0 has no hearts, card 2 has 2 hearts drawn
|
|
54
|
+
1.upto(2).each do |n|
|
|
55
|
+
range = hearts.each_index.select { |i| hearts[i] == n}
|
|
56
|
+
n.times do |i|
|
|
57
|
+
svg file: 'glass-heart.svg', range: range,
|
|
58
|
+
x: 150, y: 55 + i*42, width: 40, height: 40
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
rect color: 'black' # just a border
|
|
63
|
+
save_sheet prefix: 'ranges_', columns: 3
|
|
64
|
+
end
|
data/samples/sample.csv
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
Type,"Level"
|
|
2
|
-
Thief,1
|
|
1
|
+
Type,"Level"
|
|
2
|
+
Thief,1
|
|
3
3
|
Mastermind,2
|
data/samples/text_options.rb
CHANGED
|
@@ -1,94 +1,102 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
require 'squib'
|
|
3
|
-
|
|
4
|
-
data = {'name' => ['Thief', 'Grifter', 'Mastermind'],
|
|
5
|
-
'level' => [1,2,3]}
|
|
6
|
-
longtext = "This is left-justified text, with newlines.\nWhat do you know about tweetle beetles? well... When 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."
|
|
7
|
-
|
|
8
|
-
Squib::Deck.new(width: 825, height: 1125, cards: 3) do
|
|
9
|
-
background color: :white
|
|
10
|
-
rect x: 15, y: 15, width: 795, height: 1095, x_radius: 50, y_radius: 50
|
|
11
|
-
rect x: 30, y: 30, width: 128, height: 128, x_radius: 25, y_radius: 25
|
|
12
|
-
|
|
13
|
-
# Arrays are rendered over each card
|
|
14
|
-
text str: data['name'], x: 250, y: 55, font: 'Arial weight=900 54'
|
|
15
|
-
text str: data['level'], x: 65, y: 40, font: 'Arial 72', color: :burnt_orange
|
|
16
|
-
|
|
17
|
-
text str: 'Font strings are expressive!', x:65, y: 200,
|
|
18
|
-
font: 'Impact bold italic 36'
|
|
19
|
-
|
|
20
|
-
text str: 'Font strings are expressive!', x:65, y: 300,
|
|
21
|
-
font: 'Arial,Verdana weight=900 style=oblique 36'
|
|
22
|
-
|
|
23
|
-
text str: 'Font string sizes can be overridden per card.', x: 65, y: 350,
|
|
24
|
-
font: 'Impact 36', font_size: [16, 20, 24]
|
|
25
|
-
|
|
26
|
-
text str: 'This text has fixed width, fixed height, center-aligned, middle-valigned, has a red hint
|
|
27
|
-
hint: :red,
|
|
28
|
-
x: 65, y: 400,
|
|
29
|
-
width: 300, height: 125,
|
|
30
|
-
align: :center, valign: 'MIDDLE', # these can be specified with case-insenstive strings too
|
|
31
|
-
font: 'Serif 16'
|
|
32
|
-
|
|
33
|
-
extents = text str: 'Ink extent return value',
|
|
34
|
-
x: 65, y: 550,
|
|
35
|
-
font: 'Sans Bold', font_size: [16, 20, 24]
|
|
36
|
-
margin = 10
|
|
37
|
-
# Extents come back as an array of hashes, which can get split out like this
|
|
38
|
-
ws = extents.inject([]) { |arr, ext| arr << ext[:width] + 10; arr }
|
|
39
|
-
hs = extents.inject([]) { |arr, ext| arr << ext[:height] + 10; arr }
|
|
40
|
-
rect x: 65 - margin/2, y: 550 - margin/2,
|
|
41
|
-
width: ws, height: hs,
|
|
42
|
-
radius: 10, stroke_color: :black
|
|
43
|
-
|
|
44
|
-
# If width & height are defined and the text will overflow the box, we can ellipsize.
|
|
45
|
-
text str: "Ellipsization!\nThe ultimate question of life, the universe, and everything to life and everything is 42",
|
|
46
|
-
hint: :green, font: 'Arial 22',
|
|
47
|
-
x: 450, y: 400,
|
|
48
|
-
width: 280, height: 180,
|
|
49
|
-
ellipsize: true
|
|
50
|
-
|
|
51
|
-
# Text hints are guides for showing you how your text boxes are laid out exactly
|
|
52
|
-
hint text: :cyan
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
hint text: :off
|
|
57
|
-
text str: 'See? No hint here.',
|
|
58
|
-
x: 565, y: 625,
|
|
59
|
-
font: 'Arial 22'
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
#
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
embed.svg key: ':
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
width:
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
require 'squib'
|
|
3
|
+
|
|
4
|
+
data = {'name' => ['Thief', 'Grifter', 'Mastermind'],
|
|
5
|
+
'level' => [1,2,3]}
|
|
6
|
+
longtext = "This is left-justified text, with newlines.\nWhat do you know about tweetle beetles? well... When 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."
|
|
7
|
+
|
|
8
|
+
Squib::Deck.new(width: 825, height: 1125, cards: 3) do
|
|
9
|
+
background color: :white
|
|
10
|
+
rect x: 15, y: 15, width: 795, height: 1095, x_radius: 50, y_radius: 50
|
|
11
|
+
rect x: 30, y: 30, width: 128, height: 128, x_radius: 25, y_radius: 25
|
|
12
|
+
|
|
13
|
+
# Arrays are rendered over each card
|
|
14
|
+
text str: data['name'], x: 250, y: 55, font: 'Arial weight=900 54'
|
|
15
|
+
text str: data['level'], x: 65, y: 40, font: 'Arial 72', color: :burnt_orange
|
|
16
|
+
|
|
17
|
+
text str: 'Font strings are expressive!', x:65, y: 200,
|
|
18
|
+
font: 'Impact bold italic 36'
|
|
19
|
+
|
|
20
|
+
text str: 'Font strings are expressive!', x:65, y: 300,
|
|
21
|
+
font: 'Arial,Verdana weight=900 style=oblique 36'
|
|
22
|
+
|
|
23
|
+
text str: 'Font string sizes can be overridden per card.', x: 65, y: 350,
|
|
24
|
+
font: 'Impact 36', font_size: [16, 20, 24]
|
|
25
|
+
|
|
26
|
+
text str: 'This text has fixed width, fixed height, center-aligned, middle-valigned, and has a red hint',
|
|
27
|
+
hint: :red,
|
|
28
|
+
x: 65, y: 400,
|
|
29
|
+
width: 300, height: 125,
|
|
30
|
+
align: :center, valign: 'MIDDLE', # these can be specified with case-insenstive strings too
|
|
31
|
+
font: 'Serif 16'
|
|
32
|
+
|
|
33
|
+
extents = text str: 'Ink extent return value',
|
|
34
|
+
x: 65, y: 550,
|
|
35
|
+
font: 'Sans Bold', font_size: [16, 20, 24]
|
|
36
|
+
margin = 10
|
|
37
|
+
# Extents come back as an array of hashes, which can get split out like this
|
|
38
|
+
ws = extents.inject([]) { |arr, ext| arr << ext[:width] + 10; arr }
|
|
39
|
+
hs = extents.inject([]) { |arr, ext| arr << ext[:height] + 10; arr }
|
|
40
|
+
rect x: 65 - margin/2, y: 550 - margin/2,
|
|
41
|
+
width: ws, height: hs,
|
|
42
|
+
radius: 10, stroke_color: :black
|
|
43
|
+
|
|
44
|
+
# If width & height are defined and the text will overflow the box, we can ellipsize.
|
|
45
|
+
text str: "Ellipsization!\nThe ultimate question of life, the universe, and everything to life and everything is 42",
|
|
46
|
+
hint: :green, font: 'Arial 22',
|
|
47
|
+
x: 450, y: 400,
|
|
48
|
+
width: 280, height: 180,
|
|
49
|
+
ellipsize: true
|
|
50
|
+
|
|
51
|
+
# Text hints are guides for showing you how your text boxes are laid out exactly
|
|
52
|
+
hint text: :cyan
|
|
53
|
+
set font: 'Serif 20' # Impacts all future text calls (unless they specify differently)
|
|
54
|
+
text str: 'Text hints & fonts are globally togglable!', x: 65, y: 625
|
|
55
|
+
set font: :default # back to Squib-wide default
|
|
56
|
+
hint text: :off
|
|
57
|
+
text str: 'See? No hint here.',
|
|
58
|
+
x: 565, y: 625,
|
|
59
|
+
font: 'Arial 22'
|
|
60
|
+
|
|
61
|
+
# Text can be rotated, in radians, about the upper-left corner of the text box.
|
|
62
|
+
text str: 'Rotated',
|
|
63
|
+
x: 565, y: 675, angle: 0.2,
|
|
64
|
+
font: 'Arial 18', hint: :red
|
|
65
|
+
|
|
66
|
+
# Text can be justified, and have newlines
|
|
67
|
+
text str: longtext, font: 'Arial 16',
|
|
68
|
+
x: 65, y: 700,
|
|
69
|
+
width: '1.5in', height: inches(1),
|
|
70
|
+
justify: true, spacing: -6
|
|
71
|
+
|
|
72
|
+
# Here's how you embed images into text.
|
|
73
|
+
# Pass a block to the method call and use the given context
|
|
74
|
+
embed_text = 'Embedded icons! Take 1 :tool: and gain 2:health:. If Level 2, take 2 :tool:'
|
|
75
|
+
text(str: embed_text, font: 'Sans 18',
|
|
76
|
+
x: '1.8in', y: '2.5in', width: '0.85in',
|
|
77
|
+
align: :left, ellipsize: false) do |embed|
|
|
78
|
+
embed.svg key: ':tool:', width: 28, height: 28, file: 'spanner.svg'
|
|
79
|
+
embed.svg key: ':health:', width: 28, height: 28, file: 'glass-heart.svg'
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
text str: "Fill n <span fgcolor=\"\#ff0000\">stroke</span>",
|
|
83
|
+
color: :green, stroke_width: 2.0, stroke_color: :blue,
|
|
84
|
+
x: '1.8in', y: '2.9in', width: '0.85in', font: 'Sans Bold 26', markup: true
|
|
85
|
+
|
|
86
|
+
text str: "Stroke n <span fgcolor=\"\#ff0000\">fill</span>",
|
|
87
|
+
color: :green, stroke_width: 2.0, stroke_color: :blue, stroke_strategy: :stroke_first,
|
|
88
|
+
x: '1.8in', y: '3.0in', width: '0.85in', font: 'Sans Bold 26', markup: true
|
|
89
|
+
|
|
90
|
+
text str: "Dotted",
|
|
91
|
+
color: :white, stroke_width: 2.0, dash: '4 2', stroke_color: :black,
|
|
92
|
+
x: '1.8in', y: '3.1in', width: '0.85in', font: 'Sans Bold 26', markup: true
|
|
93
|
+
#
|
|
94
|
+
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...",
|
|
95
|
+
markup: true,
|
|
96
|
+
x: 50, y: 1000,
|
|
97
|
+
width: 750, height: 100,
|
|
98
|
+
valign: :bottom,
|
|
99
|
+
font: 'Serif 18', hint: :cyan
|
|
100
|
+
|
|
101
|
+
save prefix: 'text_', format: :png
|
|
102
|
+
end
|