dragonfly 0.5.7 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of dragonfly might be problematic. Click here for more details.

Files changed (77) hide show
  1. data/.gitignore +1 -0
  2. data/.yardopts +1 -0
  3. data/History.md +109 -0
  4. data/VERSION +1 -1
  5. data/config.rb +1 -1
  6. data/dragonfly.gemspec +19 -16
  7. data/extra_docs/ActiveRecord.md +8 -7
  8. data/extra_docs/Analysers.md +1 -1
  9. data/extra_docs/Encoding.md +1 -1
  10. data/extra_docs/ExampleUseCases.md +66 -73
  11. data/extra_docs/GettingStarted.md +1 -1
  12. data/extra_docs/Processing.md +1 -1
  13. data/extra_docs/Shortcuts.md +2 -2
  14. data/extra_docs/UsingWithRails.md +25 -37
  15. data/features/rails_2.3.5.feature +1 -8
  16. data/features/rails_3.0.0.beta3.feature +7 -0
  17. data/features/steps/rails_steps.rb +1 -11
  18. data/features/support/env.rb +1 -1
  19. data/fixtures/files/app/views/albums/show.html.erb +1 -0
  20. data/fixtures/files/config/initializers/{aaa_dragonfly_load_path.rb → dragonfly.rb} +1 -0
  21. data/fixtures/rails_2.3.5/template.rb +4 -6
  22. data/fixtures/rails_3.0.0.beta3/template.rb +16 -0
  23. data/lib/dragonfly.rb +23 -1
  24. data/lib/dragonfly/active_record_extensions/attachment.rb +1 -1
  25. data/lib/dragonfly/analyser_list.rb +4 -0
  26. data/lib/dragonfly/analysis/base.rb +1 -0
  27. data/lib/dragonfly/analysis/r_magick_analyser.rb +7 -0
  28. data/lib/dragonfly/app.rb +3 -11
  29. data/lib/dragonfly/belongs_to_app.rb +24 -0
  30. data/lib/dragonfly/config/heroku_rails_images.rb +23 -0
  31. data/lib/dragonfly/config/r_magick_images.rb +69 -0
  32. data/lib/dragonfly/config/r_magick_text.rb +25 -0
  33. data/lib/dragonfly/config/rails_defaults.rb +18 -0
  34. data/lib/dragonfly/config/rails_images.rb +13 -0
  35. data/lib/dragonfly/configurable.rb +4 -3
  36. data/lib/dragonfly/data_storage/base.rb +2 -0
  37. data/lib/dragonfly/data_storage/s3data_store.rb +11 -4
  38. data/lib/dragonfly/delegator.rb +22 -10
  39. data/lib/dragonfly/encoder_list.rb +4 -0
  40. data/lib/dragonfly/encoding/base.rb +1 -0
  41. data/lib/dragonfly/encoding/r_magick_encoder.rb +52 -8
  42. data/lib/dragonfly/extended_temp_object.rb +26 -27
  43. data/lib/dragonfly/processing/base.rb +1 -0
  44. data/lib/dragonfly/processing/r_magick_processor.rb +12 -127
  45. data/lib/dragonfly/processing/r_magick_text_processor.rb +155 -0
  46. data/lib/dragonfly/processor_list.rb +4 -0
  47. data/lib/dragonfly/rails/images.rb +2 -14
  48. data/lib/dragonfly/temp_object.rb +41 -34
  49. data/spec/dragonfly/active_record_extensions/migration.rb +7 -0
  50. data/spec/dragonfly/active_record_extensions/model_spec.rb +10 -11
  51. data/spec/dragonfly/active_record_extensions/spec_helper.rb +1 -1
  52. data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +14 -1
  53. data/spec/dragonfly/belongs_to_app_spec.rb +55 -0
  54. data/spec/dragonfly/configurable_spec.rb +21 -6
  55. data/spec/dragonfly/data_storage/s3_data_store_spec.rb +1 -0
  56. data/spec/dragonfly/delegator_spec.rb +23 -12
  57. data/spec/dragonfly/extended_temp_object_spec.rb +13 -29
  58. data/spec/dragonfly/processing/{rmagick_processor_spec.rb → r_magick_processor_spec.rb} +8 -75
  59. data/spec/dragonfly/processing/r_magick_text_processor_spec.rb +84 -0
  60. data/spec/dragonfly/temp_object_spec.rb +126 -151
  61. data/spec/dragonfly_spec.rb +12 -0
  62. data/spec/ginger_scenarios.rb +2 -2
  63. data/spec/image_matchers.rb +2 -2
  64. data/yard/setup.rb +12 -2
  65. data/yard/templates/default/fulldoc/html/css/common.css +1 -2
  66. data/yard/templates/default/layout/html/layout.erb +3 -2
  67. metadata +21 -18
  68. data/History.txt +0 -75
  69. data/features/rails_3.0.0.beta.feature +0 -15
  70. data/fixtures/dragonfly_setup.rb +0 -1
  71. data/fixtures/rails +0 -22
  72. data/fixtures/rails_3.0.0.beta/template.rb +0 -13
  73. data/generators/dragonfly_app/USAGE +0 -16
  74. data/generators/dragonfly_app/dragonfly_app_generator.rb +0 -24
  75. data/generators/dragonfly_app/templates/initializer.erb +0 -35
  76. data/lib/dragonfly/r_magick_configuration.rb +0 -67
  77. data/spec/dragonfly/active_record_extensions/initializer.rb +0 -1
