summaryrefslogtreecommitdiffhomepage
path: root/lib/axlsx/drawing/pic.rb
blob: 4d970e328e1d19446664609977d5f282b1a1774c (plain)
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# -*- coding: utf-8 -*-
module Axlsx
  # a Pic object represents an image in your worksheet
  # Worksheet#add_image is the recommended way to manage images in your sheets
  # @see Worksheet#add_image
  class Pic

    # allowed file extenstions
    ALLOWED_EXTENSIONS = ['gif', 'jpeg', 'png', 'jpg']

    # The name to use for this picture
    # @return [String]
    attr_reader :name


    # A description of the picture
    # @return [String]
    attr_reader :descr

    # The path to the image you want to include
    # Only local images are supported at this time and only jpg support
    # @return [String]
    attr_reader :image_src

    # The anchor for this image
    # @return [OneCellAnchor]
    attr_reader :anchor

    # The picture locking attributes for this picture
    attr_reader :picture_locking
   
    # Creates a new Pic(ture) object
    # @param [Anchor] anchor the anchor that holds this image
    # @option options [String] name
    # @option options [String] descr
    # @option options [String] image_src
    # @option options [Array] start_at
    # @option options [Intger] width
    # @option options [Intger] height
    def initialize(anchor, options={})
      @anchor = anchor
      @anchor.drawing.worksheet.workbook.images << self
      options.each do |o|
        self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
      end
      start_at(*options[:start_at]) if options[:start_at]
      yield self if block_given?
      @picture_locking = PictureLocking.new(options)
    end
    
    def image_src=(v) 
      Axlsx::validate_string(v)
      RestrictionValidator.validate 'Pic.image_src', ALLOWED_EXTENSIONS, File.extname(v).delete('.')
      raise ArgumentError, "File does not exist" unless File.exist?(v)
      @image_src = v
    end

    # @see name
    def name=(v) Axlsx::validate_string(v); @name = v; end

    # @see descr
    def descr=(v) Axlsx::validate_string(v); @descr = v; end


    # The file name of image_src without any path information
    # @return [String]
    def file_name
      File.basename(image_src) unless image_src.nil?
    end    
    
    # returns the extension of image_src without the preceeding '.'
    # @return [String]
    def extname
      File.extname(image_src).delete('.') unless image_src.nil?
    end

    # The index of this image in the workbooks images collections
    # @return [Index]
    def index
      @anchor.drawing.worksheet.workbook.images.index(self)
    end

    # The part name for this image used in serialization and relationship building
    # @return [String]
    def pn
      "#{IMAGE_PN % [(index+1), extname]}"
    end

    # providing access to the anchor's width attribute
    # @param [Integer] v
    # @see OneCellAnchor.width
    def width
      @anchor.width
    end

    # @see width
    def width=(v)
      @anchor.width = v
    end
    
    # providing access to update the anchor's height attribute
    # @param [Integer] v
    # @see OneCellAnchor.width
    def height
      @anchor.height
    end

    # @see height
    def height=(v)
      @anchor.height = v
    end

    # This is a short cut method to set the start anchor position
    # If you need finer granularity in positioning use
    # graphic_frame.anchor.from.colOff / rowOff
    # @param [Integer] x The column
    # @param [Integer] y The row
    # @return [Marker]
    def start_at(x, y)
      @anchor.from.col = x
      @anchor.from.row = y
    end

    # Serializes the picture
    # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
    # @return [String]
    def to_xml(xml)
      xml.send('xdr:pic') {
        xml.send('xdr:nvPicPr') {
          xml.send('xdr:cNvPr', :id=>"2", :name=>name, :descr=>descr)
          xml.send('xdr:cNvPicPr') {
            picture_locking.to_xml(xml)
          }
        }
        xml.send('xdr:blipFill') {
          xml.send('a:blip', :'xmlns:r' => XML_NS_R, :'r:embed'=>"rId1")
          xml.send('a:stretch') {
            xml.send('a:fillRect')
          }
        }
        xml.send('xdr:spPr') {
          xml.send('a:xfrm') {
            xml.send('a:off', :x=>0, :y=>0)
            xml.send('a:ext', :cx=>2336800, :cy=>2161540)
          }
          xml.send('a:prstGeom', :prst=>:rect) {
            xml.send('a:avLst')
          }
        }
      }
    end
  end
end