squib 0.8.0 → 0.9.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.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +14 -0
  3. data/.travis.yml +4 -0
  4. data/CHANGELOG.md +201 -175
  5. data/Gemfile +2 -4
  6. data/README.md +650 -645
  7. data/RELEASE TODO.md +18 -18
  8. data/Rakefile +106 -99
  9. data/appveyor.yml +29 -0
  10. data/lib/squib.rb +32 -32
  11. data/lib/squib/api/background.rb +20 -20
  12. data/lib/squib/api/data.rb +131 -131
  13. data/lib/squib/api/image.rb +108 -90
  14. data/lib/squib/api/save.rb +151 -149
  15. data/lib/squib/api/settings.rb +35 -35
  16. data/lib/squib/api/shapes.rb +255 -230
  17. data/lib/squib/api/text.rb +65 -65
  18. data/lib/squib/api/text_embed.rb +96 -96
  19. data/lib/squib/args/arg_loader.rb +138 -138
  20. data/lib/squib/args/box.rb +54 -54
  21. data/lib/squib/args/card_range.rb +32 -32
  22. data/lib/squib/args/color_validator.rb +11 -11
  23. data/lib/squib/args/coords.rb +32 -32
  24. data/lib/squib/args/dir_validator.rb +16 -16
  25. data/lib/squib/args/draw.rb +92 -92
  26. data/lib/squib/args/embed_adjust.rb +25 -25
  27. data/lib/squib/args/embed_key.rb +17 -17
  28. data/lib/squib/args/hand_special.rb +37 -37
  29. data/lib/squib/args/import.rb +39 -39
  30. data/lib/squib/args/input_file.rb +37 -37
  31. data/lib/squib/args/paint.rb +43 -43
  32. data/lib/squib/args/paragraph.rb +116 -115
  33. data/lib/squib/args/save_batch.rb +63 -60
  34. data/lib/squib/args/scale_box.rb +53 -53
  35. data/lib/squib/args/sheet.rb +72 -72
  36. data/lib/squib/args/showcase_special.rb +38 -38
  37. data/lib/squib/args/svg_special.rb +37 -37
  38. data/lib/squib/args/transform.rb +60 -24
  39. data/lib/squib/args/typographer.rb +117 -117
  40. data/lib/squib/card.rb +66 -67
  41. data/lib/squib/conf.rb +131 -117
  42. data/lib/squib/constants.rb +12 -178
  43. data/lib/squib/deck.rb +113 -113
  44. data/lib/squib/graphics/cairo_context_wrapper.rb +113 -99
  45. data/lib/squib/graphics/gradient_regex.rb +46 -46
  46. data/lib/squib/graphics/hand.rb +42 -42
  47. data/lib/squib/graphics/image.rb +103 -76
  48. data/lib/squib/graphics/save_doc.rb +103 -103
  49. data/lib/squib/graphics/save_images.rb +39 -33
  50. data/lib/squib/graphics/shapes.rb +135 -119
  51. data/lib/squib/graphics/showcase.rb +85 -85
  52. data/lib/squib/graphics/text.rb +176 -176
  53. data/lib/squib/layout_parser.rb +91 -91
  54. data/lib/squib/layouts/economy.yml +85 -85
  55. data/lib/squib/layouts/fantasy.yml +101 -101
  56. data/lib/squib/layouts/hand.yml +62 -62
  57. data/lib/squib/layouts/playing-card.yml +35 -35
  58. data/lib/squib/layouts/tuck_box.yml +45 -45
  59. data/lib/squib/project_template/IDEAS.md +22 -0
  60. data/lib/squib/project_template/PLAYTESTING.md +26 -0
  61. data/lib/squib/project_template/RULES.md +21 -0
  62. data/lib/squib/project_template/config.yml +49 -45
  63. data/lib/squib/sample_helpers.rb +34 -0
  64. data/lib/squib/version.rb +10 -10
  65. data/samples/autoscale_font/_autoscale_font.rb +29 -0
  66. data/samples/color_shortcuts.rb +6 -6
  67. data/samples/csv_import.rb +26 -26
  68. data/samples/custom-config.yml +5 -5
  69. data/samples/custom_config.rb +18 -18
  70. data/samples/draw_shapes.rb +48 -45
  71. data/samples/embed_text.rb +88 -88
  72. data/samples/excel.rb +55 -55
  73. data/samples/hand.rb +24 -24
  74. data/samples/images/_images.rb +104 -0
  75. data/samples/intro/01_hello.rb +9 -0
  76. data/samples/intro/02_options.rb +15 -0
  77. data/samples/intro/03_layout.rb +12 -0
  78. data/samples/intro/04_arrays.rb +16 -0
  79. data/samples/intro/05_excel.rb +15 -0
  80. data/samples/layouts.rb +62 -62
  81. data/samples/layouts_builtin.rb +51 -51
  82. data/samples/load_images.rb +99 -78
  83. data/samples/load_images_config.yml +1 -0
  84. data/samples/quantity_explosion.csv +2 -2
  85. data/samples/ranges.rb +64 -64
  86. data/samples/sample.csv +2 -2
  87. data/samples/saves.rb +9 -1
  88. data/samples/sprites.png +0 -0
  89. data/samples/text/_text.rb +46 -0
  90. data/samples/text_options.rb +102 -102
  91. data/spec/api/api_data_spec.rb +117 -117
  92. data/spec/api/api_settings_spec.rb +37 -37
  93. data/spec/args/box_spec.rb +127 -127
  94. data/spec/args/draw_spec.rb +101 -95
  95. data/spec/args/embed_key_spec.rb +13 -13
  96. data/spec/args/input_file_spec.rb +21 -21
  97. data/spec/args/paint_spec.rb +21 -21
  98. data/spec/args/paragraph_spec.rb +152 -152
  99. data/spec/args/range_spec.rb +40 -40
  100. data/spec/args/save_batch_spec.rb +51 -51
  101. data/spec/args/scale_box_spec.rb +71 -71
  102. data/spec/args/sheet_spec.rb +58 -58
  103. data/spec/args/showcase_special_spec.rb +15 -15
  104. data/spec/args/transform_spec.rb +25 -0
  105. data/spec/card_spec.rb +11 -0
  106. data/spec/conf_spec.rb +13 -3
  107. data/spec/data/conf/unrecognized.yml +4 -0
  108. data/spec/data/csv/qty.csv +2 -2
  109. data/spec/data/csv/qty_named.csv +2 -2
  110. data/spec/data/csv/with_spaces.csv +2 -2
  111. data/spec/data/samples/autoscale_font.rb.txt +84 -84
  112. data/spec/data/samples/basic.rb.txt +227 -209
  113. data/spec/data/samples/config_text_markup.rb.txt +72 -72
  114. data/spec/data/samples/csv_import.rb.txt +213 -213
  115. data/spec/data/samples/custom_config.rb.txt +57 -48
  116. data/spec/data/samples/draw_shapes.rb.txt +555 -3
  117. data/spec/data/samples/embed_text.rb.txt +283 -283
  118. data/spec/data/samples/excel.rb.txt +661 -661
  119. data/spec/data/samples/gradients.rb.txt +77 -79
  120. data/spec/data/samples/hand.rb.txt +538 -538
  121. data/spec/data/samples/hello_world.rb.txt +36 -36
  122. data/spec/data/samples/load_images.rb.txt +170 -0
  123. data/spec/data/samples/portrait-landscape.rb.txt +51 -49
  124. data/spec/data/samples/ranges.rb.txt +472 -460
  125. data/spec/data/samples/saves.rb.txt +810 -801
  126. data/spec/data/samples/showcase.rb.txt +5926 -5910
  127. data/spec/data/samples/text_options.rb.txt +1125 -1125
  128. data/spec/data/samples/tgc_proofs.rb.txt +95 -81
  129. data/spec/graphics/cairo_context_wrapper_spec.rb +104 -84
  130. data/spec/graphics/graphics_save_doc_spec.rb +67 -67
  131. data/spec/samples/diff-with-css.example.html +39 -0
  132. data/spec/samples/expected/load_images_00.png +0 -0
  133. data/spec/samples/expected/shape_00.png +0 -0
  134. data/spec/samples/run_samples_spec.rb +17 -0
  135. data/spec/samples/samples_regression_spec.rb +72 -82
  136. data/spec/spec_helper.rb +9 -1
  137. data/squib.gemspec +49 -48
  138. data/squib.sublime-project +42 -42
  139. metadata +94 -48
  140. data/spec/graphics/graphics_images_spec.rb +0 -94
