dragonfly 1.1.4 → 1.4.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 +5 -5
- data/.travis.yml +14 -6
- data/History.md +336 -309
- data/README.md +1 -1
- data/dev/rails_template.rb +35 -33
- data/dragonfly.gemspec +10 -16
- data/lib/dragonfly.rb +3 -1
- data/lib/dragonfly/content.rb +21 -22
- data/lib/dragonfly/image_magick/commands.rb +35 -0
- data/lib/dragonfly/image_magick/generators/plain.rb +13 -7
- data/lib/dragonfly/image_magick/generators/plasma.rb +10 -6
- data/lib/dragonfly/image_magick/generators/text.rb +67 -58
- data/lib/dragonfly/image_magick/plugin.rb +26 -25
- data/lib/dragonfly/image_magick/processors/encode.rb +16 -5
- data/lib/dragonfly/image_magick/processors/thumb.rb +37 -31
- data/lib/dragonfly/job/fetch_url.rb +1 -1
- data/lib/dragonfly/model/class_methods.rb +6 -1
- data/lib/dragonfly/param_validators.rb +37 -0
- data/lib/dragonfly/response.rb +2 -2
- data/lib/dragonfly/shell.rb +19 -13
- data/lib/dragonfly/utils.rb +1 -1
- data/lib/dragonfly/version.rb +1 -1
- data/samples/white pixel.png b/data/samples/mevs' white → pixel.png +0 -0
- data/spec/dragonfly/content_spec.rb +3 -3
- data/spec/dragonfly/cookie_monster_spec.rb +2 -2
- data/spec/dragonfly/image_magick/commands_spec.rb +98 -0
- data/spec/dragonfly/image_magick/generators/plain_spec.rb +39 -13
- data/spec/dragonfly/image_magick/generators/plasma_spec.rb +28 -9
- data/spec/dragonfly/image_magick/generators/text_spec.rb +51 -20
- data/spec/dragonfly/image_magick/plugin_spec.rb +45 -28
- data/spec/dragonfly/image_magick/processors/encode_spec.rb +30 -0
- data/spec/dragonfly/image_magick/processors/thumb_spec.rb +46 -45
- data/spec/dragonfly/model/active_record_spec.rb +62 -0
- data/spec/dragonfly/param_validators_spec.rb +89 -0
- data/spec/dragonfly/shell_spec.rb +12 -10
- data/spec/dragonfly_spec.rb +37 -13
- data/spec/functional/shell_commands_spec.rb +6 -9
- data/spec/spec_helper.rb +12 -14
- metadata +45 -14
- data/lib/dragonfly/image_magick/generators/convert.rb +0 -19
- data/lib/dragonfly/image_magick/processors/convert.rb +0 -33
- data/spec/dragonfly/image_magick/generators/convert_spec.rb +0 -19
- data/spec/dragonfly/image_magick/processors/convert_spec.rb +0 -88
data/README.md
CHANGED
data/dev/rails_template.rb
CHANGED
@@ -1,40 +1,42 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
generate "
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
app.
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
after_bundle do
|
2
|
+
gem 'dragonfly', :path => File.expand_path('../..', __FILE__)
|
3
|
+
generate "dragonfly"
|
4
|
+
generate "scaffold", "photo image_uid:string image_name:string"
|
5
|
+
rake "db:migrate"
|
6
|
+
route %(
|
7
|
+
get "text/:text" => Dragonfly.app.endpoint { |params, app|
|
8
|
+
app.generate(:text, params[:text])
|
9
|
+
}
|
10
|
+
)
|
11
|
+
route "root :to => 'photos#index'"
|
12
|
+
run "rm -rf public/index.html"
|
12
13
|
|
13
|
-
possible_base_classes = ['ActiveRecord::Base', 'ApplicationRecord']
|
14
|
-
possible_base_classes.each do |base_class|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
possible_base_classes = ['ActiveRecord::Base', 'ApplicationRecord']
|
15
|
+
possible_base_classes.each do |base_class|
|
16
|
+
inject_into_file 'app/models/photo.rb', :after => "class Photo < #{base_class}\n" do
|
17
|
+
%(
|
18
|
+
attr_accessible :image rescue nil
|
19
|
+
dragonfly_accessor :image
|
20
|
+
)
|
21
|
+
end
|
20
22
|
end
|
21
|
-
end
|
22
23
|
|
23
|
-
gsub_file 'app/views/photos/_form.html.erb', /^.*:image_.*$/, ''
|
24
|
+
gsub_file 'app/views/photos/_form.html.erb', /^.*:image_.*$/, ''
|
24
25
|
|
25
|
-
inject_into_file 'app/views/photos/_form.html.erb', :before => %(<div class="actions">\n) do
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
inject_into_file 'app/views/photos/_form.html.erb', :before => %(<div class="actions">\n) do
|
27
|
+
%(
|
28
|
+
<div class="field">
|
29
|
+
<%= form.label :image %><br>
|
30
|
+
<%= form.file_field :image %>
|
31
|
+
</div>
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
33
|
+
<%= image_tag @photo.image.thumb('100x100').url if @photo.image_stored? %>
|
34
|
+
)
|
35
|
+
end
|
35
36
|
|
36
|
-
gsub_file "app/controllers/photos_controller.rb", "permit(", "permit(:image, "
|
37
|
+
gsub_file "app/controllers/photos_controller.rb", "permit(", "permit(:image, "
|
37
38
|
|
38
|
-
append_file 'app/views/photos/show.html.erb', %(
|
39
|
-
|
40
|
-
)
|
39
|
+
append_file 'app/views/photos/show.html.erb', %(
|
40
|
+
<%= image_tag @photo.image.thumb('300x300').url if @photo.image_stored? %>
|
41
|
+
)
|
42
|
+
end
|
data/dragonfly.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require "dragonfly/version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "dragonfly"
|
@@ -13,33 +13,27 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = "http://github.com/markevans/dragonfly"
|
14
14
|
spec.license = "MIT"
|
15
15
|
spec.files = `git ls-files`.split($/)
|
16
|
-
spec.executables
|
17
|
-
spec.test_files
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
spec.extra_rdoc_files = [
|
20
20
|
"LICENSE",
|
21
|
-
"README.md"
|
21
|
+
"README.md",
|
22
22
|
]
|
23
23
|
|
24
|
-
# Rack 2.0 only works with ruby >= 2.2.2
|
25
|
-
if RUBY_VERSION < "2.2.2"
|
26
|
-
rack_version = "~> 1.3"
|
27
|
-
activemodel_version = "~> 4.2"
|
28
|
-
else
|
29
|
-
rack_version = ">= 1.3"
|
30
|
-
activemodel_version = nil
|
31
|
-
end
|
32
|
-
|
33
24
|
# Runtime dependencies
|
34
|
-
spec.add_runtime_dependency("rack",
|
25
|
+
spec.add_runtime_dependency("rack", ">= 1.3")
|
35
26
|
spec.add_runtime_dependency("multi_json", "~> 1.0")
|
36
27
|
spec.add_runtime_dependency("addressable", "~> 2.3")
|
37
28
|
|
38
29
|
# Development dependencies
|
39
30
|
spec.add_development_dependency("rspec", "~> 2.5")
|
40
31
|
spec.add_development_dependency("webmock")
|
41
|
-
spec.add_development_dependency("activemodel"
|
32
|
+
spec.add_development_dependency("activemodel")
|
42
33
|
if RUBY_PLATFORM == "java"
|
43
34
|
spec.add_development_dependency("jruby-openssl")
|
35
|
+
else
|
36
|
+
spec.add_development_dependency("activerecord")
|
37
|
+
spec.add_development_dependency("sqlite3")
|
44
38
|
end
|
45
39
|
end
|
data/lib/dragonfly.rb
CHANGED
@@ -33,12 +33,14 @@ module Dragonfly
|
|
33
33
|
|
34
34
|
# Logging
|
35
35
|
def logger
|
36
|
-
@logger
|
36
|
+
@logger = Logger.new('dragonfly.log') unless instance_variable_defined?(:@logger)
|
37
|
+
@logger
|
37
38
|
end
|
38
39
|
attr_writer :logger
|
39
40
|
|
40
41
|
[:debug, :warn, :info].each do |method|
|
41
42
|
define_method method do |message|
|
43
|
+
return unless logger
|
42
44
|
logger.send(method, "DRAGONFLY: #{message}")
|
43
45
|
end
|
44
46
|
end
|
data/lib/dragonfly/content.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
require "base64"
|
2
|
+
require "forwardable"
|
3
|
+
require "dragonfly/has_filename"
|
4
|
+
require "dragonfly/temp_object"
|
5
|
+
require "dragonfly/utils"
|
6
6
|
|
7
7
|
module Dragonfly
|
8
8
|
|
@@ -16,11 +16,10 @@ module Dragonfly
|
|
16
16
|
# It is acted upon in generator, processor, analyser and datastore methods and provides a standard interface for updating content,
|
17
17
|
# no matter how that content first got there (whether in the form of a String/Pathname/File/etc.)
|
18
18
|
class Content
|
19
|
-
|
20
19
|
include HasFilename
|
21
20
|
extend Forwardable
|
22
21
|
|
23
|
-
def initialize(app, obj="", meta=nil)
|
22
|
+
def initialize(app, obj = "", meta = nil)
|
24
23
|
@app = app
|
25
24
|
@meta = {}
|
26
25
|
@previous_temp_objects = []
|
@@ -79,7 +78,7 @@ module Dragonfly
|
|
79
78
|
# @example "image/jpeg"
|
80
79
|
# @return [String]
|
81
80
|
def mime_type
|
82
|
-
meta[
|
81
|
+
meta["mime_type"] || app.mime_type_for(ext)
|
83
82
|
end
|
84
83
|
|
85
84
|
# Set the content using a pre-registered generator
|
@@ -93,7 +92,7 @@ module Dragonfly
|
|
93
92
|
|
94
93
|
# Update the content using a pre-registered processor
|
95
94
|
# @example
|
96
|
-
# content.process!(:
|
95
|
+
# content.process!(:thumb, "300x300")
|
97
96
|
# @return [Content] self
|
98
97
|
def process!(name, *args)
|
99
98
|
app.get_processor(name).call(self, *args)
|
@@ -111,10 +110,10 @@ module Dragonfly
|
|
111
110
|
# @param obj [String, Pathname, Tempfile, File, Content, TempObject] can be any of these types
|
112
111
|
# @param meta [Hash] - should be json-like, i.e. contain no types other than String, Number, Boolean
|
113
112
|
# @return [Content] self
|
114
|
-
def update(obj, meta=nil)
|
113
|
+
def update(obj, meta = nil)
|
115
114
|
meta ||= {}
|
116
|
-
self.temp_object = TempObject.new(obj, meta[
|
117
|
-
self.meta[
|
115
|
+
self.temp_object = TempObject.new(obj, meta["name"])
|
116
|
+
self.meta["name"] ||= temp_object.name if temp_object.name
|
118
117
|
clear_analyser_cache
|
119
118
|
add_meta(obj.meta) if obj.respond_to?(:meta)
|
120
119
|
add_meta(meta)
|
@@ -135,9 +134,9 @@ module Dragonfly
|
|
135
134
|
# "file --mime-type #{path}"
|
136
135
|
# end
|
137
136
|
# # ===> "beach.jpg: image/jpeg"
|
138
|
-
def shell_eval(opts={})
|
137
|
+
def shell_eval(opts = {})
|
139
138
|
should_escape = opts[:escape] != false
|
140
|
-
command = yield(should_escape ? shell.
|
139
|
+
command = yield(should_escape ? shell.escape(path) : path)
|
141
140
|
run command, :escape => should_escape
|
142
141
|
end
|
143
142
|
|
@@ -148,11 +147,11 @@ module Dragonfly
|
|
148
147
|
# "/usr/local/bin/generate_text gumfry -o #{path}"
|
149
148
|
# end
|
150
149
|
# @return [Content] self
|
151
|
-
def shell_generate(opts={})
|
150
|
+
def shell_generate(opts = {})
|
152
151
|
ext = opts[:ext] || self.ext
|
153
152
|
should_escape = opts[:escape] != false
|
154
153
|
tempfile = Utils.new_tempfile(ext)
|
155
|
-
new_path = should_escape ? shell.
|
154
|
+
new_path = should_escape ? shell.escape(tempfile.path) : tempfile.path
|
156
155
|
command = yield(new_path)
|
157
156
|
run(command, :escape => should_escape)
|
158
157
|
update(tempfile)
|
@@ -165,18 +164,18 @@ module Dragonfly
|
|
165
164
|
# "convert -resize 20x10 #{old_path} #{new_path}"
|
166
165
|
# end
|
167
166
|
# @return [Content] self
|
168
|
-
def shell_update(opts={})
|
167
|
+
def shell_update(opts = {})
|
169
168
|
ext = opts[:ext] || self.ext
|
170
169
|
should_escape = opts[:escape] != false
|
171
170
|
tempfile = Utils.new_tempfile(ext)
|
172
|
-
old_path = should_escape ? shell.
|
173
|
-
new_path = should_escape ? shell.
|
171
|
+
old_path = should_escape ? shell.escape(path) : path
|
172
|
+
new_path = should_escape ? shell.escape(tempfile.path) : tempfile.path
|
174
173
|
command = yield(old_path, new_path)
|
175
174
|
run(command, :escape => should_escape)
|
176
175
|
update(tempfile)
|
177
176
|
end
|
178
177
|
|
179
|
-
def store(opts={})
|
178
|
+
def store(opts = {})
|
180
179
|
datastore.write(self, opts)
|
181
180
|
end
|
182
181
|
|
@@ -188,7 +187,7 @@ module Dragonfly
|
|
188
187
|
end
|
189
188
|
|
190
189
|
def close
|
191
|
-
previous_temp_objects.each{|temp_object| temp_object.close }
|
190
|
+
previous_temp_objects.each { |temp_object| temp_object.close }
|
192
191
|
temp_object.close
|
193
192
|
end
|
194
193
|
|
@@ -199,6 +198,7 @@ module Dragonfly
|
|
199
198
|
private
|
200
199
|
|
201
200
|
attr_reader :previous_temp_objects
|
201
|
+
|
202
202
|
def temp_object=(temp_object)
|
203
203
|
previous_temp_objects.push(@temp_object) if @temp_object
|
204
204
|
@temp_object = temp_object
|
@@ -215,6 +215,5 @@ module Dragonfly
|
|
215
215
|
def run(command, opts)
|
216
216
|
shell.run(command, opts)
|
217
217
|
end
|
218
|
-
|
219
218
|
end
|
220
219
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Dragonfly
|
2
|
+
module ImageMagick
|
3
|
+
module Commands
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def convert(content, args = "", opts = {})
|
7
|
+
convert_command = content.env[:convert_command] || "convert"
|
8
|
+
format = opts["format"]
|
9
|
+
|
10
|
+
input_args = opts["input_args"] if opts["input_args"]
|
11
|
+
delegate_string = "#{opts["delegate"]}:" if opts["delegate"]
|
12
|
+
frame_string = "[#{opts["frame"]}]" if opts["frame"]
|
13
|
+
|
14
|
+
content.shell_update :ext => format do |old_path, new_path|
|
15
|
+
"#{convert_command} #{input_args} #{delegate_string}#{old_path}#{frame_string} #{args} #{new_path}"
|
16
|
+
end
|
17
|
+
|
18
|
+
if format
|
19
|
+
content.meta["format"] = format.to_s
|
20
|
+
content.ext = format
|
21
|
+
content.meta["mime_type"] = nil # don't need it as we have ext now
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def generate(content, args, format)
|
26
|
+
format = format.to_s
|
27
|
+
convert_command = content.env[:convert_command] || "convert"
|
28
|
+
content.shell_generate :ext => format do |path|
|
29
|
+
"#{convert_command} #{args} #{path}"
|
30
|
+
end
|
31
|
+
content.add_meta("format" => format)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,25 +1,31 @@
|
|
1
|
+
require "dragonfly/image_magick/commands"
|
2
|
+
require "dragonfly/param_validators"
|
3
|
+
|
1
4
|
module Dragonfly
|
2
5
|
module ImageMagick
|
3
6
|
module Generators
|
4
7
|
class Plain
|
8
|
+
include ParamValidators
|
5
9
|
|
6
|
-
def call(content, width, height, opts={})
|
10
|
+
def call(content, width, height, opts = {})
|
11
|
+
validate_all!([width, height], &is_number)
|
12
|
+
validate_all_keys!(opts, %w(colour color format), &is_word)
|
7
13
|
format = extract_format(opts)
|
8
|
-
|
9
|
-
|
10
|
-
|
14
|
+
|
15
|
+
colour = opts["colour"] || opts["color"] || "white"
|
16
|
+
Commands.generate(content, "-size #{width}x#{height} xc:#{colour}", format)
|
17
|
+
content.add_meta("format" => format, "name" => "plain.#{format}")
|
11
18
|
end
|
12
19
|
|
13
|
-
def update_url(url_attributes, width, height, opts={})
|
20
|
+
def update_url(url_attributes, width, height, opts = {})
|
14
21
|
url_attributes.name = "plain.#{extract_format(opts)}"
|
15
22
|
end
|
16
23
|
|
17
24
|
private
|
18
25
|
|
19
26
|
def extract_format(opts)
|
20
|
-
opts[
|
27
|
+
opts["format"] || "png"
|
21
28
|
end
|
22
|
-
|
23
29
|
end
|
24
30
|
end
|
25
31
|
end
|
@@ -1,24 +1,28 @@
|
|
1
|
+
require "dragonfly/image_magick/commands"
|
2
|
+
|
1
3
|
module Dragonfly
|
2
4
|
module ImageMagick
|
3
5
|
module Generators
|
4
6
|
class Plasma
|
7
|
+
include ParamValidators
|
5
8
|
|
6
|
-
def call(content, width, height, opts={})
|
9
|
+
def call(content, width, height, opts = {})
|
10
|
+
validate_all!([width, height], &is_number)
|
11
|
+
validate!(opts["format"], &is_word)
|
7
12
|
format = extract_format(opts)
|
8
|
-
|
9
|
-
content.add_meta(
|
13
|
+
Commands.generate(content, "-size #{width}x#{height} plasma:fractal", format)
|
14
|
+
content.add_meta("format" => format, "name" => "plasma.#{format}")
|
10
15
|
end
|
11
16
|
|
12
|
-
def update_url(url_attributes, width, height, opts={})
|
17
|
+
def update_url(url_attributes, width, height, opts = {})
|
13
18
|
url_attributes.name = "plasma.#{extract_format(opts)}"
|
14
19
|
end
|
15
20
|
|
16
21
|
private
|
17
22
|
|
18
23
|
def extract_format(opts)
|
19
|
-
opts[
|
24
|
+
opts["format"] || "png"
|
20
25
|
end
|
21
|
-
|
22
26
|
end
|
23
27
|
end
|
24
28
|
end
|
@@ -1,100 +1,111 @@
|
|
1
|
-
require
|
1
|
+
require "dragonfly/hash_with_css_style_keys"
|
2
|
+
require "dragonfly/image_magick/commands"
|
3
|
+
require "dragonfly/param_validators"
|
2
4
|
|
3
5
|
module Dragonfly
|
4
6
|
module ImageMagick
|
5
7
|
module Generators
|
6
8
|
class Text
|
9
|
+
include ParamValidators
|
7
10
|
|
8
11
|
FONT_STYLES = {
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
+
"normal" => "normal",
|
13
|
+
"italic" => "italic",
|
14
|
+
"oblique" => "oblique",
|
12
15
|
}
|
13
16
|
|
14
17
|
FONT_STRETCHES = {
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
"normal" => "normal",
|
19
|
+
"semi-condensed" => "semi-condensed",
|
20
|
+
"condensed" => "condensed",
|
21
|
+
"extra-condensed" => "extra-condensed",
|
22
|
+
"ultra-condensed" => "ultra-condensed",
|
23
|
+
"semi-expanded" => "semi-expanded",
|
24
|
+
"expanded" => "expanded",
|
25
|
+
"extra-expanded" => "extra-expanded",
|
26
|
+
"ultra-expanded" => "ultra-expanded",
|
24
27
|
}
|
25
28
|
|
26
29
|
FONT_WEIGHTS = {
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
30
|
+
"normal" => "normal",
|
31
|
+
"bold" => "bold",
|
32
|
+
"bolder" => "bolder",
|
33
|
+
"lighter" => "lighter",
|
34
|
+
"100" => 100,
|
35
|
+
"200" => 200,
|
36
|
+
"300" => 300,
|
37
|
+
"400" => 400,
|
38
|
+
"500" => 500,
|
39
|
+
"600" => 600,
|
40
|
+
"700" => 700,
|
41
|
+
"800" => 800,
|
42
|
+
"900" => 900,
|
40
43
|
}
|
41
44
|
|
42
|
-
|
45
|
+
IS_COLOUR = ->(param) {
|
46
|
+
/\A(#\w+|rgba?\([\d\.,]+\)|\w+)\z/ === param
|
47
|
+
}
|
48
|
+
|
49
|
+
def update_url(url_attributes, string, opts = {})
|
43
50
|
url_attributes.name = "text.#{extract_format(opts)}"
|
44
51
|
end
|
45
52
|
|
46
|
-
def call(content, string, opts={})
|
53
|
+
def call(content, string, opts = {})
|
54
|
+
validate_all_keys!(opts, %w(font font_family), &is_words)
|
55
|
+
validate_all_keys!(opts, %w(color background_color stroke_color), &IS_COLOUR)
|
56
|
+
validate!(opts["format"], &is_word)
|
57
|
+
|
47
58
|
opts = HashWithCssStyleKeys[opts]
|
48
59
|
args = []
|
49
60
|
format = extract_format(opts)
|
50
|
-
background = opts[
|
51
|
-
font_size = (opts[
|
61
|
+
background = opts["background_color"] || "none"
|
62
|
+
font_size = (opts["font_size"] || 12).to_i
|
63
|
+
font_family = opts["font_family"] || opts["font"]
|
52
64
|
escaped_string = "\"#{string.gsub(/"/, '\"')}\""
|
53
65
|
|
54
66
|
# Settings
|
55
67
|
args.push("-gravity NorthWest")
|
56
68
|
args.push("-antialias")
|
57
69
|
args.push("-pointsize #{font_size}")
|
58
|
-
args.push("-
|
59
|
-
args.push("-
|
60
|
-
args.push("-
|
61
|
-
args.push("-
|
62
|
-
args.push("-
|
63
|
-
args.push("-
|
64
|
-
args.push("-weight #{FONT_WEIGHTS[opts['font_weight']]}") if opts['font_weight']
|
70
|
+
args.push("-family '#{font_family}'") if font_family
|
71
|
+
args.push("-fill #{opts["color"]}") if opts["color"]
|
72
|
+
args.push("-stroke #{opts["stroke_color"]}") if opts["stroke_color"]
|
73
|
+
args.push("-style #{FONT_STYLES[opts["font_style"]]}") if opts["font_style"]
|
74
|
+
args.push("-stretch #{FONT_STRETCHES[opts["font_stretch"]]}") if opts["font_stretch"]
|
75
|
+
args.push("-weight #{FONT_WEIGHTS[opts["font_weight"]]}") if opts["font_weight"]
|
65
76
|
args.push("-background #{background}")
|
66
77
|
args.push("label:#{escaped_string}")
|
67
78
|
|
68
79
|
# Padding
|
69
|
-
pt, pr, pb, pl = parse_padding_string(opts[
|
70
|
-
padding_top
|
71
|
-
padding_right
|
72
|
-
padding_bottom = (opts[
|
73
|
-
padding_left
|
80
|
+
pt, pr, pb, pl = parse_padding_string(opts["padding"]) if opts["padding"]
|
81
|
+
padding_top = (opts["padding_top"] || pt).to_i
|
82
|
+
padding_right = (opts["padding_right"] || pr).to_i
|
83
|
+
padding_bottom = (opts["padding_bottom"] || pb).to_i
|
84
|
+
padding_left = (opts["padding_left"] || pl).to_i
|
74
85
|
|
75
|
-
|
86
|
+
Commands.generate(content, args.join(" "), format)
|
76
87
|
|
77
88
|
if (padding_top || padding_right || padding_bottom || padding_left)
|
78
89
|
dimensions = content.analyse(:image_properties)
|
79
|
-
text_width
|
80
|
-
text_height = dimensions[
|
81
|
-
width
|
82
|
-
height = padding_top
|
90
|
+
text_width = dimensions["width"]
|
91
|
+
text_height = dimensions["height"]
|
92
|
+
width = padding_left + text_width + padding_right
|
93
|
+
height = padding_top + text_height + padding_bottom
|
83
94
|
|
84
95
|
args = args.slice(0, args.length - 2)
|
85
96
|
args.push("-size #{width}x#{height}")
|
86
97
|
args.push("xc:#{background}")
|
87
98
|
args.push("-annotate 0x0+#{padding_left}+#{padding_top} #{escaped_string}")
|
88
|
-
|
99
|
+
Commands.generate(content, args.join(" "), format)
|
89
100
|
end
|
90
101
|
|
91
|
-
content.add_meta(
|
102
|
+
content.add_meta("format" => format, "name" => "text.#{format}")
|
92
103
|
end
|
93
104
|
|
94
105
|
private
|
95
106
|
|
96
107
|
def extract_format(opts)
|
97
|
-
opts[
|
108
|
+
opts["format"] || "png"
|
98
109
|
end
|
99
110
|
|
100
111
|
# Use css-style padding declaration, i.e.
|
@@ -103,25 +114,23 @@ module Dragonfly
|
|
103
114
|
# 10 5 10 (top, left/right, bottom)
|
104
115
|
# 10 5 10 5 (top, right, bottom, left)
|
105
116
|
def parse_padding_string(str)
|
106
|
-
padding_parts = str.gsub(
|
117
|
+
padding_parts = str.gsub("px", "").split(/\s+/).map { |px| px.to_i }
|
107
118
|
case padding_parts.size
|
108
119
|
when 1
|
109
120
|
p = padding_parts.first
|
110
|
-
[p,p,p,p]
|
121
|
+
[p, p, p, p]
|
111
122
|
when 2
|
112
|
-
p,q = padding_parts
|
113
|
-
[p,q,p,q]
|
123
|
+
p, q = padding_parts
|
124
|
+
[p, q, p, q]
|
114
125
|
when 3
|
115
|
-
p,q,r = padding_parts
|
116
|
-
[p,q,r,q]
|
126
|
+
p, q, r = padding_parts
|
127
|
+
[p, q, r, q]
|
117
128
|
when 4
|
118
129
|
padding_parts
|
119
130
|
else raise ArgumentError, "Couldn't parse padding string '#{str}' - should be a css-style string"
|
120
131
|
end
|
121
132
|
end
|
122
133
|
end
|
123
|
-
|
124
134
|
end
|
125
135
|
end
|
126
136
|
end
|
127
|
-
|