File: sprite_methods.rb

package info (click to toggle)
ruby-compass 1.0.3~dfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 8,184 kB
  • ctags: 1,789
  • sloc: ruby: 12,904; makefile: 100; perl: 43; xml: 14; sh: 4
file content (136 lines) | stat: -rw-r--r-- 4,134 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
module Compass
  module SassExtensions
    module Sprites
      module SpriteMethods
        
        # Changing this string will invalidate all previously generated sprite images.
        # We should do so only when the packing algorithm changes
        SPRITE_VERSION = "2"
        
        # Calculates the overal image dimensions
        # collects image sizes and input parameters for each sprite
        # Calculates the height
        def compute_image_metadata!
          @width = 0
          init_images
          compute_image_positions!
          init_engine
        end
        
        def init_engine
          @engine = eval("::Compass::SassExtensions::Sprites::#{modulize}Engine.new(nil, nil, nil)")
          @engine.width = @width
          @engine.height = @height
          @engine.images = @images
        end
        
        # Creates the Sprite::Image objects for each image and calculates the width
        def init_images
          @images = Images.new
          image_names.each do |relative_file|
            @images << Image.new(self, relative_file, kwargs)
          end
          unless sort_method == 'none'
            @images.sort_by! sort_method
          end
        end

        def name_and_hash
          "#{path}-s#{uniqueness_hash}.png"
        end

        # The on-the-disk filename of the sprite
        def filename
          File.join(Compass.configuration.generated_images_path, name_and_hash)
        end

        def relativize(path)
          Pathname.new(path).relative_path_from(Pathname.new(Dir.pwd)).to_s rescue path
        end

        # Generate a sprite image if necessary
        def generate
          if generation_required?
            if kwargs.get_var('cleanup').value
              cleanup_old_sprites
            end
            engine.construct_sprite
            Compass.configuration.run_sprite_generated(engine.canvas)
            save!
          else
            log :unchanged, filename
          end
        end
        
        def cleanup_old_sprites
          Sass::Util.glob(File.join(Compass.configuration.generated_images_path, "#{path}-s*.png")).each do |file|
            log :remove, file
            FileUtils.rm file
            Compass.configuration.run_sprite_removed(file)
          end
        end
        
        # Does this sprite need to be generated
        def generation_required?
          !File.exists?(filename) || outdated? || options[:force]
        end

        # Returns the uniqueness hash for this sprite object
        def uniqueness_hash
          @uniqueness_hash ||= begin
            sum = Digest::MD5.new
            sum << SPRITE_VERSION
            sum << path
            sum << layout
            images.each do |image|
              [:relative_file, :height, :width, :repeat, :spacing, :position, :digest].each do |attr|
                sum << image.send(attr).to_s
              end
            end
            sum.hexdigest[0...10]
          end
          @uniqueness_hash
        end

        # Saves the sprite engine
        def save!
          FileUtils.mkdir_p(File.dirname(filename))
          saved = engine.save(filename)
          log :create, filename
          Compass.configuration.run_sprite_saved(filename)
          @mtime = nil if saved
          saved
        end

        # All the full-path filenames involved in this sprite
        def image_filenames
          @images.map(&:file)
        end

        # Checks whether this sprite is outdated
        def outdated?
          if File.exists?(filename)
            return @images.any? {|image| image.mtime.to_i > self.mtime.to_i }
          end
          true
        end

        # Mtime of the sprite file
        def mtime
          @mtime ||= File.mtime(filename)
        end
        
       # Calculate the size of the sprite
        def size
          [width, height]
        end

        def log(action, filename, *extra)
          if options[:compass] && options[:compass][:logger] && !options[:quiet]
            options[:compass][:logger].record(action, relativize(filename), *extra)
          end
        end
      end
    end
  end
end