@@ -1,99 +1,113 @@
1
- require 'forwardable'
2
- require 'squib/graphics/gradient_regex'
3
-
4
- module Squib
5
- module Graphics
6
- # Wrapper class for the Cairo context. Private.
7
- # @api private
8
- class CairoContextWrapper
9
- extend Forwardable
10
-
11
- # :nodoc:
12
- # @api private
13
- attr_accessor :cairo_cxt
14
-
15
- # :nodoc:
16
- # @api private
17
- def initialize(cairo_cxt)
18
- @cairo_cxt = cairo_cxt
19
- end
20
-
21
- def_delegators :cairo_cxt, :save, :set_source_color, :paint, :restore,
22
- :translate, :rotate, :move_to, :update_pango_layout, :width, :height,
23
- :show_pango_layout, :rounded_rectangle, :set_line_width, :stroke, :fill,
24
- :set_source, :scale, :render_rsvg_handle, :circle, :triangle, :line_to,
25
- :operator=, :show_page, :clip, :transform, :mask, :create_pango_layout,
26
- :antialias=, :curve_to, :matrix, :matrix=, :identity_matrix, :pango_layout_path,
27
- :stroke_preserve, :target, :new_path, :fill_preserve, :close_path,
28
- :set_line_join, :set_line_cap, :set_dash
29
-
30
- # :nodoc:
31
- # @api private
32
- def set_source_squibcolor(arg)
33
- raise 'nil is not a valid color' if arg.nil?
34
- if match = arg.match(LINEAR_GRADIENT)
35
- x1, y1, x2, y2 = match.captures
36
- linear = Cairo::LinearPattern.new(x1.to_f, y1.to_f, x2.to_f, y2.to_f)
37
- arg.scan(STOPS).each do |color, offset|
38
- linear.add_color_stop(offset.to_f, color)
39
- end
40
- @cairo_cxt.set_source(linear)
41
- elsif match = arg.match(RADIAL_GRADIENT)
42
- x1, y1, r1, x2, y2, r2 = match.captures
43
- linear = Cairo::RadialPattern.new(x1.to_f, y1.to_f, r1.to_f,
44
- x2.to_f, y2.to_f, r2.to_f)
45
- arg.scan(STOPS).each do |color, offset|
46
- linear.add_color_stop(offset.to_f, color)
47
- end
48
- @cairo_cxt.set_source(linear)
49
- else
50
- @cairo_cxt.set_source_color(arg)
51
- end
52
- end
53
-
54
- # Convenience method for a common task
55
- # @api private
56
- def fill_n_stroke(draw)
57
- return stroke_n_fill(draw) if draw.stroke_strategy == :stroke_first
58
- set_source_squibcolor draw.fill_color
59
- fill_preserve
60
- set_source_squibcolor draw.stroke_color
61
- set_line_width draw.stroke_width
62
- set_line_join draw.join
63
- set_line_cap draw.cap
64
- set_dash draw.dash
65
- stroke
66
- end
67
-
68
- def stroke_n_fill(draw)
69
- return fill_n_stroke(draw) if draw.stroke_strategy == :fill_first
70
- set_source_squibcolor draw.stroke_color
71
- set_line_width draw.stroke_width
72
- set_line_join draw.join
73
- set_line_cap draw.cap
74
- set_dash draw.dash
75
- stroke_preserve
76
- set_source_squibcolor draw.fill_color
77
- fill
78
- end
79
-
80
- # Convenience method for a common task
81
- # @api private
82
- def fancy_stroke(draw)
83
- set_source_squibcolor draw.stroke_color
84
- set_line_width draw.stroke_width
85
- set_line_join draw.join
86
- set_line_cap draw.cap
87
- set_dash draw.dash
88
- stroke
89
- end
90
-
91
- def rotate_about(x, y, angle)
92
- translate(x, y)
93
- rotate(angle)
94
- translate(-x, -y)
95
- end
96
-
97
- end
98
- end
99
- end
1
+ require 'forwardable'
2
+ require 'squib/graphics/gradient_regex'
3
+
4
+ module Squib
5
+ module Graphics
6
+ # Wrapper class for the Cairo context. Private.
7
+ # @api private
8
+ class CairoContextWrapper
9
+ extend Forwardable
10
+
11
+ # :nodoc:
12
+ # @api private
13
+ attr_accessor :cairo_cxt
14
+
15
+ # :nodoc:
16
+ # @api private
17
+ def initialize(cairo_cxt)
18
+ @cairo_cxt = cairo_cxt
19
+ end
20
+
21
+ def_delegators :cairo_cxt, :save, :set_source_color, :paint, :restore,
22
+ :translate, :rotate, :move_to, :update_pango_layout, :width, :height,
23
+ :show_pango_layout, :rounded_rectangle, :set_line_width, :stroke, :fill,
24
+ :set_source, :scale, :render_rsvg_handle, :circle, :triangle, :line_to,
25
+ :operator=, :show_page, :clip, :transform, :mask, :create_pango_layout,
26
+ :antialias=, :curve_to, :matrix, :matrix=, :identity_matrix, :pango_layout_path,
27
+ :stroke_preserve, :target, :new_path, :fill_preserve, :close_path,
28
+ :set_line_join, :set_line_cap, :set_dash
29
+
30
+ # :nodoc:
31
+ # @api private
32
+ def set_source_squibcolor(arg)
33
+ raise 'nil is not a valid color' if arg.nil?
34
+ if match = arg.match(LINEAR_GRADIENT)
35
+ x1, y1, x2, y2 = match.captures
36
+ linear = Cairo::LinearPattern.new(x1.to_f, y1.to_f, x2.to_f, y2.to_f)
37
+ arg.scan(STOPS).each do |color, offset|
38
+ linear.add_color_stop(offset.to_f, color)
39
+ end
40
+ linear.matrix = matrix # match the coordinate systems - see bug 127
41
+ @cairo_cxt.set_source(linear)
42
+ elsif match = arg.match(RADIAL_GRADIENT)
43
+ x1, y1, r1, x2, y2, r2 = match.captures
44
+ radial = Cairo::RadialPattern.new(x1.to_f, y1.to_f, r1.to_f,
45
+ x2.to_f, y2.to_f, r2.to_f)
46
+ radial.matrix = matrix # match the coordinate systems - see bug 127
47
+ arg.scan(STOPS).each do |color, offset|
48
+ radial.add_color_stop(offset.to_f, color)
49
+ end
50
+ @cairo_cxt.set_source(radial)
51
+ else
52
+ @cairo_cxt.set_source_color(arg)
53
+ end
54
+ end
55
+
56
+ # Convenience method for a common task
57
+ # @api private
58
+ def fill_n_stroke(draw)
59
+ return stroke_n_fill(draw) if draw.stroke_strategy == :stroke_first
60
+ set_source_squibcolor draw.fill_color
61
+ fill_preserve
62
+ set_source_squibcolor draw.stroke_color
63
+ set_line_width draw.stroke_width
64
+ set_line_join draw.join
65
+ set_line_cap draw.cap
66
+ set_dash draw.dash
67
+ stroke
68
+ end
69
+
70
+ def stroke_n_fill(draw)
71
+ return fill_n_stroke(draw) if draw.stroke_strategy == :fill_first
72
+ set_source_squibcolor draw.stroke_color
73
+ set_line_width draw.stroke_width
74
+ set_line_join draw.join
75
+ set_line_cap draw.cap
76
+ set_dash draw.dash
77
+ stroke_preserve
78
+ set_source_squibcolor draw.fill_color
79
+ fill
80
+ end
81
+
82
+ # Convenience method for a common task
83
+ # @api private
84
+ def fancy_stroke(draw)
85
+ set_source_squibcolor draw.stroke_color
86
+ set_line_width draw.stroke_width
87
+ set_line_join draw.join
88
+ set_line_cap draw.cap
89
+ set_dash draw.dash
90
+ stroke
91
+ end
92
+
93
+ def rotate_about(x, y, angle)
94
+ translate(x, y)
95
+ rotate(angle)
96
+ translate(-x, -y)
97
+ end
98
+
99
+ # Flip either vertical or horizontal depending
100
+ # From the cairo website: http://cairographics.org/matrix_transform/
101
+ # cairo.Matrix(fx, 0, 0,
102
+ # fy, cx*(1-fx), cy*(fy-1))
103
+ # fx/fy = 1 means 'no flip', fx/fy = -1 are used for horizontal/vertical flip
104
+ def flip(vertical, horizontal, x, y)
105
+ v = vertical ? -1.0 : 1.0
106
+ h = horizontal ? -1.0 : 1.0
107
+ transform Cairo::Matrix.new(v, 0.0, 0.0,
108
+ h, x*(1-v), y*(1-h))
109
+ end
110
+
111
+ end
112
+ end
113
+ end
@@ -1,47 +1,47 @@
1
- module Squib
2
- # @api private
3
- module Graphics
4
- STOPS = / # used to capture the stops
5
- \s* # leading whitespace is ok
6
- (\#?[\w]+) # color
7
- @ # no spaces here
8
- (\d+\.?\d*) # offset number
9
- /x
10
-
11
- LINEAR_GRADIENT = /
12
- \( \s* # coordinate 1
13
- (\d+\.?\d*) \s* # x1 number
14
- ,\s* # whitespace after comma is ok
15
- (\d+\.?\d*) \s* # y1 number
16
- \)
17
- \s* # space between coordinates is ok
18
- \( \s* # coordinate 2
19
- (\d+\.?\d*) \s* # x2 number
20
- ,\s* # whitespace after comma is ok
21
- (\d+\.?\d*) \s* # y2 number
22
- \)
23
- (#{STOPS})+ # stops
24
- \s* # trailing whitespace is ok
25
- /x
26
-
27
- RADIAL_GRADIENT = /
28
- \( \s* # coordinate 1
29
- (\d+\.?\d*) \s* # x1 number
30
- ,\s* # whitespace after comma is ok
31
- (\d+\.?\d*) \s* # y1 number
32
- ,\s* # whitespace after comma is ok
33
- (\d+\.?\d*) \s* # r1 number
34
- \)
35
- \s* # space between coordinates is ok
36
- \( \s* # coordinate 2
37
- (\d+\.?\d*) \s* # x2 number
38
- ,\s* # whitespace after comma is ok
39
- (\d+\.?\d*) \s* # y2 number
40
- ,\s* # whitespace after comma is ok
41
- (\d+\.?\d*) \s* # r2 number
42
- \)
43
- (#{STOPS})+ # stops
44
- \s* # trailing whitespace is ok
45
- /x
46
- end
1
+ module Squib
2
+ # @api private
3
+ module Graphics
4
+ STOPS = / # used to capture the stops
5
+ \s* # leading whitespace is ok
6
+ (\#?[\w]+) # color
7
+ @ # no spaces here
8
+ (\d+\.?\d*) # offset number
9
+ /x
10
+
11
+ LINEAR_GRADIENT = /
12
+ \( \s* # coordinate 1
13
+ (\d+\.?\d*) \s* # x1 number
14
+ ,\s* # whitespace after comma is ok
15
+ (\d+\.?\d*) \s* # y1 number
16
+ \)
17
+ \s* # space between coordinates is ok
18
+ \( \s* # coordinate 2
19
+ (\d+\.?\d*) \s* # x2 number
20
+ ,\s* # whitespace after comma is ok
21
+ (\d+\.?\d*) \s* # y2 number
22
+ \)
23
+ (#{STOPS})+ # stops
24
+ \s* # trailing whitespace is ok
25
+ /x
26
+
27
+ RADIAL_GRADIENT = /
28
+ \( \s* # coordinate 1
29
+ (\d+\.?\d*) \s* # x1 number
30
+ ,\s* # whitespace after comma is ok
31
+ (\d+\.?\d*) \s* # y1 number
32
+ ,\s* # whitespace after comma is ok
33
+ (\d+\.?\d*) \s* # r1 number
34
+ \)
35
+ \s* # space between coordinates is ok
36
+ \( \s* # coordinate 2
37
+ (\d+\.?\d*) \s* # x2 number
38
+ ,\s* # whitespace after comma is ok
39
+ (\d+\.?\d*) \s* # y2 number
40
+ ,\s* # whitespace after comma is ok
41
+ (\d+\.?\d*) \s* # r2 number
42
+ \)
43
+ (#{STOPS})+ # stops
44
+ \s* # trailing whitespace is ok
45
+ /x
46
+ end
47
47
  end
@@ -1,42 +1,42 @@
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, sheet, hand)
9
- cards = range.collect { |i| @cards[i] }
10
- center_x = width / 2.0
11
- center_y = hand.radius + height
12
- out_size = 3.0 * center_y
13
- angle_delta = (hand.angle_range.last - hand.angle_range.first) / cards.size
14
- cxt = Cairo::Context.new(Cairo::RecordingSurface.new(0, 0, out_size, out_size))
15
- cxt.translate(out_size / 2.0, out_size / 2.0)
16
- cxt.rotate(hand.angle_range.first)
17
- cxt.translate(-width, -width)
18
- cards.each_with_index do |card, i|
19
- cxt.translate(center_x, center_y)
20
- cxt.rotate(angle_delta)
21
- cxt.translate(-center_x, -center_y)
22
- card.use_cairo do |card_cxt|
23
- cxt.rounded_rectangle(sheet.trim, sheet.trim,
24
- width - (2 * sheet.trim), height - (2 * sheet.trim),
25
- sheet.trim_radius, sheet.trim_radius)
26
- cxt.clip
27
- cxt.set_source(card_cxt.target)
28
- cxt.paint
29
- cxt.reset_clip
30
- end
31
- end
32
- x, y, w, h = cxt.target.ink_extents # I love Ruby assignment ;)
33
- png_cxt = Squib::Graphics::CairoContextWrapper.new(Cairo::Context.new(Cairo::ImageSurface.new(w + 2*sheet.margin, h + 2*sheet.margin)))
34
- png_cxt.set_source_squibcolor(sheet.fill_color)
35
- png_cxt.paint
36
- png_cxt.translate(-x + sheet.margin, -y + sheet.margin)
37
- png_cxt.set_source(cxt.target)
38
- png_cxt.paint
39
- png_cxt.target.write_to_png sheet.full_filename
40
- end
41
- end
42
- end
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, sheet, hand)
9
+ cards = range.collect { |i| @cards[i] }
10
+ center_x = width / 2.0
11
+ center_y = hand.radius + height
12
+ out_size = 3.0 * center_y
13
+ angle_delta = (hand.angle_range.last - hand.angle_range.first) / cards.size
14
+ cxt = Cairo::Context.new(Cairo::RecordingSurface.new(0, 0, out_size, out_size))
15
+ cxt.translate(out_size / 2.0, out_size / 2.0)
16
+ cxt.rotate(hand.angle_range.first)
17
+ cxt.translate(-width, -width)
18
+ cards.each_with_index do |card, i|
19
+ cxt.translate(center_x, center_y)
20
+ cxt.rotate(angle_delta)
21
+ cxt.translate(-center_x, -center_y)
22
+ card.use_cairo do |card_cxt|
23
+ cxt.rounded_rectangle(sheet.trim, sheet.trim,
24
+ width - (2 * sheet.trim), height - (2 * sheet.trim),
25
+ sheet.trim_radius, sheet.trim_radius)
26
+ cxt.clip
27
+ cxt.set_source(card_cxt.target)
28
+ cxt.paint
29
+ cxt.reset_clip
30
+ end
31
+ end
32
+ x, y, w, h = cxt.target.ink_extents # I love Ruby assignment ;)
33
+ png_cxt = Squib::Graphics::CairoContextWrapper.new(Cairo::Context.new(Cairo::ImageSurface.new(w + 2*sheet.margin, h + 2*sheet.margin)))
34
+ png_cxt.set_source_squibcolor(sheet.fill_color)
35
+ png_cxt.paint
36
+ png_cxt.translate(-x + sheet.margin, -y + sheet.margin)
37
+ png_cxt.set_source(cxt.target)
38
+ png_cxt.paint
39
+ png_cxt.target.write_to_png sheet.full_filename
40
+ end
41
+ end
42
+ end
@@ -1,76 +1,103 @@
1
- module Squib
2
-
3
- # Cache all pngs we've already loaded
4
- #
5
- # :nodoc:
6
- # @api private
7
- def cache_load_image(file)
8
- @img_cache ||= {}
9
- @img_cache[file] || @img_cache[file] = Cairo::ImageSurface.from_png(file)
10
- end
11
- module_function :cache_load_image
12
-
13
- class Card
14
-
15
- # :nodoc:
16
- # @api private
17
- def png(file, box, paint, trans)
18
- Squib.logger.debug {"RENDERING PNG: \n file: #{file}\n box: #{box}\n paint: #{paint}\n trans: #{trans}"}
19
- return if file.nil? or file.eql? ''
20
- png = Squib.cache_load_image(file)
21
- use_cairo do |cc|
22
- cc.translate(box.x, box.y)
23
- if box.width != :native || box.height != :native
24
- box.width = png.width.to_f if box.width == :native
25
- box.height = png.height.to_f if box.height == :native
26
- box.width = png.width.to_f * box.height.to_f / png.height.to_f if box.width == :scale
27
- box.height = png.height.to_f * box.width.to_f / png.width.to_f if box.height == :scale
28
- Squib.logger.warn "PNG scaling results in aliasing."
29
- cc.scale(box.width.to_f / png.width.to_f, box.height.to_f / png.height.to_f)
30
- end
31
- cc.rotate(trans.angle)
32
- cc.translate(-box.x, -box.y)
33
- cc.set_source(png, box.x, box.y)
34
- cc.operator = paint.blend unless paint.blend == :none
35
- if paint.mask.empty?
36
- cc.paint(paint.alpha)
37
- else
38
- cc.set_source_squibcolor(paint.mask)
39
- cc.mask(png, box.x, box.y)
40
- end
41
- end
42
- end
43
-
44
- # :nodoc:
45
- # @api private
46
- def svg(file, svg_args, box, paint, trans)
47
- Squib.logger.debug {"Rendering: #{file}, id: #{id} @#{x},#{y} #{width}x#{height}, alpha: #{alpha}, blend: #{blend}, angle: #{angle}, mask: #{mask}"}
48
- Squib.logger.warn 'Both an SVG file and SVG data were specified' unless file.to_s.empty? || svg_args.data.to_s.empty?
49
- return if (file.nil? or file.eql? '') and svg_args.data.nil? # nothing specified TODO Move this out to arg validator
50
- svg_args.data = File.read(file) if svg_args.data.to_s.empty?
51
- svg = RSVG::Handle.new_from_data(svg_args.data)
52
- box.width = svg.width if box.width == :native
53
- box.height = svg.height if box.height == :native
54
- box.width = svg.width.to_f * box.height.to_f / svg.height.to_f if box.width == :scale
55
- box.height = svg.height.to_f * box.width.to_f / svg.width.to_f if box.height == :scale
56
- scale_width = box.width.to_f / svg.width.to_f
57
- scale_height = box.height.to_f / svg.height.to_f
58
- use_cairo do |cc|
59
- cc.translate(box.x, box.y)
60
- cc.rotate(trans.angle)
61
- cc.scale(scale_width, scale_height)
62
- cc.operator = paint.blend unless paint.blend == :none
63
- if paint.mask.to_s.empty?
64
- cc.render_rsvg_handle(svg, svg_args.id)
65
- else
66
- tmp = Cairo::ImageSurface.new(box.width / scale_width, box.height / scale_height)
67
- tmp_cc = Cairo::Context.new(tmp)
68
- tmp_cc.render_rsvg_handle(svg, svg_args.id)
69
- cc.set_source_squibcolor(paint.mask)
70
- cc.mask(tmp, 0, 0)
71
- end
72
- end
73
- end
74
-
75
- end
76
- end
1
+ module Squib
2
+
3
+ # Cache all pngs we've already loaded
4
+ #
5
+ # :nodoc:
6
+ # @api private
7
+ def cache_load_image(file)
8
+ @img_cache ||= {}
9
+ @img_cache[file] || @img_cache[file] = Cairo::ImageSurface.from_png(file)
10
+ end
11
+ module_function :cache_load_image
12
+
13
+ class Card
14
+
15
+ # :nodoc:
16
+ # @api private
17
+ def png(file, box, paint, trans)
18
+ Squib.logger.debug {"RENDERING PNG: \n file: #{file}\n box: #{box}\n paint: #{paint}\n trans: #{trans}"}
19
+ return if file.nil? or file.eql? ''
20
+ png = Squib.cache_load_image(file)
21
+ use_cairo do |cc|
22
+ cc.translate(box.x, box.y)
23
+ box.width = png.width.to_f if box.width == :native
24
+ box.height = png.height.to_f if box.height == :native
25
+ box.width = png.width.to_f * box.height.to_f / png.height.to_f if box.width == :scale
26
+ box.height = png.height.to_f * box.width.to_f / png.width.to_f if box.height == :scale
27
+
28
+ scale_width = box.width.to_f / png.width.to_f
29
+ scale_height = box.height.to_f / png.height.to_f
30
+ warn_png_scale(file, scale_width, scale_height)
31
+ cc.scale(scale_width, scale_height)
32
+
33
+ cc.rotate(trans.angle)
34
+ cc.flip(trans.flip_vertical, trans.flip_horizontal, box.width / 2, box.height / 2)
35
+ cc.translate(-box.x, -box.y)
36
+
37
+ trans.crop_width = png.width.to_f if trans.crop_width == :native
38
+ trans.crop_height = png.height.to_f if trans.crop_height == :native
39
+ cc.rounded_rectangle(box.x, box.y, trans.crop_width, trans.crop_height, trans.crop_corner_x_radius, trans.crop_corner_y_radius)
40
+ cc.clip
41
+ cc.translate(-trans.crop_x, -trans.crop_y)
42
+
43
+
44
+ cc.set_source(png, box.x, box.y)
45
+ cc.operator = paint.blend unless paint.blend == :none
46
+ if paint.mask.empty?
47
+ cc.paint(paint.alpha)
48
+ else
49
+ cc.set_source_squibcolor(paint.mask)
50
+ cc.mask(png, box.x, box.y)
51
+ end
52
+ end
53
+ end
54
+
55
+ # :nodoc:
56
+ # @api private
57
+ def warn_png_scale(file, scale_width, scale_height)
58
+ if @deck.conf.warn_png_scale? && (scale_width > 1.0 || scale_height > 1.0)
59
+ Squib.logger.warn "PNG is being upscaled - antialiasing could result: #{file}"
60
+ end
61
+ end
62
+
63
+ # :nodoc:
64
+ # @api private
65
+ def svg(file, svg_args, box, paint, trans)
66
+ Squib.logger.debug {"Rendering: #{file}, id: #{id} @#{x},#{y} #{width}x#{height}, alpha: #{alpha}, blend: #{blend}, angle: #{angle}, mask: #{mask}"}
67
+ Squib.logger.warn 'Both an SVG file and SVG data were specified' unless file.to_s.empty? || svg_args.data.to_s.empty?
68
+ return if (file.nil? or file.eql? '') and svg_args.data.nil? # nothing specified TODO Move this out to arg validator
69
+ svg_args.data = File.read(file) if svg_args.data.to_s.empty?
70
+ svg = RSVG::Handle.new_from_data(svg_args.data)
71
+ box.width = svg.width if box.width == :native
72
+ box.height = svg.height if box.height == :native
73
+ box.width = svg.width.to_f * box.height.to_f / svg.height.to_f if box.width == :scale
74
+ box.height = svg.height.to_f * box.width.to_f / svg.width.to_f if box.height == :scale
75
+ scale_width = box.width.to_f / svg.width.to_f
76
+ scale_height = box.height.to_f / svg.height.to_f
77
+ use_cairo do |cc|
78
+ cc.translate(box.x, box.y)
79
+ cc.flip(trans.flip_vertical, trans.flip_horizontal, box.width / 2, box.height / 2)
80
+ cc.rotate(trans.angle)
81
+ cc.scale(scale_width, scale_height)
82
+
83
+ trans.crop_width = box.width if trans.crop_width == :native
84
+ trans.crop_height = box.height if trans.crop_height == :native
85
+ cc.rounded_rectangle(0, 0, trans.crop_width / scale_width, trans.crop_height / scale_height, trans.crop_corner_x_radius, trans.crop_corner_y_radius)
86
+ cc.clip
87
+ cc.translate(-trans.crop_x, -trans.crop_y)
88
+
89
+ cc.operator = paint.blend unless paint.blend == :none
90
+ if paint.mask.to_s.empty?
91
+ cc.render_rsvg_handle(svg, svg_args.id)
92
+ else
93
+ tmp = Cairo::ImageSurface.new(box.width / scale_width, box.height / scale_height)
94
+ tmp_cc = Cairo::Context.new(tmp)
95
+ tmp_cc.render_rsvg_handle(svg, svg_args.id)
96
+ cc.set_source_squibcolor(paint.mask)
97
+ cc.mask(tmp, 0, 0)
98
+ end
99
+ end
100
+ end
101
+
102
+ end
103
+ end