@@ -0,0 +1,25 @@
1
+ module Dragonfly
2
+ module Config
3
+
4
+ module RMagickText
5
+
6
+ def self.apply_configuration(app)
7
+ app.configure do |c|
8
+ c.datastore = DataStorage::TransparentDataStore.new
9
+ c.register_analyser(Analysis::FileCommandAnalyser)
10
+ c.register_processor(Processing::RMagickTextProcessor)
11
+ c.register_encoder(Encoding::RMagickEncoder)
12
+ c.parameters.add_shortcut :text, Hash do |_, options|
13
+ {
14
+ :processing_method => :text,
15
+ :processing_options => options,
16
+ :format => :png
17
+ }
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ module Dragonfly
2
+ module Config
3
+
4
+ module RailsDefaults
5
+
6
+ def self.apply_configuration(app)
7
+ app.configure do |c|
8
+ c.log = ::Rails.logger
9
+ c.datastore.root_path = "#{::Rails.root}/public/system/dragonfly/#{::Rails.env}"
10
+ c.url_handler.configure do |u|
11
+ u.path_prefix = '/media'
12
+ end
13
+ end
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ module Dragonfly
2
+ module Config
3
+
4
+ module RailsImages
5
+
6
+ def self.apply_configuration(app)
7
+ app.configure_with(RMagickImages)
8
+ app.configure_with(RailsDefaults)
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -27,12 +27,13 @@ module Dragonfly
27
27
 
28
28
  module InstanceMethods
29
29
 
30
- def configure(&blk)
30
+ def configure(&block)
31
31
  yield ConfigurationProxy.new(self)
32
32
  end
33
33
 
34
- def configure_with(configurer)
35
- configurer.apply_configuration(self)
34
+ def configure_with(configurer, *args, &block)
35
+ configurer.apply_configuration(self, *args)
36
+ configure(&block) if block
36
37
  end
37
38
 
38
39
  def configuration
@@ -2,6 +2,8 @@ module Dragonfly
2
2
  module DataStorage
3
3
  class Base
4
4
 
5
+ include BelongsToApp
6
+
5
7
  def store(temp_object)
6
8
  raise NotImplementedError
7
9
  end
@@ -6,10 +6,12 @@ module Dragonfly
6
6
  class S3DataStore < Base
7
7
 
8
8
  include Configurable
9
+ include AWS::S3
9
10
 
10
11
  configurable_attr :bucket_name
11
12
  configurable_attr :access_key_id
12
13
  configurable_attr :secret_access_key
14
+ configurable_attr :use_filesystem, true
13
15
 
14
16
  def connect!
