compass-magick 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  Compass Magick
2
2
  ==============
3
3
 
4
- Dynamic image generation for Compass using ChunkyPNG (no dependency on RMagick).
4
+ Dynamic image generation for Compass using ChunkyPNG/PhantomJS (no dependency on RMagick).
5
5
 
6
6
  Example
7
7
  -------
@@ -22,6 +22,8 @@ Installation is simple via RubyGems. [Compass](http://beta.compass-style.org) an
22
22
 
23
23
  gem install compass-magick
24
24
 
25
+ If you wish to use [PhantomJS](http://www.phantomjs.org/), please follow the [build instructions](http://code.google.com/p/phantomjs/wiki/BuildInstructions).
26
+
25
27
  Usage
26
28
  -----
27
29
 
@@ -33,12 +35,14 @@ To use Compass Magick within your existing projects, require the plugin from you
33
35
 
34
36
  require 'magick'
35
37
 
38
+ There is a [short tutorial](http://blog.angeloff.name/post/4659977659/compass-magick-tutorial-part-1) available which should guide you through creating a simple themeable button.
39
+
36
40
  APIs
37
41
  ----
38
42
 
39
43
  [List of all available commands](https://github.com/StanAngeloff/compass-magick/blob/master/APIs.md).
40
44
 
41
- RDoc is also [available for the entire project](http://stanangeloff.github.com/compass-magick/doc/frames.html).
45
+ RDoc is also [available for the entire project](http://rubydoc.info/gems/compass-magick/frames).
42
46
 
43
47
  Contribute
44
48
  ----------
@@ -50,8 +54,8 @@ You can help by looking at any of the following areas (ordered by priority):
50
54
  - [Optimizing the code](https://github.com/StanAngeloff/compass-magick/blob/master/lib/magick/canvas.rb#L98) as floating point math may not always be needed and too many object copies sucks
51
55
  - [Writing tests](https://github.com/StanAngeloff/compass-magick/tree/master/spec) to make sure nothing breaks in new versions
52
56
  - [Performing code reviews](https://github.com/StanAngeloff/compass-magick/tree/master/lib) since this is my very first Ruby project and I don't have any experience with the language so there are probably many st**OO**pid things in code
53
- - [Improving RDoc](http://stanangeloff.github.com/compass-magick/doc/frames.html) because you can never have too much documentation
54
- - [Adding new plugins](http://stanangeloff.github.com/compass-magick/doc/Compass/Magick/Plugins.html). Compass Magick [looks](https://github.com/StanAngeloff/compass-magick/blob/master/lib/magick.rb#L39) for Ruby files and imports those on startup
57
+ - [Improving RDoc](http://rubydoc.info/gems/compass-magick/frames) because you can never have too much documentation
58
+ - [Adding new plugins](http://rubydoc.info/gems/compass-magick/Compass/Magick/Plugins.html). Compass Magick [looks](https://github.com/StanAngeloff/compass-magick/blob/master/lib/magick.rb#L39) for Ruby files and imports those on startup
55
59
  - [Submitting more examples](https://github.com/StanAngeloff/compass-magick/tree/gh-pages) to show off what Compass Magick can do
56
60
  - [Opening issues](https://github.com/StanAngeloff/compass-magick/issues) for features you find missing or broken
57
61
  - Porting over some of [CamanJS](http://camanjs.com/)' goodness, we all love visual effects
@@ -64,4 +68,4 @@ You can help by looking at any of the following areas (ordered by priority):
64
68
 
65
69
  ### Copyright
66
70
 
67
- Copyright (c) 2011 Stan Angeloff. See [LICENSE.md](https://github.com/StanAngeloff/compass-magick/blob/master/LICENSE.md) for details.
71
+ > Copyright (c) 2011 Stan Angeloff. See [LICENSE.md](https://github.com/StanAngeloff/compass-magick/blob/master/LICENSE.md) for details.
data/extras/magick.js ADDED
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env phantomjs
2
+ if (phantom.state.length === 0) {
3
+ var width = parseInt(phantom.args[0], 10),
4
+ height = parseInt(phantom.args[1], 10),
5
+ padding = Math.max(width, height),
6
+ head, body, i, styles, j, length, instruction;
7
+ if (isNaN(width) || isNaN(height) || phantom.args.length < 4) {
8
+ console.error('Usage: magick.js width height styles [styles […]] filename');
9
+ phantom.exit();
10
+ } else {
11
+ head = []; body = [];
12
+ for (i = 2; i < phantom.args.length - 1; i ++) {
13
+ styles = phantom.args[i].split(';');
14
+ for (j = 0, length = styles.length; j < length; j ++) {
15
+ instruction = styles[j].replace(/^\s+|\s+$/g, '');
16
+ if (instruction.indexOf(':') > 0) {
17
+ styles.push('-webkit-' + instruction);
18
+ }
19
+ }
20
+ head.push('#element-' + i + ' { ' +
21
+ 'width: ' + width + 'px; ' +
22
+ 'height: ' + height + 'px; ' +
23
+ 'box-sizing: border-box; ' +
24
+ '-webkit-box-sizing: border-box; ' +
25
+ styles.join('; ') + '; ' +
26
+ '}');
27
+ body.push('<div id="element-' + i + '"></div>');
28
+ }
29
+ try {
30
+ phantom.state = 1;
31
+ phantom.viewportSize = {
32
+ width: width + padding * 2,
33
+ height: height + padding * 2
34
+ };
35
+ phantom.content =
36
+ '<html>' +
37
+ '<head>' +
38
+ '<style>' +
39
+ head.join('\n') +
40
+ '</style>' +
41
+ '</head>' +
42
+ '<body style="background: transparent; margin: ' + padding + 'px ' + padding + 'px; padding: 0;">' +
43
+ body.join('\n') +
44
+ '</body>' +
45
+ '</html>';
46
+ } catch (e) {
47
+ phantom.exit();
48
+ throw e;
49
+ }
50
+ }
51
+ } else {
52
+ try {
53
+ phantom.render(phantom.args[phantom.args.length - 1]);
54
+ } finally {
55
+ phantom.exit();
56
+ }
57
+ }
data/lib/magick.rb CHANGED
@@ -32,7 +32,7 @@ module Compass::Magick
32
32
  # The current version of Compass Magick. This value is updated manually on
33
33
  # release. If you are using a Git clone, the version will always end with
34
34
  # '.git'.
35
- VERSION = '0.1.2.git'
35
+ VERSION = '0.1.3.git'
36
36
 
37
37
  # The locations where plug-ins are located. These paths are scanned for
38
38
  # *.rb files and loaded in order.
@@ -42,6 +42,9 @@ module Compass::Magick
42
42
  File.join(Dir.getwd, 'plugins')
43
43
  ]
44
44
 
45
+ # The location of the `extras/` directory.
46
+ EXTRAS_PATH = File.expand_path(File.join(File.dirname(__FILE__), '..', 'extras'))
47
+
45
48
  # Default exception class for Compass Magick
46
49
  class Exception < ::StandardError; end
47
50
 
@@ -62,6 +65,7 @@ module Compass::Magick
62
65
  end
63
66
 
64
67
  require 'magick/utils'
68
+ require 'magick/configuration'
65
69
  require 'magick/scriptable'
66
70
  require 'magick/command'
67
71
  require 'magick/effect'
@@ -77,3 +81,7 @@ Compass::Frameworks.register('magick',
77
81
  :stylesheets_directory => File.join(File.dirname(__FILE__), 'stylesheets'),
78
82
  :templates_directory => File.join(File.dirname(__FILE__), 'templates')
79
83
  )
84
+
85
+ # Extend Compass configuration with new properties (defined by Compass Magick
86
+ # and plugins).
87
+ Compass::Configuration::Data.send(:include, Compass::Magick::Configuration)
@@ -0,0 +1,41 @@
1
+ require 'shellwords'
2
+
3
+ module Compass::Magick
4
+ # Configuration methods to allow plugins to register new configurable
5
+ # properties.
6
+ module Configuration
7
+ extend Compass::Configuration::Inheritance::ClassMethods
8
+ extend self
9
+
10
+ # Registers a new property in `config.rb`.
11
+ #
12
+ # If you use this method, you should also define two additional methods:
13
+ #
14
+ # - comment_for_$name - emits a comment against the properly into the
15
+ # configuration file when serialized
16
+ # - default_$name - provides a default value for the property when one
17
+ # isn't specified in the configuration file
18
+ #
19
+ # @param [Symbol] name The name of the property.
20
+ def add_property(name)
21
+ Compass::Configuration::ATTRIBUTES.push(name)
22
+ inherited_accessor(name)
23
+ end
24
+
25
+ # Converts a Cygwin Unix path to a Windows path, e.g.:
26
+ #
27
+ # /cygdrive/d/path/to/file
28
+ # ==>
29
+ # D:/path/to/file
30
+ #
31
+ # @param [String] path The Unix path to convert.
32
+ # @return [String] The Windows path.
33
+ def cygwin_path(path)
34
+ if RUBY_PLATFORM.include?('cygwin') && path.index('/') == 0
35
+ IO.popen("cygpath -m #{path.include?(':') ? '-p' : ''} #{path.shellescape}").readline.chomp.gsub(/;/, '\\;')
36
+ else
37
+ path
38
+ end
39
+ end
40
+ end
41
+ end
@@ -85,7 +85,7 @@ module Compass::Magick
85
85
  ChunkyPNG::Color.r(canvas_pixel),
86
86
  ChunkyPNG::Color.g(canvas_pixel),
87
87
  ChunkyPNG::Color.b(canvas_pixel),
88
- ChunkyPNG::Color.a(canvas_pixel) * (mask_alpha / 255.0)
88
+ (ChunkyPNG::Color.a(canvas_pixel) * (mask_alpha / 255.0)).to_i
89
89
  ))
90
90
  end
91
91
  end
data/lib/magick/shapes.rb CHANGED
@@ -45,7 +45,7 @@ module Compass::Magick
45
45
  else
46
46
  if sqdist < rpf2
47
47
  fact = (((center - Math.sqrt(sqdist)) * 2.0 / feather) * 0.5 + 0.5)
48
- mask.set_pixel(x, y, ChunkyPNG::Color.rgba(255, 255, 255, 255 * [0, [fact, 1].min].max))
48
+ mask.set_pixel(x, y, ChunkyPNG::Color.rgba(255, 255, 255, (255 * [0, [fact, 1].min].max).to_i))
49
49
  end
50
50
  end
51
51
  end
@@ -75,13 +75,13 @@ module Compass::Magick
75
75
  if sqdist < romf2
76
76
  if sqdist < ripf2
77
77
  fact = (((Math.sqrt(sqdist) - inrad) * 2 / feather) * 0.5 + 0.5)
78
- mask.set_pixel(x, y, ChunkyPNG::Color.rgba(255, 255, 255, 255 * [0, [fact, 1].min].max))
78
+ mask.set_pixel(x, y, ChunkyPNG::Color.rgba(255, 255, 255, (255 * [0, [fact, 1].min].max).to_i))
79
79
  else
80
80
  mask.set_pixel(x, y, ChunkyPNG::Color::WHITE)
81
81
  end
82
82
  else
83
83
  fact = (((center - Math.sqrt(sqdist)) * 2 / feather) * 0.5 + 0.5)
84
- mask.set_pixel(x, y, ChunkyPNG::Color.rgba(255, 255, 255, 255 * [0, [fact, 1].min].max))
84
+ mask.set_pixel(x, y, ChunkyPNG::Color.rgba(255, 255, 255, (255 * [0, [fact, 1].min].max).to_i))
85
85
  end
86
86
  end
87
87
  end
data/lib/magick/utils.rb CHANGED
@@ -35,7 +35,7 @@ module Compass::Magick
35
35
  # @param [Sass::Script::Color] color The source color in Sass' format.
36
36
  # @return [ChunkyPNG::Color] The source color in ChunkyPNG's format.
37
37
  def to_chunky_color(color)
38
- ChunkyPNG::Color.rgba(color.red, color.green, color.blue, color.alpha * 255)
38
+ ChunkyPNG::Color.rgba(color.red, color.green, color.blue, (color.alpha * 255).to_i)
39
39
  end
40
40
 
41
41
  # Converts a fill type (solid color or gradient) to a {Canvas} object.
@@ -0,0 +1,132 @@
1
+ module Compass::Magick
2
+ module Configuration
3
+ # Registers a new property in config.rb `phantom_executable` which allows
4
+ # Users to configure the location of the PhantomJS binary.
5
+ #
6
+ # You would usually have `phantomjs` on $PATH, but in cases where you have
7
+ # installed it to another directory, you can specify the full path using
8
+ # this property.
9
+ add_property :phantom_executable
10
+
11
+ # Registers a new property in config.rb `phantom_script` which allows
12
+ # Users to configure the location of the PhantomJS rendering script.
13
+ #
14
+ # This is very useful on Cygwin installations where Cygwin paths don't
15
+ # mix well with a Windows build of PhantomJS.
16
+ add_property :phantom_script
17
+
18
+ # Emits the comment for the `phantom_executable` property into the
19
+ # configuration file when serialized -- makes it easier to understand for
20
+ # new Users.
21
+ #
22
+ # @return [String] The comment for the `phantom_executable` property.
23
+ def comment_for_phantom_executable
24
+ "# Path to the PhantomJS binary\n"
25
+ end
26
+
27
+ # Emits the comment for the `phantom_script` property into the
28
+ # configuration file when serialized -- makes it easier to understand for
29
+ # new Users.
30
+ #
31
+ # @return [String] The comment for the `phantom_script` property.
32
+ def comment_for_phantom_script
33
+ "# Path to magick.js used to render a web page (using PhantomJS, a headless WebKit)\n"
34
+ end
35
+
36
+ # Provides the default value for `phantom_executable` when one isn't
37
+ # specified in the configuration file.
38
+ #
39
+ # @return [String] The default path to the PhantomJS binary.
40
+ def default_phantom_executable
41
+ ENV['PHANTOM_PATH'] || 'phantomjs'
42
+ end
43
+
44
+ # Provides the default value for `phantom_script` when one isn't
45
+ # specified in the configuration file.
46
+ #
47
+ # @return [String] The default path to the magick.js script used to
48
+ # render a web page.
49
+ def default_phantom_script
50
+ cygwin_path(ENV['PHANTOM_SCRIPT'] || File.join(EXTRAS_PATH, 'magick.js'))
51
+ end
52
+ end
53
+
54
+ module Plugins
55
+ # Creates a new {Canvas} with the given width and height and renders all
56
+ # styles using the PhantomJS headless Webkit. The resulting image is
57
+ # cropped by removing all transparent pixels.
58
+ #
59
+ # The PhantomJS viewport will be set to `width` / `height` with
60
+ # padding: max(`width`, `height`). If you apply drop shadows or outlines,
61
+ # the returned image will be larger than the specified size to accommodate
62
+ # the overflowing content.
63
+ #
64
+ # @see {Compass::Magick::Configuration}
65
+ # @overload magick_phantom(width, height, styles)
66
+ # @param [Sass::Script::Number] width The (desired) width of the canvas.
67
+ # @param [Sass::Script::Number] height The (desired) height of the
68
+ # canvas.
69
+ # @param [{String => Sass::Script::String}] styles The CSS styles to
70
+ # render in PhantomJS where the hash key is the CSS property name and
71
+ # the hash value is the CSS property value.
72
+ # @overload magick_phantom(width, height, *styles)
73
+ # @param [Sass::Script::Number] width The (desired) width of the canvas.
74
+ # @param [Sass::Script::Number] height The (desired) height of the
75
+ # canvas.
76
+ # @param [[String]] styles A list of CSS styles to render in PhantomJS.
77
+ # @return {Canvas} A new Canvas instance cropped of all transparent
78
+ # pixels.
79
+ def magick_phantom(width, height, *args)
80
+ Compass::Magick::Utils.assert_type 'width', width, Sass::Script::Number
81
+ Compass::Magick::Utils.assert_type 'height', height, Sass::Script::Number
82
+ elements = []
83
+ args.each do |styles|
84
+ Compass::Magick::Utils.assert_one_of 'magick-phantom(..)', styles, Sass::Script::String, Hash
85
+ instructions = []
86
+ if styles.kind_of?(Sass::Script::String)
87
+ instructions.push(styles.value)
88
+ else
89
+ styles.each do |key, value|
90
+ instructions.push("#{key.gsub('_', '-')}: #{value.kind_of?(Sass::Script::String) ? value.value : value.to_s}")
91
+ end
92
+ end
93
+ elements.push(instructions.join('; '))
94
+ end
95
+ basename = "~magick-phantom-#{ rand(36**8).to_s(36) }.png"
96
+ filename = File.join(Compass.configuration.images_path, basename)
97
+ command = [Compass.configuration.phantom_executable, Compass.configuration.phantom_script]
98
+ command = command.concat([width.to_s, height.to_s])
99
+ command = command.concat(elements)
100
+ command = command.concat([Compass::Magick::Configuration.cygwin_path(filename)])
101
+ begin
102
+ system(command.shelljoin)
103
+ canvas = Canvas.new(Sass::Script::String.new(basename))
104
+ min_top = canvas.height - 1
105
+ max_right = 0
106
+ max_bottom = 0
107
+ min_left = canvas.width - 1
108
+ for y in 0...canvas.height
109
+ for x in 0...canvas.width
110
+ if ! ChunkyPNG::Color.fully_transparent?(canvas.get_pixel(x, y))
111
+ min_top = y if y < min_top
112
+ max_right = x if x > max_right
113
+ max_bottom = y if y > max_bottom
114
+ min_left = x if x < min_left
115
+ end
116
+ end
117
+ end
118
+ if min_left < max_right && min_top < max_bottom
119
+ canvas.crop(min_left, min_top, max_right - min_left + 1, max_bottom - min_top + 1)
120
+ else
121
+ puts '(Compass:Magick) Phantom image rendering failed. Please make sure you have at least one drawing instruction in your styles:'
122
+ puts "$ #{command.shelljoin}"
123
+ canvas
124
+ end
125
+ ensure
126
+ File.unlink(filename) if File.exists?(filename)
127
+ end
128
+ end
129
+
130
+ Sass::Script::Functions.declare :magick_phantom, [:width, :height], :var_args => true, :var_kwargs => true
131
+ end
132
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: compass-magick
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 2
10
- version: 0.1.2
9
+ - 3
10
+ version: 0.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Stan Angeloff
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-16 00:00:00 Z
18
+ date: 2011-04-27 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: compass
@@ -80,6 +80,7 @@ files:
80
80
  - LICENSE.md
81
81
  - lib/magick/canvas.rb
82
82
  - lib/magick/command.rb
83
+ - lib/magick/configuration.rb
83
84
  - lib/magick/effect.rb
84
85
  - lib/magick/functions/canvas.rb
85
86
  - lib/magick/functions/drawing.rb
@@ -98,7 +99,9 @@ files:
98
99
  - lib/magick.rb
99
100
  - lib/plugins/corners.rb
100
101
  - lib/plugins/pattern.rb
102
+ - lib/plugins/phantom.rb
101
103
  - lib/stylesheets/_magick.sass
104
+ - extras/magick.js
102
105
  - spec/canvas_spec.rb
103
106
  - spec/helpers.rb
104
107
  - spec/types/gradients_spec.rb
@@ -135,7 +138,7 @@ rubyforge_project:
135
138
  rubygems_version: 1.7.2
136
139
  signing_key:
137
140
  specification_version: 3
138
- summary: Dynamic image generation for Compass using ChunkyPNG.
141
+ summary: Dynamic image generation for Compass using ChunkyPNG/PhantomJS.
139
142
  test_files:
140
143
  - spec/canvas_spec.rb
141
144
  - spec/helpers.rb