15
17
  AWS::S3::Base.establish_connection!(
@@ -19,32 +21,37 @@ module Dragonfly
19
21
  end
20
22
 
21
23
  def create_bucket!
22
- AWS::S3::Bucket.create(bucket_name)
24
+ Bucket.create(bucket_name) unless bucket_names.include?(bucket_name)
23
25
  end
24
26
 
25
27
  def store(temp_object)
26
28
  uid = generate_uid(temp_object.basename || 'file')
27
29
  ensure_initialized
28
- AWS::S3::S3Object.store(uid, temp_object.file, bucket_name)
30
+ object = use_filesystem ? temp_object.file : temp_object.data
31
+ S3Object.store(uid, object, bucket_name)
29
32
  uid
30
33
  end
31
34
 
32
35
  def retrieve(uid)
33
36
  ensure_initialized
34
- AWS::S3::S3Object.value(uid, bucket_name)
37
+ S3Object.value(uid, bucket_name)
35
38
  rescue AWS::S3::NoSuchKey => e
36
39
  raise DataNotFound, "#{e} - #{uid}"
37
40
  end
38
41
 
39
42
  def destroy(uid)
40
43
  ensure_initialized
41
- AWS::S3::S3Object.delete(uid, bucket_name)
44
+ S3Object.delete(uid, bucket_name)
42
45
  rescue AWS::S3::NoSuchKey => e
43
46
  raise DataNotFound, "#{e} - #{uid}"
44
47
  end
45
48
 
46
49
  private
47
50
 
51
+ def bucket_names
52
+ Service.buckets.map{|bucket| bucket.name }
53
+ end
54
+
48
55
  def ensure_initialized
49
56
  unless @initialized
50
57
  connect!
@@ -1,6 +1,8 @@
1
1
  module Dragonfly
2
2
  module Delegator
3
3
 
4
+ include BelongsToApp
5
+
4
6
  # This gets raised if no delegated objects are able to handle
5
7
  # the method call, even though they respond to that method.
6
8
  class UnableToHandle < StandardError; end
@@ -8,7 +10,9 @@ module Dragonfly
8
10
  def register(klass, *args, &block)
9
11
  object = klass.new(*args)
10
12
  object.configure(&block) if block
13
+ object.app = self.app if app_set? && object.is_a?(BelongsToApp)
11
14
  registered_objects << object
15
+ object
12
16
  end
13
17
 
14
18
  def unregister(klass)
@@ -23,12 +27,23 @@ module Dragonfly
23
27
  @registered_objects ||= []
24
28
  end
25
29
 
26
- def callable_methods
30
+ def delegate(meth, *args)
31
+ registered_objects.reverse.each do |object|
32
+ catch :unable_to_handle do
33
+ return object.send(meth, *args) if object.respond_to?(meth)
34
+ end
35
+ end
36
+ # If the code gets here, then none of the registered objects were able to handle the method call
37
+ raise UnableToHandle, "None of the objects registered with #{self} were able to deal with the method call " +
38
+ "#{meth}(#{args.map{|a| a.inspect[0..100]}.join(',')}). You need to register one that can."
39
+ end
40
+
41
+ def delegatable_methods
27
42
  registered_objects.map{|a| a.delegatable_methods }.flatten.uniq
28
43
  end
29
44
 
30
- def has_callable_method?(method)
31
- callable_methods.include?(method.to_method_name)
45
+ def has_delegatable_method?(method)
46
+ delegatable_methods.include?(method.to_method_name)
32
47
  end
33
48
 
34
49
  private
@@ -36,14 +51,11 @@ module Dragonfly
36
51
  attr_writer :registered_objects
37
52
 
38
53
  def method_missing(meth, *args)
39
- registered_objects.reverse.each do |object|
40
- catch :unable_to_handle do
41
- return object.send(meth, *args) if object.respond_to?(meth)
42
- end
54
+ if has_delegatable_method?(meth)
55
+ delegate(meth, *args)
56
+ else
57
+ super
43
58
  end
44
- raise UnableToHandle, "None of the registered objects for #{self} were able to deal with the method call " +
45
- "#{meth}(#{args.map{|a| a.inspect[0..100]}.join(',')}), even though the method is implemented" if self.has_callable_method?(meth)
46
- super
47
59
  end
48
60
 
49
61
  end
@@ -1,5 +1,9 @@
1
1
  module Dragonfly
2
2
  class EncoderList
3
3
  include Delegator
4
+
5
+ def initialize(app)
6
+ @app = app
7
+ end
4
8
  end
5
9
  end
@@ -2,6 +2,7 @@ module Dragonfly
2
2
  module Encoding
3
3
  class Base
4
4
 
5
+ include BelongsToApp
5
6
  include Delegatable
6
7
 
7
8
  def encode(*args)
@@ -2,15 +2,50 @@ require 'RMagick'
2
2
 
3
3
  module Dragonfly
4
4
  module Encoding
5
-
5
+
6
6
  class RMagickEncoder < Base
7
-
8
- SUPPORTED_FORMATS = Magick.formats.select{|k,v| v =~ /.*rw./ }.map{|f| f.first.downcase }
9
-
7
+
8
+ include Configurable
9
+
10
+ configurable_attr :supported_formats, [
11
+ :ai,
12
+ :bmp,
13
+ :eps,
14
+ :gif,
15
+ :gif87,
16
+ :ico,
17
+ :j2c,
18
+ :jp2,
19
+ :jpeg,
20
+ :jpg,
21
+ :pbm,
22
+ :pcd,
23
+ :pct,
24
+ :pcx,
25
+ :pdf,
26
+ :pict,
27
+ :pjpeg,
28
+ :png,
29
+ :png24,
30
+ :png32,
31
+ :png8,
32
+ :pnm,
33
+ :ppm,
34
+ :ps,
35
+ :psd,
36
+ :ras,
37
+ :tga,
38
+ :tiff,
39
+ :wbmp,
40
+ :xbm,
41
+ :xpm,
42
+ :xwd
43
+ ]
44
+
10
45
  def encode(image, format, encoding={})
11
46
  format = format.to_s.downcase
12
- throw :unable_to_handle unless SUPPORTED_FORMATS.include?(format)
13
- encoded_image = Magick::Image.from_blob(image.data).first
47
+ throw :unable_to_handle unless supported_formats.include?(format.to_sym)
48
+ encoded_image = rmagick_image(image)
14
49
  if encoded_image.format.downcase == format
15
50
  image # do nothing
16
51
  else
@@ -18,8 +53,17 @@ module Dragonfly
18
53
  encoded_image.to_blob
19
54
  end
20
55
  end
21
-
56
+
57
+ private
58
+
59
+ def rmagick_image(temp_object)
60
+ Magick::Image.from_blob(temp_object.data).first
61
+ rescue Magick::ImageMagickError => e
62
+ log.warn("Unable to handle content in #{self.class} - got:\n#{e}")
63
+ throw :unable_to_handle
64
+ end
65
+
22
66
  end
23
-
67
+
24
68
  end
25
69
  end
@@ -22,15 +22,16 @@ module Dragonfly
22
22
  # temp_object.transform!('300x200', :gif) # ===> operate on self
23
23
  class ExtendedTempObject < TempObject
24
24
 
25
- # Exceptions
26
- class NotConfiguredError < RuntimeError; end
25
+ include BelongsToApp
27
26
 
28
- class << self
29
- attr_accessor :app
27
+ def initialize(obj, app)
28
+ super(obj)
29
+ self.app = app
30
+ @cache = {}
30
31
  end
31
32
 
32
33
  def process(processing_method, *args)
33
- self.class.new(processor.send(processing_method, self, *args))
34
+ self.class.new(processor.send(processing_method, self, *args), app)
34
35
  end
35
36
 
36
37
  def process!(processing_method, *args)
@@ -38,7 +39,7 @@ module Dragonfly
38
39
  end
39
40
 
40
41
  def encode(*args)
41
- self.class.new(encoder.encode(self, *args))
42
+ self.class.new(encoder.encode(self, *args), app)
42
43
  end
43
44
 
44
45
  def encode!(*args)
@@ -56,38 +57,40 @@ module Dragonfly
56
57
  self
57
58
  end
58
59
 
59
- # As we create customly configured subclasses of this class, the console
60
- # gives a confusing output when inspecting, so modify here
61
- def inspect
62
- super.sub('Class:','Custom Dragonfly::ExtendedTempObject:')
63
- end
64
-
65
60
  # Modify methods, public_methods and respond_to?, because method_missing
66
61
  # allows methods from the analyser
67
62
 
68
63
  def methods(*args)
69
- (super + analyser.callable_methods).uniq
64
+ (super + analyser.delegatable_methods).uniq
70
65
  end
71
66
 
72
67
  def public_methods(*args)
73
- (super + analyser.callable_methods).uniq
68
+ (super + analyser.delegatable_methods).uniq
74
69
  end
75
70
 
76
71
  def respond_to?(method)
77
- super || analyser.has_callable_method?(method)
72
+ super || analyser.has_delegatable_method?(method)
78
73
  end
79
74
 
80
75
  private
76
+
77
+ attr_reader :cache
81
78
 
79
+ def flush_cache!
80
+ @cache = {}
81
+ end
82
+
83
+ def reset!
84
+ super
85
+ flush_cache!
86
+ end
87
+
82
88
  def method_missing(method, *args, &block)
83
- if analyser.has_callable_method?(method)
84
- # Define the method so we don't use method_missing next time
85
- instance_var = "@#{method}"
86
- self.class.class_eval do
89
+ if analyser.has_delegatable_method?(method)
90
+ # Define the method on the instance so we don't use method_missing next time
91
+ class << self; self; end.class_eval do
87
92
  define_method method do
88
- # Lazy reader, like
89
- # @width ||= analyser.width(self)
90
- instance_variable_set(instance_var, instance_variable_get(instance_var) || analyser.send(method, self))
93
+ cache[method] ||= analyser.delegate(method, self)
91
94
  end
92
95
  end
93
96
  # Now that it's defined (for next time)
@@ -97,10 +100,6 @@ module Dragonfly
97
100
  end
98
101
  end
99
102
 
100
- def app
101
- self.class.app ? self.class.app : raise(NotConfiguredError, "#{self.class} has no app set")
102
- end
103
-
104
103
  def analyser
105
104
  app.analysers
106
105
  end
@@ -116,6 +115,6 @@ module Dragonfly
116
115
  def parameters_class
117
116
  app.parameters_class
118
117
  end
119
-
118
+
120
119
  end
121
120
  end
@@ -2,6 +2,7 @@ module Dragonfly
2
2
  module Processing
3
3
  class Base
4
4
 
5
+ include BelongsToApp
5
6
  include Delegatable
6
7
 
7
8
  end
@@ -2,7 +2,6 @@ require 'RMagick'
2
2
 
3
3
  module Dragonfly
4
4
  module Processing
5
-
6
5
  class RMagickProcessor < Base
7
6
 
8
7
  GRAVITIES = {
@@ -16,60 +15,13 @@ module Dragonfly
16
15
  's' => Magick::SouthGravity,
17
16
  'se' => Magick::SouthEastGravity
18
17
  }
19
-
20
- FONT_STYLES = {
21
- 'normal' => Magick::NormalStyle,
22
- 'italic' => Magick::ItalicStyle,
23
- 'oblique' => Magick::ObliqueStyle
24
- }
25
-
26
- FONT_STRETCHES = {
27
- 'normal' => Magick::NormalStretch,
28
- 'semi-condensed' => Magick::SemiCondensedStretch,
29
- 'condensed' => Magick::CondensedStretch,
30
- 'extra-condensed' => Magick::ExtraCondensedStretch,
31
- 'ultra-condensed' => Magick::UltraCondensedStretch,
32
- 'semi-expanded' => Magick::SemiExpandedStretch,
33
- 'expanded' => Magick::ExpandedStretch,
34
- 'extra-expanded' => Magick::ExtraExpandedStretch,
35
- 'ultra-expanded' => Magick::UltraExpandedStretch
36
- }
37
-
38
- FONT_WEIGHTS = {
39
- 'normal' => Magick::NormalWeight,
40
- 'bold' => Magick::BoldWeight,
41
- 'bolder' => Magick::BolderWeight,
42
- 'lighter' => Magick::LighterWeight,
43
- '100' => 100,
44
- '200' => 200,
45
- '300' => 300,
46
- '400' => 400,
47
- '500' => 500,
48
- '600' => 600,
49
- '700' => 700,
50
- '800' => 800,
51
- '900' => 900
52
- }
53
-
54
- # HashWithCssStyleKeys is solely for being able to access a hash
55
- # which has css-style keys (e.g. 'font-size') with the underscore
56
- # symbol version
57
- # @example
58
- # opts = {'font-size' => '23px', :color => 'white'}
59
- # opts = HashWithCssStyleKeys[opts]
60
- # opts[:font_size] # ===> '23px'
61
- # opts[:color] # ===> 'white'
62
- class HashWithCssStyleKeys < Hash
63
- def [](key)
64
- super || (
65
- str_key = key.to_s
66
- css_key = str_key.gsub('_','-')
67
- super(str_key) || super(css_key) || super(css_key.to_sym)
68
- )
69
- end
18
+
19
+ def generate(width, height, format='png')
20
+ image = Magick::Image.read("plasma:fractal"){self.size = "#{width}x#{height}"}.first
21
+ image.format = format.to_s
22
+ image.to_blob
70
23
  end
71
24
 
72
-
73
25
  # Processing methods
74
26
 
75
27
  def crop(temp_object, opts={})
@@ -89,11 +41,11 @@ module Dragonfly
89
41
  image.crop(gravity, x, y, width, height).to_blob
90
42
  end
91
43
 
92
- def generate(width, height, format='png')
93
- image = Magick::Image.read("plasma:fractal"){self.size = "#{width}x#{height}"}.first
94
- image.format = format.to_s
95
- image.to_blob
44
+ def greyscale(temp_object, opts={})
45
+ depth = opts[:depth] || 256
46
+ rmagick_image(temp_object).quantize(depth, Magick::GRAYColorspace).to_blob
96
47
  end
48
+ alias grayscale greyscale
97
49
 
98
50
  def resize(temp_object, opts={})
99
51
  rmagick_image(temp_object).change_geometry!(opts[:geometry]) do |cols, rows, img|
@@ -124,52 +76,6 @@ module Dragonfly
124
76
  temp_object
125
77
  end
126
78
  end
127
-
128
- def text(temp_object, opts={})
129
- opts = HashWithCssStyleKeys[opts]
130
-
131
- draw = Magick::Draw.new
132
- draw.gravity = Magick::CenterGravity
133
- draw.text_antialias = true
134
-
135
- # Settings
136
- draw.font = opts[:font] if opts[:font]
137
- draw.font_family = opts[:font_family] if opts[:font_family]
138
- draw.pointsize = opts[:font_size].to_f if opts[:font_size]
139
- draw.fill = opts[:color] if opts[:color]
140
- draw.stroke = opts[:stroke_color] if opts[:stroke_color]
141
- draw.font_style = FONT_STYLES[opts[:font_style]] if opts[:font_style]
142
- draw.font_stretch = FONT_STRETCHES[opts[:font_stretch]] if opts[:font_stretch]
143
- draw.font_weight = FONT_WEIGHTS[opts[:font_weight]] if opts[:font_weight]
144
-
145
- text = temp_object.data
146
-
147
- # Calculate dimensions
148
- metrics = draw.get_type_metrics(text)
149
- width, height = metrics.width, metrics.height
150
-
151
- pt, pr, pb, pl = parse_padding_string(opts[:padding]) if opts[:padding]
152
- padding_top = opts[:padding_top] || pt || 0
153
- padding_right = opts[:padding_right] || pr || 0
154
- padding_bottom = opts[:padding_bottom] || pb || 0
155
- padding_left = opts[:padding_left] || pl || 0
156
-
157
- # Hack - for small font sizes, the width seems to be affected by rounding errors
158
- padding_right += 2
159
-
160
- total_width = padding_left + width + padding_right
161
- total_height = padding_top + height + padding_bottom
162
-
163
- # Draw the background
164
- image = Magick::Image.new(total_width, total_height){
165
- self.background_color = opts[:background_color] || 'transparent'
166
- }
167
- # Draw the text
168
- draw.annotate(image, width, height, padding_left, padding_top, text)
169
- # Output image as string
170
- image.format = 'png'
171
- image.to_blob
172
- end
173
79
 
174
80
  def vignette(temp_object, opts={})
175
81
  x = opts[:x].to_f || temp_object.width * 0.1
@@ -184,32 +90,11 @@ module Dragonfly
184
90
 
185
91
  def rmagick_image(temp_object)
186
92
  Magick::Image.from_blob(temp_object.data).first
187
- end
188
-
189
- # Use css-style padding declaration, i.e.
190
- # 10 (all sides)
191
- # 10 5 (top/bottom, left/right)
192
- # 10 5 10 (top, left/right, bottom)
193
- # 10 5 10 5 (top, right, bottom, left)
194
- def parse_padding_string(str)
195
- padding_parts = str.gsub('px','').split(/\s+/).map{|px| px.to_i}
196
- case padding_parts.size
197
- when 1
198
- p = padding_parts.first
199
- [p,p,p,p]
200
- when 2
201
- p,q = padding_parts
202
- [p,q,p,q]
203
- when 3
204
- p,q,r = padding_parts
205
- [p,q,r,q]
206
- when 4
207
- padding_parts
208
- else raise ArgumentError, "Couldn't parse padding string '#{str}' - should be a css-style string"
209
- end
93
+ rescue Magick::ImageMagickError => e
94
+ log.warn("Unable to handle content in #{self.class} - got:\n#{e}")
95
+ throw :unable_to_handle
210
96
  end
211
97
 
212
98
  end
213
-
214
99
  end
215
100
  end