write_xlsx 1.12.1 → 1.12.3
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 +4 -4
 - data/.rubocop.yml +12 -0
 - data/Changes +6 -0
 - data/LICENSE.txt +1 -1
 - data/examples/autofilter.rb +1 -2
 - data/examples/colors.rb +4 -4
 - data/examples/formats.rb +14 -14
 - data/lib/write_xlsx/chart/area.rb +1 -1
 - data/lib/write_xlsx/chart/axis.rb +4 -4
 - data/lib/write_xlsx/chart/bar.rb +1 -1
 - data/lib/write_xlsx/chart/caption.rb +8 -4
 - data/lib/write_xlsx/chart/column.rb +1 -1
 - data/lib/write_xlsx/chart/doughnut.rb +2 -2
 - data/lib/write_xlsx/chart/line.rb +1 -1
 - data/lib/write_xlsx/chart/pie.rb +2 -2
 - data/lib/write_xlsx/chart/radar.rb +1 -1
 - data/lib/write_xlsx/chart/scatter.rb +1 -1
 - data/lib/write_xlsx/chart/series.rb +10 -20
 - data/lib/write_xlsx/chart/stock.rb +1 -1
 - data/lib/write_xlsx/chart.rb +14 -21
 - data/lib/write_xlsx/chartsheet.rb +3 -3
 - data/lib/write_xlsx/drawing.rb +108 -114
 - data/lib/write_xlsx/format.rb +20 -24
 - data/lib/write_xlsx/image.rb +89 -0
 - data/lib/write_xlsx/image_property.rb +163 -0
 - data/lib/write_xlsx/inserted_chart.rb +42 -0
 - data/lib/write_xlsx/package/app.rb +1 -0
 - data/lib/write_xlsx/package/button.rb +58 -5
 - data/lib/write_xlsx/package/conditional_format.rb +4 -4
 - data/lib/write_xlsx/package/packager.rb +22 -27
 - data/lib/write_xlsx/package/rich_value.rb +1 -1
 - data/lib/write_xlsx/package/styles.rb +1 -1
 - data/lib/write_xlsx/package/vml.rb +10 -19
 - data/lib/write_xlsx/shape.rb +3 -2
 - data/lib/write_xlsx/sparkline.rb +1 -1
 - data/lib/write_xlsx/utility.rb +8 -203
 - data/lib/write_xlsx/version.rb +1 -1
 - data/lib/write_xlsx/workbook.rb +87 -175
 - data/lib/write_xlsx/worksheet/data_validation.rb +1 -1
 - data/lib/write_xlsx/worksheet/hyperlink.rb +2 -2
 - data/lib/write_xlsx/worksheet.rb +478 -484
 - data/lib/write_xlsx/zip_file_utils.rb +2 -2
 - data/write_xlsx.gemspec +3 -3
 - metadata +15 -9
 
    
        data/lib/write_xlsx/worksheet.rb
    CHANGED
    
    | 
         @@ -1,15 +1,18 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # -*- coding: utf-8 -*-
         
     | 
| 
       2 
2 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
            require 'write_xlsx/package/xml_writer_simple'
         
     | 
| 
       5 
     | 
    
         
            -
            require 'write_xlsx/package/button'
         
     | 
| 
       6 
4 
     | 
    
         
             
            require 'write_xlsx/colors'
         
     | 
| 
       7 
     | 
    
         
            -
            require 'write_xlsx/ 
     | 
| 
      
 5 
     | 
    
         
            +
            require 'write_xlsx/compatibility'
         
     | 
| 
       8 
6 
     | 
    
         
             
            require 'write_xlsx/drawing'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'write_xlsx/format'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'write_xlsx/image'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require 'write_xlsx/image_property'
         
     | 
| 
      
 10 
     | 
    
         
            +
            require 'write_xlsx/inserted_chart'
         
     | 
| 
      
 11 
     | 
    
         
            +
            require 'write_xlsx/package/button'
         
     | 
| 
      
 12 
     | 
    
         
            +
            require 'write_xlsx/package/conditional_format'
         
     | 
| 
      
 13 
     | 
    
         
            +
            require 'write_xlsx/package/xml_writer_simple'
         
     | 
| 
       9 
14 
     | 
    
         
             
            require 'write_xlsx/sparkline'
         
     | 
| 
       10 
     | 
    
         
            -
            require 'write_xlsx/compatibility'
         
     | 
| 
       11 
15 
     | 
    
         
             
            require 'write_xlsx/utility'
         
     | 
| 
       12 
     | 
    
         
            -
            require 'write_xlsx/package/conditional_format'
         
     | 
| 
       13 
16 
     | 
    
         
             
            require 'write_xlsx/worksheet/cell_data'
         
     | 
| 
       14 
17 
     | 
    
         
             
            require 'write_xlsx/worksheet/data_validation'
         
     | 
| 
       15 
18 
     | 
    
         
             
            require 'write_xlsx/worksheet/hyperlink'
         
     | 
| 
         @@ -21,24 +24,23 @@ module Writexlsx 
     | 
|
| 
       21 
24 
     | 
    
         
             
              class Worksheet
         
     | 
| 
       22 
25 
     | 
    
         
             
                include Writexlsx::Utility
         
     | 
| 
       23 
26 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
                 
     | 
| 
       25 
     | 
    
         
            -
                PADDING         = 5                       # :nodoc:
         
     | 
| 
       26 
     | 
    
         
            -
                COLINFO         = Struct.new('ColInfo', :width, :format, :hidden, :level, :collapsed, :autofit)
         
     | 
| 
      
 27 
     | 
    
         
            +
                COLINFO = Struct.new('ColInfo', :width, :format, :hidden, :level, :collapsed, :autofit)
         
     | 
| 
       27 
28 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
                attr_reader :index 
     | 
| 
      
 29 
     | 
    
         
            +
                attr_reader :index, :name                                     # :nodoc:
         
     | 
| 
       29 
30 
     | 
    
         
             
                attr_reader :charts, :images, :tables, :shapes, :drawings     # :nodoc:
         
     | 
| 
       30 
31 
     | 
    
         
             
                attr_reader :header_images, :footer_images, :background_image # :nodoc:
         
     | 
| 
       31 
32 
     | 
    
         
             
                attr_reader :vml_drawing_links                                # :nodoc:
         
     | 
| 
       32 
33 
     | 
    
         
             
                attr_reader :vml_data_id                                      # :nodoc:
         
     | 
| 
       33 
34 
     | 
    
         
             
                attr_reader :vml_header_id                                    # :nodoc:
         
     | 
| 
       34 
35 
     | 
    
         
             
                attr_reader :autofilter_area                                  # :nodoc:
         
     | 
| 
       35 
     | 
    
         
            -
                attr_reader :writer, :set_rows, :col_info 
     | 
| 
      
 36 
     | 
    
         
            +
                attr_reader :writer, :set_rows, :col_info, :row_sizes         # :nodoc:
         
     | 
| 
       36 
37 
     | 
    
         
             
                attr_reader :vml_shape_id                                     # :nodoc:
         
     | 
| 
       37 
38 
     | 
    
         
             
                attr_reader :comments, :comments_author                       # :nodoc:
         
     | 
| 
       38 
39 
     | 
    
         
             
                attr_accessor :data_bars_2010, :dxf_priority                  # :nodoc:
         
     | 
| 
       39 
40 
     | 
    
         
             
                attr_reader :vba_codename                                     # :nodoc:
         
     | 
| 
       40 
41 
     | 
    
         
             
                attr_writer :excel_version                                    # :nodoc:
         
     | 
| 
       41 
42 
     | 
    
         
             
                attr_reader :filter_cells                                     # :nodoc:
         
     | 
| 
      
 43 
     | 
    
         
            +
                attr_accessor :default_row_height                             # :nodoc:
         
     | 
| 
       42 
44 
     | 
    
         | 
| 
       43 
45 
     | 
    
         
             
                def initialize(workbook, index, name) # :nodoc:
         
     | 
| 
       44 
46 
     | 
    
         
             
                  rowmax   = 1_048_576
         
     | 
| 
         @@ -78,6 +80,7 @@ module Writexlsx 
     | 
|
| 
       78 
80 
     | 
    
         | 
| 
       79 
81 
     | 
    
         
             
                  @set_cols = {}
         
     | 
| 
       80 
82 
     | 
    
         
             
                  @set_rows = {}
         
     | 
| 
      
 83 
     | 
    
         
            +
                  @col_size_changed = false
         
     | 
| 
       81 
84 
     | 
    
         
             
                  @zoom = 100
         
     | 
| 
       82 
85 
     | 
    
         
             
                  @zoom_scale_normal = true
         
     | 
| 
       83 
86 
     | 
    
         
             
                  @right_to_left = false
         
     | 
| 
         @@ -94,7 +97,6 @@ module Writexlsx 
     | 
|
| 
       94 
97 
     | 
    
         | 
| 
       95 
98 
     | 
    
         
             
                  @last_shape_id          = 1
         
     | 
| 
       96 
99 
     | 
    
         
             
                  @rel_count              = 0
         
     | 
| 
       97 
     | 
    
         
            -
                  @hlink_count            = 0
         
     | 
| 
       98 
100 
     | 
    
         
             
                  @external_hyper_links   = []
         
     | 
| 
       99 
101 
     | 
    
         
             
                  @external_drawing_links = []
         
     | 
| 
       100 
102 
     | 
    
         
             
                  @external_comment_links = []
         
     | 
| 
         @@ -116,27 +118,25 @@ module Writexlsx 
     | 
|
| 
       116 
118 
     | 
    
         
             
                  @has_dynamic_functions  = false
         
     | 
| 
       117 
119 
     | 
    
         
             
                  @has_embedded_images    = false
         
     | 
| 
       118 
120 
     | 
    
         | 
| 
       119 
     | 
    
         
            -
                  @use_future_functions 
     | 
| 
      
 121 
     | 
    
         
            +
                  @use_future_functions   = false
         
     | 
| 
       120 
122 
     | 
    
         | 
| 
       121 
123 
     | 
    
         
             
                  @header_images          = []
         
     | 
| 
       122 
124 
     | 
    
         
             
                  @footer_images          = []
         
     | 
| 
       123 
     | 
    
         
            -
                  @background_image       =  
     | 
| 
      
 125 
     | 
    
         
            +
                  @background_image       = nil
         
     | 
| 
       124 
126 
     | 
    
         | 
| 
       125 
     | 
    
         
            -
                  @outline_row_level 
     | 
| 
       126 
     | 
    
         
            -
                  @outline_col_level 
     | 
| 
      
 127 
     | 
    
         
            +
                  @outline_row_level      = 0
         
     | 
| 
      
 128 
     | 
    
         
            +
                  @outline_col_level      = 0
         
     | 
| 
       127 
129 
     | 
    
         | 
| 
       128 
130 
     | 
    
         
             
                  @original_row_height    = 15
         
     | 
| 
       129 
131 
     | 
    
         
             
                  @default_row_height     = 15
         
     | 
| 
       130 
132 
     | 
    
         
             
                  @default_row_pixels     = 20
         
     | 
| 
       131 
133 
     | 
    
         
             
                  @default_col_width      = 8.43
         
     | 
| 
       132 
     | 
    
         
            -
                  @default_col_pixels     = 64
         
     | 
| 
       133 
134 
     | 
    
         
             
                  @default_row_rezoed     = 0
         
     | 
| 
       134 
135 
     | 
    
         
             
                  @default_date_pixels    = 68
         
     | 
| 
       135 
136 
     | 
    
         | 
| 
       136 
137 
     | 
    
         
             
                  @merge = []
         
     | 
| 
       137 
138 
     | 
    
         | 
| 
       138 
     | 
    
         
            -
                  @has_vml 
     | 
| 
       139 
     | 
    
         
            -
                  @has_header_vml = false
         
     | 
| 
      
 139 
     | 
    
         
            +
                  @has_vml  = false
         
     | 
| 
       140 
140 
     | 
    
         
             
                  @comments = Package::Comments.new(self)
         
     | 
| 
       141 
141 
     | 
    
         
             
                  @buttons_array          = []
         
     | 
| 
       142 
142 
     | 
    
         
             
                  @header_images_array    = []
         
     | 
| 
         @@ -155,8 +155,8 @@ module Writexlsx 
     | 
|
| 
       155 
155 
     | 
    
         
             
                    @original_row_height      = 12.75
         
     | 
| 
       156 
156 
     | 
    
         
             
                    @default_row_height       = 12.75
         
     | 
| 
       157 
157 
     | 
    
         
             
                    @default_row_pixels       = 17
         
     | 
| 
       158 
     | 
    
         
            -
                    self.margins_left_right 
     | 
| 
       159 
     | 
    
         
            -
                    self.margins_top_bottom 
     | 
| 
      
 158 
     | 
    
         
            +
                    self.margins_left_right   = 0.75
         
     | 
| 
      
 159 
     | 
    
         
            +
                    self.margins_top_bottom   = 1
         
     | 
| 
       160 
160 
     | 
    
         
             
                    @page_setup.margin_header = 0.5
         
     | 
| 
       161 
161 
     | 
    
         
             
                    @page_setup.margin_footer = 0.5
         
     | 
| 
       162 
162 
     | 
    
         
             
                    @page_setup.header_footer_aligns = false
         
     | 
| 
         @@ -204,11 +204,6 @@ module Writexlsx 
     | 
|
| 
       204 
204 
     | 
    
         
             
                  end
         
     | 
| 
       205 
205 
     | 
    
         
             
                end
         
     | 
| 
       206 
206 
     | 
    
         | 
| 
       207 
     | 
    
         
            -
                #
         
     | 
| 
       208 
     | 
    
         
            -
                # The name method is used to retrieve the name of a worksheet.
         
     | 
| 
       209 
     | 
    
         
            -
                #
         
     | 
| 
       210 
     | 
    
         
            -
                attr_reader :name
         
     | 
| 
       211 
     | 
    
         
            -
             
     | 
| 
       212 
207 
     | 
    
         
             
                #
         
     | 
| 
       213 
208 
     | 
    
         
             
                # Set this worksheet as a selected worksheet, i.e. the worksheet has its tab
         
     | 
| 
       214 
209 
     | 
    
         
             
                # highlighted.
         
     | 
| 
         @@ -296,29 +291,6 @@ module Writexlsx 
     | 
|
| 
       296 
291 
     | 
    
         
             
                  @protected_ranges << [range, range_name, password]
         
     | 
| 
       297 
292 
     | 
    
         
             
                end
         
     | 
| 
       298 
293 
     | 
    
         | 
| 
       299 
     | 
    
         
            -
                def protect_default_settings  # :nodoc:
         
     | 
| 
       300 
     | 
    
         
            -
                  {
         
     | 
| 
       301 
     | 
    
         
            -
                    sheet:                 true,
         
     | 
| 
       302 
     | 
    
         
            -
                    content:               false,
         
     | 
| 
       303 
     | 
    
         
            -
                    objects:               false,
         
     | 
| 
       304 
     | 
    
         
            -
                    scenarios:             false,
         
     | 
| 
       305 
     | 
    
         
            -
                    format_cells:          false,
         
     | 
| 
       306 
     | 
    
         
            -
                    format_columns:        false,
         
     | 
| 
       307 
     | 
    
         
            -
                    format_rows:           false,
         
     | 
| 
       308 
     | 
    
         
            -
                    insert_columns:        false,
         
     | 
| 
       309 
     | 
    
         
            -
                    insert_rows:           false,
         
     | 
| 
       310 
     | 
    
         
            -
                    insert_hyperlinks:     false,
         
     | 
| 
       311 
     | 
    
         
            -
                    delete_columns:        false,
         
     | 
| 
       312 
     | 
    
         
            -
                    delete_rows:           false,
         
     | 
| 
       313 
     | 
    
         
            -
                    select_locked_cells:   true,
         
     | 
| 
       314 
     | 
    
         
            -
                    sort:                  false,
         
     | 
| 
       315 
     | 
    
         
            -
                    autofilter:            false,
         
     | 
| 
       316 
     | 
    
         
            -
                    pivot_tables:          false,
         
     | 
| 
       317 
     | 
    
         
            -
                    select_unlocked_cells: true
         
     | 
| 
       318 
     | 
    
         
            -
                  }
         
     | 
| 
       319 
     | 
    
         
            -
                end
         
     | 
| 
       320 
     | 
    
         
            -
                private :protect_default_settings
         
     | 
| 
       321 
     | 
    
         
            -
             
     | 
| 
       322 
294 
     | 
    
         
             
                #
         
     | 
| 
       323 
295 
     | 
    
         
             
                # :call-seq:
         
     | 
| 
       324 
296 
     | 
    
         
             
                #   set_column(firstcol, lastcol, width, format, hidden, level, collapsed)
         
     | 
| 
         @@ -376,7 +348,7 @@ module Writexlsx 
     | 
|
| 
       376 
348 
     | 
    
         
             
                  end
         
     | 
| 
       377 
349 
     | 
    
         | 
| 
       378 
350 
     | 
    
         
             
                  # Store the column change to allow optimisations.
         
     | 
| 
       379 
     | 
    
         
            -
                  @col_size_changed =  
     | 
| 
      
 351 
     | 
    
         
            +
                  @col_size_changed = true
         
     | 
| 
       380 
352 
     | 
    
         
             
                end
         
     | 
| 
       381 
353 
     | 
    
         | 
| 
       382 
354 
     | 
    
         
             
                #
         
     | 
| 
         @@ -398,12 +370,8 @@ module Writexlsx 
     | 
|
| 
       398 
370 
     | 
    
         
             
                  # Ensure at least $first_col, $last_col and $width
         
     | 
| 
       399 
371 
     | 
    
         
             
                  return if data.size < 3
         
     | 
| 
       400 
372 
     | 
    
         | 
| 
       401 
     | 
    
         
            -
                  first_col = data 
     | 
| 
       402 
     | 
    
         
            -
                   
     | 
| 
       403 
     | 
    
         
            -
                  pixels    = data[2]
         
     | 
| 
       404 
     | 
    
         
            -
                  format    = data[3]
         
     | 
| 
       405 
     | 
    
         
            -
                  hidden    = data[4] || 0
         
     | 
| 
       406 
     | 
    
         
            -
                  level     = data[5]
         
     | 
| 
      
 373 
     | 
    
         
            +
                  first_col, last_col, pixels, format, hidden, level = data
         
     | 
| 
      
 374 
     | 
    
         
            +
                  hidden ||= 0
         
     | 
| 
       407 
375 
     | 
    
         | 
| 
       408 
376 
     | 
    
         
             
                  width = pixels_to_width(pixels) if ptrue?(pixels)
         
     | 
| 
       409 
377 
     | 
    
         | 
| 
         @@ -671,7 +639,10 @@ module Writexlsx 
     | 
|
| 
       671 
639 
     | 
    
         
             
                  raise 'Header string must be less than 255 characters' if string.length > 255
         
     | 
| 
       672 
640 
     | 
    
         | 
| 
       673 
641 
     | 
    
         
             
                  # Replace the Excel placeholder &[Picture] with the internal &G.
         
     | 
| 
       674 
     | 
    
         
            -
                   
     | 
| 
      
 642 
     | 
    
         
            +
                  header_footer_string = string.gsub("&[Picture]", '&G')
         
     | 
| 
      
 643 
     | 
    
         
            +
                  # placeholeder /&G/ の数
         
     | 
| 
      
 644 
     | 
    
         
            +
                  placeholder_count = header_footer_string.scan("&G").count
         
     | 
| 
      
 645 
     | 
    
         
            +
                  @page_setup.header = header_footer_string
         
     | 
| 
       675 
646 
     | 
    
         | 
| 
       676 
647 
     | 
    
         
             
                  @page_setup.header_footer_aligns = options[:align_with_margins] if options[:align_with_margins]
         
     | 
| 
       677 
648 
     | 
    
         | 
| 
         @@ -683,17 +654,13 @@ module Writexlsx 
     | 
|
| 
       683 
654 
     | 
    
         
             
                  [
         
     | 
| 
       684 
655 
     | 
    
         
             
                    [:image_left, 'LH'], [:image_center, 'CH'], [:image_right, 'RH']
         
     | 
| 
       685 
656 
     | 
    
         
             
                  ].each do |p|
         
     | 
| 
       686 
     | 
    
         
            -
                    @header_images <<  
     | 
| 
      
 657 
     | 
    
         
            +
                    @header_images << ImageProperty.new(options[p.first], position: p.last) if options[p.first]
         
     | 
| 
       687 
658 
     | 
    
         
             
                  end
         
     | 
| 
       688 
659 
     | 
    
         | 
| 
       689 
     | 
    
         
            -
                  # placeholeder /&G/ の数
         
     | 
| 
       690 
     | 
    
         
            -
                  placeholder_count = @page_setup.header.scan("&G").count
         
     | 
| 
       691 
     | 
    
         
            -
             
     | 
| 
       692 
     | 
    
         
            -
                  image_count = @header_images.count
         
     | 
| 
      
 660 
     | 
    
         
            +
                  # # placeholeder /&G/ の数
         
     | 
| 
      
 661 
     | 
    
         
            +
                  # placeholder_count = @page_setup.header.scan("&G").count
         
     | 
| 
       693 
662 
     | 
    
         | 
| 
       694 
     | 
    
         
            -
                  raise "Number of header image (#{ 
     | 
| 
       695 
     | 
    
         
            -
             
     | 
| 
       696 
     | 
    
         
            -
                  @has_header_vml = true if image_count > 0
         
     | 
| 
      
 663 
     | 
    
         
            +
                  raise "Number of header image (#{@header_images.size}) doesn't match placeholder count (#{placeholder_count}) in string: #{@page_setup.header}" if @header_images.size != placeholder_count
         
     | 
| 
       697 
664 
     | 
    
         | 
| 
       698 
665 
     | 
    
         
             
                  @page_setup.margin_header         = margin || 0.3
         
     | 
| 
       699 
666 
     | 
    
         
             
                  @page_setup.header_footer_changed = true
         
     | 
| 
         @@ -705,8 +672,6 @@ module Writexlsx 
     | 
|
| 
       705 
672 
     | 
    
         
             
                def set_footer(string = '', margin = 0.3, options = {})
         
     | 
| 
       706 
673 
     | 
    
         
             
                  raise 'Footer string must be less than 255 characters' if string.length > 255
         
     | 
| 
       707 
674 
     | 
    
         | 
| 
       708 
     | 
    
         
            -
                  @page_setup.footer = string.dup
         
     | 
| 
       709 
     | 
    
         
            -
             
     | 
| 
       710 
675 
     | 
    
         
             
                  # Replace the Excel placeholder &[Picture] with the internal &G.
         
     | 
| 
       711 
676 
     | 
    
         
             
                  @page_setup.footer = string.gsub("&[Picture]", '&G')
         
     | 
| 
       712 
677 
     | 
    
         | 
| 
         @@ -720,17 +685,13 @@ module Writexlsx 
     | 
|
| 
       720 
685 
     | 
    
         
             
                  [
         
     | 
| 
       721 
686 
     | 
    
         
             
                    [:image_left, 'LF'], [:image_center, 'CF'], [:image_right, 'RF']
         
     | 
| 
       722 
687 
     | 
    
         
             
                  ].each do |p|
         
     | 
| 
       723 
     | 
    
         
            -
                    @footer_images <<  
     | 
| 
      
 688 
     | 
    
         
            +
                    @footer_images << ImageProperty.new(options[p.first], position: p.last) if options[p.first]
         
     | 
| 
       724 
689 
     | 
    
         
             
                  end
         
     | 
| 
       725 
690 
     | 
    
         | 
| 
       726 
691 
     | 
    
         
             
                  # placeholeder /&G/ の数
         
     | 
| 
       727 
692 
     | 
    
         
             
                  placeholder_count = @page_setup.footer.scan("&G").count
         
     | 
| 
       728 
693 
     | 
    
         | 
| 
       729 
     | 
    
         
            -
                   
     | 
| 
       730 
     | 
    
         
            -
             
     | 
| 
       731 
     | 
    
         
            -
                  raise "Number of footer image (#{image_count}) doesn't match placeholder count (#{placeholder_count}) in string: #{@page_setup.footer}" if image_count != placeholder_count
         
     | 
| 
       732 
     | 
    
         
            -
             
     | 
| 
       733 
     | 
    
         
            -
                  @has_header_vml = true if image_count > 0
         
     | 
| 
      
 694 
     | 
    
         
            +
                  raise "Number of footer image (#{@footer_images.size}) doesn't match placeholder count (#{placeholder_count}) in string: #{@page_setup.footer}" if @footer_images.size != placeholder_count
         
     | 
| 
       734 
695 
     | 
    
         | 
| 
       735 
696 
     | 
    
         
             
                  @page_setup.margin_footer         = margin
         
     | 
| 
       736 
697 
     | 
    
         
             
                  @page_setup.header_footer_changed = true
         
     | 
| 
         @@ -1327,18 +1288,6 @@ module Writexlsx 
     | 
|
| 
       1327 
1288 
     | 
    
         
             
                  store_data_to_table(BlankCellData.new(_format), _row, _col)
         
     | 
| 
       1328 
1289 
     | 
    
         
             
                end
         
     | 
| 
       1329 
1290 
     | 
    
         | 
| 
       1330 
     | 
    
         
            -
                def expand_formula(formula, function, addition = '')
         
     | 
| 
       1331 
     | 
    
         
            -
                  if formula =~ /\b(#{function})/
         
     | 
| 
       1332 
     | 
    
         
            -
                    formula.gsub(
         
     | 
| 
       1333 
     | 
    
         
            -
                      ::Regexp.last_match(1),
         
     | 
| 
       1334 
     | 
    
         
            -
                      "_xlfn#{addition}.#{::Regexp.last_match(1)}"
         
     | 
| 
       1335 
     | 
    
         
            -
                    )
         
     | 
| 
       1336 
     | 
    
         
            -
                  else
         
     | 
| 
       1337 
     | 
    
         
            -
                    formula
         
     | 
| 
       1338 
     | 
    
         
            -
                  end
         
     | 
| 
       1339 
     | 
    
         
            -
                end
         
     | 
| 
       1340 
     | 
    
         
            -
                private :expand_formula
         
     | 
| 
       1341 
     | 
    
         
            -
             
     | 
| 
       1342 
1291 
     | 
    
         
             
                #
         
     | 
| 
       1343 
1292 
     | 
    
         
             
                # Utility method to strip equal sign and array braces from a formula
         
     | 
| 
       1344 
1293 
     | 
    
         
             
                # and also expand out future and dynamic array formulas.
         
     | 
| 
         @@ -1758,7 +1707,7 @@ module Writexlsx 
     | 
|
| 
       1758 
1707 
     | 
    
         
             
                # The outline_settings() method is used to control the appearance of
         
     | 
| 
       1759 
1708 
     | 
    
         
             
                # outlines in Excel.
         
     | 
| 
       1760 
1709 
     | 
    
         
             
                #
         
     | 
| 
       1761 
     | 
    
         
            -
                def outline_settings(visible = 1, symbols_below = 1, symbols_right = 1, auto_style =  
     | 
| 
      
 1710 
     | 
    
         
            +
                def outline_settings(visible = 1, symbols_below = 1, symbols_right = 1, auto_style = false)
         
     | 
| 
       1762 
1711 
     | 
    
         
             
                  @outline_on    = visible
         
     | 
| 
       1763 
1712 
     | 
    
         
             
                  @outline_below = symbols_below
         
     | 
| 
       1764 
1713 
     | 
    
         
             
                  @outline_right = symbols_right
         
     | 
| 
         @@ -1804,14 +1753,15 @@ module Writexlsx 
     | 
|
| 
       1804 
1753 
     | 
    
         
             
                    _tip                 = tip
         
     | 
| 
       1805 
1754 
     | 
    
         
             
                    _ignore_write_string = ignore_write_string
         
     | 
| 
       1806 
1755 
     | 
    
         
             
                  end
         
     | 
| 
       1807 
     | 
    
         
            -
             
     | 
| 
      
 1756 
     | 
    
         
            +
             
     | 
| 
      
 1757 
     | 
    
         
            +
                  _format, _str = _str, _format if _str.respond_to?(:xf_index) || (_format && !_format.respond_to?(:xf_index))
         
     | 
| 
       1808 
1758 
     | 
    
         
             
                  raise WriteXLSXInsufficientArgumentError if [_row, _col, _url].include?(nil)
         
     | 
| 
       1809 
1759 
     | 
    
         | 
| 
       1810 
1760 
     | 
    
         
             
                  # Check that row and col are valid and store max and min values
         
     | 
| 
       1811 
1761 
     | 
    
         
             
                  check_dimensions(_row, _col)
         
     | 
| 
       1812 
1762 
     | 
    
         
             
                  store_row_col_max_min_values(_row, _col)
         
     | 
| 
       1813 
1763 
     | 
    
         | 
| 
       1814 
     | 
    
         
            -
                  hyperlink = Hyperlink.factory(_url, _str, _tip)
         
     | 
| 
      
 1764 
     | 
    
         
            +
                  hyperlink = Hyperlink.factory(_url, _str, _tip, @max_url_length)
         
     | 
| 
       1815 
1765 
     | 
    
         
             
                  store_hyperlink(_row, _col, hyperlink)
         
     | 
| 
       1816 
1766 
     | 
    
         | 
| 
       1817 
1767 
     | 
    
         
             
                  raise "URL '#{url}' added but URL exceeds Excel's limit of 65,530 URLs per worksheet." if hyperlinks_count > 65_530
         
     | 
| 
         @@ -1914,10 +1864,10 @@ module Writexlsx 
     | 
|
| 
       1914 
1864 
     | 
    
         
             
                  x_offset = _chart.x_offset if ptrue?(_chart.x_offset)
         
     | 
| 
       1915 
1865 
     | 
    
         
             
                  y_offset = _chart.y_offset if ptrue?(_chart.y_offset)
         
     | 
| 
       1916 
1866 
     | 
    
         | 
| 
       1917 
     | 
    
         
            -
                  @charts <<  
     | 
| 
      
 1867 
     | 
    
         
            +
                  @charts << InsertedChart.new(
         
     | 
| 
       1918 
1868 
     | 
    
         
             
                    _row,    _col,    _chart, x_offset,    y_offset,
         
     | 
| 
       1919 
1869 
     | 
    
         
             
                    x_scale, y_scale, anchor, description, decorative
         
     | 
| 
       1920 
     | 
    
         
            -
                   
     | 
| 
      
 1870 
     | 
    
         
            +
                  )
         
     | 
| 
       1921 
1871 
     | 
    
         
             
                end
         
     | 
| 
       1922 
1872 
     | 
    
         | 
| 
       1923 
1873 
     | 
    
         
             
                #
         
     | 
| 
         @@ -1959,10 +1909,10 @@ module Writexlsx 
     | 
|
| 
       1959 
1909 
     | 
    
         
             
                  y_scale  ||= 1
         
     | 
| 
       1960 
1910 
     | 
    
         
             
                  anchor   ||= 2
         
     | 
| 
       1961 
1911 
     | 
    
         | 
| 
       1962 
     | 
    
         
            -
                  @images <<  
     | 
| 
      
 1912 
     | 
    
         
            +
                  @images << Image.new(
         
     | 
| 
       1963 
1913 
     | 
    
         
             
                    _row, _col, _image, x_offset, y_offset,
         
     | 
| 
       1964 
1914 
     | 
    
         
             
                    x_scale, y_scale, url, tip, anchor, description, decorative
         
     | 
| 
       1965 
     | 
    
         
            -
                   
     | 
| 
      
 1915 
     | 
    
         
            +
                  )
         
     | 
| 
       1966 
1916 
     | 
    
         
             
                end
         
     | 
| 
       1967 
1917 
     | 
    
         | 
| 
       1968 
1918 
     | 
    
         
             
                #
         
     | 
| 
         @@ -2005,18 +1955,19 @@ module Writexlsx 
     | 
|
| 
       2005 
1955 
     | 
    
         
             
                  end
         
     | 
| 
       2006 
1956 
     | 
    
         | 
| 
       2007 
1957 
     | 
    
         
             
                  # Get the image properties, mainly for the type and checksum.
         
     | 
| 
       2008 
     | 
    
         
            -
                   
     | 
| 
       2009 
     | 
    
         
            -
             
     | 
| 
       2010 
     | 
    
         
            -
                   
     | 
| 
      
 1958 
     | 
    
         
            +
                  image_property = ImageProperty.new(
         
     | 
| 
      
 1959 
     | 
    
         
            +
                    image, description: description, decorative: decorative
         
     | 
| 
      
 1960 
     | 
    
         
            +
                  )
         
     | 
| 
      
 1961 
     | 
    
         
            +
                  @workbook.store_image_types(image_property.type)
         
     | 
| 
       2011 
1962 
     | 
    
         | 
| 
       2012 
1963 
     | 
    
         
             
                  # Check for duplicate images.
         
     | 
| 
       2013 
     | 
    
         
            -
                  image_index = @embedded_image_indexes[md5]
         
     | 
| 
      
 1964 
     | 
    
         
            +
                  image_index = @embedded_image_indexes[image_property.md5]
         
     | 
| 
       2014 
1965 
     | 
    
         | 
| 
       2015 
1966 
     | 
    
         
             
                  unless ptrue?(image_index)
         
     | 
| 
       2016 
     | 
    
         
            -
                    @workbook.embedded_images <<  
     | 
| 
      
 1967 
     | 
    
         
            +
                    @workbook.embedded_images << image_property
         
     | 
| 
       2017 
1968 
     | 
    
         | 
| 
       2018 
1969 
     | 
    
         
             
                    image_index = @workbook.embedded_images.size
         
     | 
| 
       2019 
     | 
    
         
            -
                    @embedded_image_indexes[md5] = image_index
         
     | 
| 
      
 1970 
     | 
    
         
            +
                    @embedded_image_indexes[image_property.md5] = image_index
         
     | 
| 
       2020 
1971 
     | 
    
         
             
                  end
         
     | 
| 
       2021 
1972 
     | 
    
         | 
| 
       2022 
1973 
     | 
    
         
             
                  # Write the cell placeholder.
         
     | 
| 
         @@ -2024,6 +1975,76 @@ module Writexlsx 
     | 
|
| 
       2024 
1975 
     | 
    
         
             
                  @has_embedded_images = true
         
     | 
| 
       2025 
1976 
     | 
    
         
             
                end
         
     | 
| 
       2026 
1977 
     | 
    
         | 
| 
      
 1978 
     | 
    
         
            +
                #
         
     | 
| 
      
 1979 
     | 
    
         
            +
                # :call-seq:
         
     | 
| 
      
 1980 
     | 
    
         
            +
                #   insert_shape(row, col, shape [ , x, y, x_scale, y_scale ])
         
     | 
| 
      
 1981 
     | 
    
         
            +
                #
         
     | 
| 
      
 1982 
     | 
    
         
            +
                # Insert a shape into the worksheet.
         
     | 
| 
      
 1983 
     | 
    
         
            +
                #
         
     | 
| 
      
 1984 
     | 
    
         
            +
                def insert_shape(
         
     | 
| 
      
 1985 
     | 
    
         
            +
                      row_start, column_start, shape = nil, x_offset = nil, y_offset = nil,
         
     | 
| 
      
 1986 
     | 
    
         
            +
                      x_scale = nil, y_scale = nil, anchor = nil
         
     | 
| 
      
 1987 
     | 
    
         
            +
                    )
         
     | 
| 
      
 1988 
     | 
    
         
            +
                  # Check for a cell reference in A1 notation and substitute row and column.
         
     | 
| 
      
 1989 
     | 
    
         
            +
                  if (row_col_array = row_col_notation(row_start))
         
     | 
| 
      
 1990 
     | 
    
         
            +
                    _row_start, _column_start = row_col_array
         
     | 
| 
      
 1991 
     | 
    
         
            +
                    _shape    = column_start
         
     | 
| 
      
 1992 
     | 
    
         
            +
                    _x_offset = shape
         
     | 
| 
      
 1993 
     | 
    
         
            +
                    _y_offset = x_offset
         
     | 
| 
      
 1994 
     | 
    
         
            +
                    _x_scale  = y_offset
         
     | 
| 
      
 1995 
     | 
    
         
            +
                    _y_scale  = x_scale
         
     | 
| 
      
 1996 
     | 
    
         
            +
                    _anchor   = y_scale
         
     | 
| 
      
 1997 
     | 
    
         
            +
                  else
         
     | 
| 
      
 1998 
     | 
    
         
            +
                    _row_start = row_start
         
     | 
| 
      
 1999 
     | 
    
         
            +
                    _column_start = column_start
         
     | 
| 
      
 2000 
     | 
    
         
            +
                    _shape = shape
         
     | 
| 
      
 2001 
     | 
    
         
            +
                    _x_offset = x_offset
         
     | 
| 
      
 2002 
     | 
    
         
            +
                    _y_offset = y_offset
         
     | 
| 
      
 2003 
     | 
    
         
            +
                    _x_scale = x_scale
         
     | 
| 
      
 2004 
     | 
    
         
            +
                    _y_scale = y_scale
         
     | 
| 
      
 2005 
     | 
    
         
            +
                    _anchor = anchor
         
     | 
| 
      
 2006 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2007 
     | 
    
         
            +
                  raise "Insufficient arguments in insert_shape()" if [_row_start, _column_start, _shape].include?(nil)
         
     | 
| 
      
 2008 
     | 
    
         
            +
             
     | 
| 
      
 2009 
     | 
    
         
            +
                  _shape.set_position(
         
     | 
| 
      
 2010 
     | 
    
         
            +
                    _row_start, _column_start, _x_offset, _y_offset,
         
     | 
| 
      
 2011 
     | 
    
         
            +
                    _x_scale, _y_scale, _anchor
         
     | 
| 
      
 2012 
     | 
    
         
            +
                  )
         
     | 
| 
      
 2013 
     | 
    
         
            +
                  # Assign a shape ID.
         
     | 
| 
      
 2014 
     | 
    
         
            +
                  while true
         
     | 
| 
      
 2015 
     | 
    
         
            +
                    id = _shape.id || 0
         
     | 
| 
      
 2016 
     | 
    
         
            +
                    used = @shape_hash[id]
         
     | 
| 
      
 2017 
     | 
    
         
            +
             
     | 
| 
      
 2018 
     | 
    
         
            +
                    # Test if shape ID is already used. Otherwise assign a new one.
         
     | 
| 
      
 2019 
     | 
    
         
            +
                    if !used && id != 0
         
     | 
| 
      
 2020 
     | 
    
         
            +
                      break
         
     | 
| 
      
 2021 
     | 
    
         
            +
                    else
         
     | 
| 
      
 2022 
     | 
    
         
            +
                      @last_shape_id += 1
         
     | 
| 
      
 2023 
     | 
    
         
            +
                      _shape.id = @last_shape_id
         
     | 
| 
      
 2024 
     | 
    
         
            +
                    end
         
     | 
| 
      
 2025 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2026 
     | 
    
         
            +
             
     | 
| 
      
 2027 
     | 
    
         
            +
                  # Allow lookup of entry into shape array by shape ID.
         
     | 
| 
      
 2028 
     | 
    
         
            +
                  @shape_hash[_shape.id] = _shape.element = @shapes.size
         
     | 
| 
      
 2029 
     | 
    
         
            +
             
     | 
| 
      
 2030 
     | 
    
         
            +
                  insert = if ptrue?(_shape.stencil)
         
     | 
| 
      
 2031 
     | 
    
         
            +
                             # Insert a copy of the shape, not a reference so that the shape is
         
     | 
| 
      
 2032 
     | 
    
         
            +
                             # used as a stencil. Previously stamped copies don't get modified
         
     | 
| 
      
 2033 
     | 
    
         
            +
                             # if the stencil is modified.
         
     | 
| 
      
 2034 
     | 
    
         
            +
                             _shape.dup
         
     | 
| 
      
 2035 
     | 
    
         
            +
                           else
         
     | 
| 
      
 2036 
     | 
    
         
            +
                             _shape
         
     | 
| 
      
 2037 
     | 
    
         
            +
                           end
         
     | 
| 
      
 2038 
     | 
    
         
            +
             
     | 
| 
      
 2039 
     | 
    
         
            +
                  # For connectors change x/y coords based on location of connected shapes.
         
     | 
| 
      
 2040 
     | 
    
         
            +
                  insert.auto_locate_connectors(@shapes, @shape_hash)
         
     | 
| 
      
 2041 
     | 
    
         
            +
             
     | 
| 
      
 2042 
     | 
    
         
            +
                  # Insert a link to the shape on the list of shapes. Connection to
         
     | 
| 
      
 2043 
     | 
    
         
            +
                  # the parent shape is maintained.
         
     | 
| 
      
 2044 
     | 
    
         
            +
                  @shapes << insert
         
     | 
| 
      
 2045 
     | 
    
         
            +
                  insert
         
     | 
| 
      
 2046 
     | 
    
         
            +
                end
         
     | 
| 
      
 2047 
     | 
    
         
            +
             
     | 
| 
       2027 
2048 
     | 
    
         
             
                #
         
     | 
| 
       2028 
2049 
     | 
    
         
             
                # :call-seq:
         
     | 
| 
       2029 
2050 
     | 
    
         
             
                #   repeat_formula(row, column, formula [ , format ])
         
     | 
| 
         @@ -2087,9 +2108,6 @@ module Writexlsx 
     | 
|
| 
       2087 
2108 
     | 
    
         
             
                  level  = args[4] || 0
         
     | 
| 
       2088 
2109 
     | 
    
         
             
                  collapsed = args[5] || 0
         
     | 
| 
       2089 
2110 
     | 
    
         | 
| 
       2090 
     | 
    
         
            -
                  # Get the default row height.
         
     | 
| 
       2091 
     | 
    
         
            -
                  default_height = @default_row_height
         
     | 
| 
       2092 
     | 
    
         
            -
             
     | 
| 
       2093 
2111 
     | 
    
         
             
                  # Use min col in check_dimensions. Default to 0 if undefined.
         
     | 
| 
       2094 
2112 
     | 
    
         
             
                  min_col = @dim_colmin || 0
         
     | 
| 
       2095 
2113 
     | 
    
         | 
| 
         @@ -2097,12 +2115,12 @@ module Writexlsx 
     | 
|
| 
       2097 
2115 
     | 
    
         
             
                  check_dimensions(row, min_col)
         
     | 
| 
       2098 
2116 
     | 
    
         
             
                  store_row_col_max_min_values(row, min_col)
         
     | 
| 
       2099 
2117 
     | 
    
         | 
| 
       2100 
     | 
    
         
            -
                  height ||=  
     | 
| 
      
 2118 
     | 
    
         
            +
                  height ||= @default_row_height
         
     | 
| 
       2101 
2119 
     | 
    
         | 
| 
       2102 
2120 
     | 
    
         
             
                  # If the height is 0 the row is hidden and the height is the default.
         
     | 
| 
       2103 
2121 
     | 
    
         
             
                  if height == 0
         
     | 
| 
       2104 
2122 
     | 
    
         
             
                    hidden = 1
         
     | 
| 
       2105 
     | 
    
         
            -
                    height =  
     | 
| 
      
 2123 
     | 
    
         
            +
                    height = @default_row_height
         
     | 
| 
       2106 
2124 
     | 
    
         
             
                  end
         
     | 
| 
       2107 
2125 
     | 
    
         | 
| 
       2108 
2126 
     | 
    
         
             
                  # Set the limits for the outline levels (0 <= x <= 7).
         
     | 
| 
         @@ -2311,8 +2329,11 @@ module Writexlsx 
     | 
|
| 
       2311 
2329 
     | 
    
         
             
                    _col = col
         
     | 
| 
       2312 
2330 
     | 
    
         
             
                    _properties = properties
         
     | 
| 
       2313 
2331 
     | 
    
         
             
                  end
         
     | 
| 
       2314 
     | 
    
         
            -
             
     | 
| 
       2315 
     | 
    
         
            -
                  @ 
     | 
| 
      
 2332 
     | 
    
         
            +
             
     | 
| 
      
 2333 
     | 
    
         
            +
                  @buttons_array << Writexlsx::Package::Button.new(
         
     | 
| 
      
 2334 
     | 
    
         
            +
                    self, _row, _col, _properties, @default_row_pixels, @buttons_array.size + 1
         
     | 
| 
      
 2335 
     | 
    
         
            +
                  )
         
     | 
| 
      
 2336 
     | 
    
         
            +
                  @has_vml = true
         
     | 
| 
       2316 
2337 
     | 
    
         
             
                end
         
     | 
| 
       2317 
2338 
     | 
    
         | 
| 
       2318 
2339 
     | 
    
         
             
                #
         
     | 
| 
         @@ -2415,7 +2436,7 @@ module Writexlsx 
     | 
|
| 
       2415 
2436 
     | 
    
         | 
| 
       2416 
2437 
     | 
    
         
             
                  tokens = extract_filter_tokens(expression)
         
     | 
| 
       2417 
2438 
     | 
    
         | 
| 
       2418 
     | 
    
         
            -
                  raise "Incorrect number of tokens in expression '#{expression}'" unless  
     | 
| 
      
 2439 
     | 
    
         
            +
                  raise "Incorrect number of tokens in expression '#{expression}'" unless [3, 7].include?(tokens.size)
         
     | 
| 
       2419 
2440 
     | 
    
         | 
| 
       2420 
2441 
     | 
    
         
             
                  tokens = parse_filter_expression(expression, tokens)
         
     | 
| 
       2421 
2442 
     | 
    
         | 
| 
         @@ -2494,7 +2515,7 @@ module Writexlsx 
     | 
|
| 
       2494 
2515 
     | 
    
         
             
                end
         
     | 
| 
       2495 
2516 
     | 
    
         | 
| 
       2496 
2517 
     | 
    
         
             
                def has_header_vml?  # :nodoc:
         
     | 
| 
       2497 
     | 
    
         
            -
                  @ 
     | 
| 
      
 2518 
     | 
    
         
            +
                  !(@header_images.empty? && @footer_images.empty?)
         
     | 
| 
       2498 
2519 
     | 
    
         
             
                end
         
     | 
| 
       2499 
2520 
     | 
    
         | 
| 
       2500 
2521 
     | 
    
         
             
                def has_comments? # :nodoc:
         
     | 
| 
         @@ -2509,49 +2530,29 @@ module Writexlsx 
     | 
|
| 
       2509 
2530 
     | 
    
         
             
                  !!@is_chartsheet
         
     | 
| 
       2510 
2531 
     | 
    
         
             
                end
         
     | 
| 
       2511 
2532 
     | 
    
         | 
| 
       2512 
     | 
    
         
            -
                def set_external_vml_links(vml_drawing_id) # :nodoc:
         
     | 
| 
       2513 
     | 
    
         
            -
                  @external_vml_links <<
         
     | 
| 
       2514 
     | 
    
         
            -
                    ['/vmlDrawing', "../drawings/vmlDrawing#{vml_drawing_id}.vml"]
         
     | 
| 
       2515 
     | 
    
         
            -
                end
         
     | 
| 
       2516 
     | 
    
         
            -
             
     | 
| 
       2517 
     | 
    
         
            -
                def set_external_comment_links(comment_id) # :nodoc:
         
     | 
| 
       2518 
     | 
    
         
            -
                  @external_comment_links <<
         
     | 
| 
       2519 
     | 
    
         
            -
                    ['/comments',   "../comments#{comment_id}.xml"]
         
     | 
| 
       2520 
     | 
    
         
            -
                end
         
     | 
| 
       2521 
     | 
    
         
            -
             
     | 
| 
       2522 
2533 
     | 
    
         
             
                #
         
     | 
| 
       2523 
2534 
     | 
    
         
             
                # Set up chart/drawings.
         
     | 
| 
       2524 
2535 
     | 
    
         
             
                #
         
     | 
| 
       2525 
2536 
     | 
    
         
             
                def prepare_chart(index, chart_id, drawing_id) # :nodoc:
         
     | 
| 
       2526 
2537 
     | 
    
         
             
                  drawing_type = 1
         
     | 
| 
       2527 
2538 
     | 
    
         | 
| 
       2528 
     | 
    
         
            -
                   
     | 
| 
       2529 
     | 
    
         
            -
                   
     | 
| 
       2530 
     | 
    
         
            -
             
     | 
| 
       2531 
     | 
    
         
            -
                  chart.id = chart_id - 1
         
     | 
| 
       2532 
     | 
    
         
            -
                  x_scale ||= 0
         
     | 
| 
       2533 
     | 
    
         
            -
                  y_scale ||= 0
         
     | 
| 
      
 2539 
     | 
    
         
            +
                  inserted_chart = @charts[index]
         
     | 
| 
      
 2540 
     | 
    
         
            +
                  inserted_chart.chart.id = chart_id - 1
         
     | 
| 
       2534 
2541 
     | 
    
         | 
| 
       2535 
     | 
    
         
            -
                   
     | 
| 
       2536 
     | 
    
         
            -
                  width  = chart.width  if ptrue?(chart.width)
         
     | 
| 
       2537 
     | 
    
         
            -
                  height = chart.height if ptrue?(chart.height)
         
     | 
| 
       2538 
     | 
    
         
            -
             
     | 
| 
       2539 
     | 
    
         
            -
                  width  = (0.5 + (width  * x_scale)).to_i
         
     | 
| 
       2540 
     | 
    
         
            -
                  height = (0.5 + (height * y_scale)).to_i
         
     | 
| 
       2541 
     | 
    
         
            -
             
     | 
| 
       2542 
     | 
    
         
            -
                  dimensions = position_object_emus(col, row, x_offset, y_offset, width, height, anchor)
         
     | 
| 
       2543 
     | 
    
         
            -
             
     | 
| 
       2544 
     | 
    
         
            -
                  # Set the chart name for the embedded object if it has been specified.
         
     | 
| 
       2545 
     | 
    
         
            -
                  name = chart.name
         
     | 
| 
      
 2542 
     | 
    
         
            +
                  dimensions = position_object_emus(inserted_chart)
         
     | 
| 
       2546 
2543 
     | 
    
         | 
| 
       2547 
2544 
     | 
    
         
             
                  # Create a Drawing object to use with worksheet unless one already exists.
         
     | 
| 
       2548 
     | 
    
         
            -
                  drawing = Drawing.new( 
     | 
| 
      
 2545 
     | 
    
         
            +
                  drawing = Drawing.new(
         
     | 
| 
      
 2546 
     | 
    
         
            +
                    drawing_type, dimensions, 0, 0, nil, inserted_chart.anchor,
         
     | 
| 
      
 2547 
     | 
    
         
            +
                    drawing_rel_index, 0, nil, inserted_chart.name,
         
     | 
| 
      
 2548 
     | 
    
         
            +
                    inserted_chart.description, inserted_chart.decorative
         
     | 
| 
      
 2549 
     | 
    
         
            +
                  )
         
     | 
| 
       2549 
2550 
     | 
    
         
             
                  if drawings?
         
     | 
| 
       2550 
2551 
     | 
    
         
             
                    @drawings.add_drawing_object(drawing)
         
     | 
| 
       2551 
2552 
     | 
    
         
             
                  else
         
     | 
| 
       2552 
2553 
     | 
    
         
             
                    @drawings = Drawings.new
         
     | 
| 
       2553 
2554 
     | 
    
         
             
                    @drawings.add_drawing_object(drawing)
         
     | 
| 
       2554 
     | 
    
         
            -
                    @drawings.embedded =  
     | 
| 
      
 2555 
     | 
    
         
            +
                    @drawings.embedded = true
         
     | 
| 
       2555 
2556 
     | 
    
         | 
| 
       2556 
2557 
     | 
    
         
             
                    @external_drawing_links << ['/drawing', "../drawings/drawing#{drawing_id}.xml"]
         
     | 
| 
       2557 
2558 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -2589,85 +2590,6 @@ module Writexlsx 
     | 
|
| 
       2589 
2590 
     | 
    
         
             
                  data
         
     | 
| 
       2590 
2591 
     | 
    
         
             
                end
         
     | 
| 
       2591 
2592 
     | 
    
         | 
| 
       2592 
     | 
    
         
            -
                #
         
     | 
| 
       2593 
     | 
    
         
            -
                # Calculate the vertices that define the position of a graphical object within
         
     | 
| 
       2594 
     | 
    
         
            -
                # the worksheet in pixels.
         
     | 
| 
       2595 
     | 
    
         
            -
                #
         
     | 
| 
       2596 
     | 
    
         
            -
                def position_object_pixels(col_start, row_start, x1, y1, width, height, anchor = nil) # :nodoc:
         
     | 
| 
       2597 
     | 
    
         
            -
                  # Adjust start column for negative offsets.
         
     | 
| 
       2598 
     | 
    
         
            -
                  while x1 < 0 && col_start > 0
         
     | 
| 
       2599 
     | 
    
         
            -
                    x1 += size_col(col_start - 1)
         
     | 
| 
       2600 
     | 
    
         
            -
                    col_start -= 1
         
     | 
| 
       2601 
     | 
    
         
            -
                  end
         
     | 
| 
       2602 
     | 
    
         
            -
             
     | 
| 
       2603 
     | 
    
         
            -
                  # Adjust start row for negative offsets.
         
     | 
| 
       2604 
     | 
    
         
            -
                  while y1 < 0 && row_start > 0
         
     | 
| 
       2605 
     | 
    
         
            -
                    y1 += size_row(row_start - 1)
         
     | 
| 
       2606 
     | 
    
         
            -
                    row_start -= 1
         
     | 
| 
       2607 
     | 
    
         
            -
                  end
         
     | 
| 
       2608 
     | 
    
         
            -
             
     | 
| 
       2609 
     | 
    
         
            -
                  # Ensure that the image isn't shifted off the page at top left.
         
     | 
| 
       2610 
     | 
    
         
            -
                  x1 = 0 if x1 < 0
         
     | 
| 
       2611 
     | 
    
         
            -
                  y1 = 0 if y1 < 0
         
     | 
| 
       2612 
     | 
    
         
            -
             
     | 
| 
       2613 
     | 
    
         
            -
                  # Calculate the absolute x offset of the top-left vertex.
         
     | 
| 
       2614 
     | 
    
         
            -
                  x_abs = if @col_size_changed
         
     | 
| 
       2615 
     | 
    
         
            -
                            (0..col_start - 1).inject(0) { |sum, col| sum += size_col(col, anchor) }
         
     | 
| 
       2616 
     | 
    
         
            -
                          else
         
     | 
| 
       2617 
     | 
    
         
            -
                            # Optimisation for when the column widths haven't changed.
         
     | 
| 
       2618 
     | 
    
         
            -
                            @default_col_pixels * col_start
         
     | 
| 
       2619 
     | 
    
         
            -
                          end
         
     | 
| 
       2620 
     | 
    
         
            -
                  x_abs += x1
         
     | 
| 
       2621 
     | 
    
         
            -
             
     | 
| 
       2622 
     | 
    
         
            -
                  # Calculate the absolute y offset of the top-left vertex.
         
     | 
| 
       2623 
     | 
    
         
            -
                  # Store the column change to allow optimisations.
         
     | 
| 
       2624 
     | 
    
         
            -
                  y_abs = if @row_size_changed
         
     | 
| 
       2625 
     | 
    
         
            -
                            (0..row_start - 1).inject(0) { |sum, row| sum += size_row(row, anchor) }
         
     | 
| 
       2626 
     | 
    
         
            -
                          else
         
     | 
| 
       2627 
     | 
    
         
            -
                            # Optimisation for when the row heights haven't changed.
         
     | 
| 
       2628 
     | 
    
         
            -
                            @default_row_pixels * row_start
         
     | 
| 
       2629 
     | 
    
         
            -
                          end
         
     | 
| 
       2630 
     | 
    
         
            -
                  y_abs += y1
         
     | 
| 
       2631 
     | 
    
         
            -
             
     | 
| 
       2632 
     | 
    
         
            -
                  # Adjust start column for offsets that are greater than the col width.
         
     | 
| 
       2633 
     | 
    
         
            -
                  while x1 >= size_col(col_start, anchor)
         
     | 
| 
       2634 
     | 
    
         
            -
                    x1 -= size_col(col_start)
         
     | 
| 
       2635 
     | 
    
         
            -
                    col_start += 1
         
     | 
| 
       2636 
     | 
    
         
            -
                  end
         
     | 
| 
       2637 
     | 
    
         
            -
             
     | 
| 
       2638 
     | 
    
         
            -
                  # Adjust start row for offsets that are greater than the row height.
         
     | 
| 
       2639 
     | 
    
         
            -
                  while y1 >= size_row(row_start, anchor)
         
     | 
| 
       2640 
     | 
    
         
            -
                    y1 -= size_row(row_start)
         
     | 
| 
       2641 
     | 
    
         
            -
                    row_start += 1
         
     | 
| 
       2642 
     | 
    
         
            -
                  end
         
     | 
| 
       2643 
     | 
    
         
            -
             
     | 
| 
       2644 
     | 
    
         
            -
                  # Initialise end cell to the same as the start cell.
         
     | 
| 
       2645 
     | 
    
         
            -
                  col_end = col_start
         
     | 
| 
       2646 
     | 
    
         
            -
                  row_end = row_start
         
     | 
| 
       2647 
     | 
    
         
            -
             
     | 
| 
       2648 
     | 
    
         
            -
                  # Only offset the image in the cell if the row/col isn't hidden.
         
     | 
| 
       2649 
     | 
    
         
            -
                  width  += x1 if size_col(col_start, anchor) > 0
         
     | 
| 
       2650 
     | 
    
         
            -
                  height += y1 if size_row(row_start, anchor) > 0
         
     | 
| 
       2651 
     | 
    
         
            -
             
     | 
| 
       2652 
     | 
    
         
            -
                  # Subtract the underlying cell widths to find the end cell of the object.
         
     | 
| 
       2653 
     | 
    
         
            -
                  while width >= size_col(col_end, anchor)
         
     | 
| 
       2654 
     | 
    
         
            -
                    width -= size_col(col_end, anchor)
         
     | 
| 
       2655 
     | 
    
         
            -
                    col_end += 1
         
     | 
| 
       2656 
     | 
    
         
            -
                  end
         
     | 
| 
       2657 
     | 
    
         
            -
             
     | 
| 
       2658 
     | 
    
         
            -
                  # Subtract the underlying cell heights to find the end cell of the object.
         
     | 
| 
       2659 
     | 
    
         
            -
                  while height >= size_row(row_end, anchor)
         
     | 
| 
       2660 
     | 
    
         
            -
                    height -= size_row(row_end, anchor)
         
     | 
| 
       2661 
     | 
    
         
            -
                    row_end += 1
         
     | 
| 
       2662 
     | 
    
         
            -
                  end
         
     | 
| 
       2663 
     | 
    
         
            -
             
     | 
| 
       2664 
     | 
    
         
            -
                  # The end vertices are whatever is left from the width and height.
         
     | 
| 
       2665 
     | 
    
         
            -
                  x2 = width
         
     | 
| 
       2666 
     | 
    
         
            -
                  y2 = height
         
     | 
| 
       2667 
     | 
    
         
            -
             
     | 
| 
       2668 
     | 
    
         
            -
                  [col_start, row_start, x1, y1, col_end, row_end, x2, y2, x_abs, y_abs]
         
     | 
| 
       2669 
     | 
    
         
            -
                end
         
     | 
| 
       2670 
     | 
    
         
            -
             
     | 
| 
       2671 
2593 
     | 
    
         
             
                def comments_visible? # :nodoc:
         
     | 
| 
       2672 
2594 
     | 
    
         
             
                  !!@comments_visible
         
     | 
| 
       2673 
2595 
     | 
    
         
             
                end
         
     | 
| 
         @@ -2725,7 +2647,7 @@ module Writexlsx 
     | 
|
| 
       2725 
2647 
     | 
    
         
             
                  if index.to_s =~ /^#([0-9A-F]{6})$/i
         
     | 
| 
       2726 
2648 
     | 
    
         
             
                    "FF#{::Regexp.last_match(1).upcase}"
         
     | 
| 
       2727 
2649 
     | 
    
         
             
                  else
         
     | 
| 
       2728 
     | 
    
         
            -
                    "FF#{ 
     | 
| 
      
 2650 
     | 
    
         
            +
                    "FF#{palette_color_from_index(index)}"
         
     | 
| 
       2729 
2651 
     | 
    
         
             
                  end
         
     | 
| 
       2730 
2652 
     | 
    
         
             
                end
         
     | 
| 
       2731 
2653 
     | 
    
         | 
| 
         @@ -2872,42 +2794,242 @@ module Writexlsx 
     | 
|
| 
       2872 
2794 
     | 
    
         
             
                  @has_embedded_images
         
     | 
| 
       2873 
2795 
     | 
    
         
             
                end
         
     | 
| 
       2874 
2796 
     | 
    
         | 
| 
       2875 
     | 
    
         
            -
                 
     | 
| 
      
 2797 
     | 
    
         
            +
                # Check that some image or drawing needs to be processed.
         
     | 
| 
      
 2798 
     | 
    
         
            +
                def some_image_or_drawing_to_be_processed?
         
     | 
| 
      
 2799 
     | 
    
         
            +
                  charts.size + images.size + shapes.size + header_images.size + footer_images.size + (background_image ? 1 : 0) == 0
         
     | 
| 
      
 2800 
     | 
    
         
            +
                end
         
     | 
| 
       2876 
2801 
     | 
    
         | 
| 
       2877 
     | 
    
         
            -
                 
     | 
| 
       2878 
     | 
    
         
            -
             
     | 
| 
       2879 
     | 
    
         
            -
                #
         
     | 
| 
       2880 
     | 
    
         
            -
                def compare_col_info(col_options, previous_options)
         
     | 
| 
       2881 
     | 
    
         
            -
                  if !col_options.width.nil? != !previous_options.width.nil?
         
     | 
| 
       2882 
     | 
    
         
            -
                    return nil
         
     | 
| 
       2883 
     | 
    
         
            -
                  end
         
     | 
| 
       2884 
     | 
    
         
            -
                  if col_options.width && previous_options.width &&
         
     | 
| 
       2885 
     | 
    
         
            -
                     col_options.width != previous_options.width
         
     | 
| 
       2886 
     | 
    
         
            -
                    return nil
         
     | 
| 
       2887 
     | 
    
         
            -
                  end
         
     | 
| 
      
 2802 
     | 
    
         
            +
                def prepare_drawings(drawing_id, chart_ref_id, image_ref_id, image_ids, header_image_ids, background_ids)
         
     | 
| 
      
 2803 
     | 
    
         
            +
                  has_drawings = false
         
     | 
| 
       2888 
2804 
     | 
    
         | 
| 
       2889 
     | 
    
         
            -
                   
     | 
| 
       2890 
     | 
    
         
            -
             
     | 
| 
       2891 
     | 
    
         
            -
                  end
         
     | 
| 
       2892 
     | 
    
         
            -
                  if col_options.format && previous_options.format &&
         
     | 
| 
       2893 
     | 
    
         
            -
                     col_options.format != previous_options.format
         
     | 
| 
       2894 
     | 
    
         
            -
                    return nil
         
     | 
| 
       2895 
     | 
    
         
            -
                  end
         
     | 
| 
      
 2805 
     | 
    
         
            +
                  # Check that some image or drawing needs to be processed.
         
     | 
| 
      
 2806 
     | 
    
         
            +
                  unless some_image_or_drawing_to_be_processed?
         
     | 
| 
       2896 
2807 
     | 
    
         | 
| 
       2897 
     | 
    
         
            -
             
     | 
| 
       2898 
     | 
    
         
            -
             
     | 
| 
       2899 
     | 
    
         
            -
             
     | 
| 
      
 2808 
     | 
    
         
            +
                    # Don't increase the drawing_id header/footer images.
         
     | 
| 
      
 2809 
     | 
    
         
            +
                    unless charts.empty? && images.empty? && shapes.empty?
         
     | 
| 
      
 2810 
     | 
    
         
            +
                      drawing_id += 1
         
     | 
| 
      
 2811 
     | 
    
         
            +
                      has_drawings = true
         
     | 
| 
      
 2812 
     | 
    
         
            +
                    end
         
     | 
| 
       2900 
2813 
     | 
    
         | 
| 
       2901 
     | 
    
         
            -
             
     | 
| 
       2902 
     | 
    
         
            -
             
     | 
| 
      
 2814 
     | 
    
         
            +
                    # Prepare the background images.
         
     | 
| 
      
 2815 
     | 
    
         
            +
                    image_ref_id = prepare_background_image(background_ids, image_ref_id)
         
     | 
| 
       2903 
2816 
     | 
    
         | 
| 
       2904 
     | 
    
         
            -
             
     | 
| 
       2905 
     | 
    
         
            -
             
     | 
| 
       2906 
     | 
    
         
            -
             
     | 
| 
       2907 
     | 
    
         
            -
             
     | 
| 
       2908 
     | 
    
         
            -
             
     | 
| 
       2909 
     | 
    
         
            -
                    #  
     | 
| 
       2910 
     | 
    
         
            -
                     
     | 
| 
      
 2817 
     | 
    
         
            +
                    # Prepare the worksheet images.
         
     | 
| 
      
 2818 
     | 
    
         
            +
                    images.each do |image|
         
     | 
| 
      
 2819 
     | 
    
         
            +
                      image_ref_id = prepare_image(image, drawing_id, image_ids, image_ref_id)
         
     | 
| 
      
 2820 
     | 
    
         
            +
                    end
         
     | 
| 
      
 2821 
     | 
    
         
            +
             
     | 
| 
      
 2822 
     | 
    
         
            +
                    # Prepare the worksheet charts.
         
     | 
| 
      
 2823 
     | 
    
         
            +
                    charts.each_with_index do |_chart, index|
         
     | 
| 
      
 2824 
     | 
    
         
            +
                      chart_ref_id += 1
         
     | 
| 
      
 2825 
     | 
    
         
            +
                      prepare_chart(index, chart_ref_id, drawing_id)
         
     | 
| 
      
 2826 
     | 
    
         
            +
                    end
         
     | 
| 
      
 2827 
     | 
    
         
            +
             
     | 
| 
      
 2828 
     | 
    
         
            +
                    # Prepare the worksheet shapes.
         
     | 
| 
      
 2829 
     | 
    
         
            +
                    shapes.each_with_index do |_shape, index|
         
     | 
| 
      
 2830 
     | 
    
         
            +
                      prepare_shape(index, drawing_id)
         
     | 
| 
      
 2831 
     | 
    
         
            +
                    end
         
     | 
| 
      
 2832 
     | 
    
         
            +
             
     | 
| 
      
 2833 
     | 
    
         
            +
                    # Prepare the header and footer images.
         
     | 
| 
      
 2834 
     | 
    
         
            +
                    [header_images, footer_images].each do |images|
         
     | 
| 
      
 2835 
     | 
    
         
            +
                      images.each do |image|
         
     | 
| 
      
 2836 
     | 
    
         
            +
                        image_ref_id = prepare_header_footer_image(
         
     | 
| 
      
 2837 
     | 
    
         
            +
                          image, header_image_ids, image_ref_id
         
     | 
| 
      
 2838 
     | 
    
         
            +
                        )
         
     | 
| 
      
 2839 
     | 
    
         
            +
                      end
         
     | 
| 
      
 2840 
     | 
    
         
            +
                    end
         
     | 
| 
      
 2841 
     | 
    
         
            +
             
     | 
| 
      
 2842 
     | 
    
         
            +
                    if has_drawings
         
     | 
| 
      
 2843 
     | 
    
         
            +
                      @workbook.drawings << drawings
         
     | 
| 
      
 2844 
     | 
    
         
            +
                    end
         
     | 
| 
      
 2845 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2846 
     | 
    
         
            +
             
     | 
| 
      
 2847 
     | 
    
         
            +
                  [drawing_id, chart_ref_id, image_ref_id]
         
     | 
| 
      
 2848 
     | 
    
         
            +
                end
         
     | 
| 
      
 2849 
     | 
    
         
            +
             
     | 
| 
      
 2850 
     | 
    
         
            +
                #
         
     | 
| 
      
 2851 
     | 
    
         
            +
                # Set the background image for the worksheet.
         
     | 
| 
      
 2852 
     | 
    
         
            +
                #
         
     | 
| 
      
 2853 
     | 
    
         
            +
                def set_background(image)
         
     | 
| 
      
 2854 
     | 
    
         
            +
                  raise "Couldn't locate #{image}: $!" unless File.exist?(image)
         
     | 
| 
      
 2855 
     | 
    
         
            +
             
     | 
| 
      
 2856 
     | 
    
         
            +
                  @background_image = ImageProperty.new(image)
         
     | 
| 
      
 2857 
     | 
    
         
            +
                end
         
     | 
| 
      
 2858 
     | 
    
         
            +
             
     | 
| 
      
 2859 
     | 
    
         
            +
                #
         
     | 
| 
      
 2860 
     | 
    
         
            +
                # Calculate the vertices that define the position of a graphical object
         
     | 
| 
      
 2861 
     | 
    
         
            +
                # within the worksheet in pixels.
         
     | 
| 
      
 2862 
     | 
    
         
            +
                #
         
     | 
| 
      
 2863 
     | 
    
         
            +
                def position_object_pixels(col_start, row_start, x1, y1, width, height, anchor = nil) # :nodoc:
         
     | 
| 
      
 2864 
     | 
    
         
            +
                  # Adjust start column for negative offsets.
         
     | 
| 
      
 2865 
     | 
    
         
            +
                  while x1 < 0 && col_start > 0
         
     | 
| 
      
 2866 
     | 
    
         
            +
                    x1 += size_col(col_start - 1)
         
     | 
| 
      
 2867 
     | 
    
         
            +
                    col_start -= 1
         
     | 
| 
      
 2868 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2869 
     | 
    
         
            +
             
     | 
| 
      
 2870 
     | 
    
         
            +
                  # Adjust start row for negative offsets.
         
     | 
| 
      
 2871 
     | 
    
         
            +
                  while y1 < 0 && row_start > 0
         
     | 
| 
      
 2872 
     | 
    
         
            +
                    y1 += size_row(row_start - 1)
         
     | 
| 
      
 2873 
     | 
    
         
            +
                    row_start -= 1
         
     | 
| 
      
 2874 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2875 
     | 
    
         
            +
             
     | 
| 
      
 2876 
     | 
    
         
            +
                  # Ensure that the image isn't shifted off the page at top left.
         
     | 
| 
      
 2877 
     | 
    
         
            +
                  x1 = 0 if x1 < 0
         
     | 
| 
      
 2878 
     | 
    
         
            +
                  y1 = 0 if y1 < 0
         
     | 
| 
      
 2879 
     | 
    
         
            +
             
     | 
| 
      
 2880 
     | 
    
         
            +
                  # Calculate the absolute x offset of the top-left vertex.
         
     | 
| 
      
 2881 
     | 
    
         
            +
                  x_abs = if @col_size_changed
         
     | 
| 
      
 2882 
     | 
    
         
            +
                            (0..(col_start - 1)).inject(0) { |sum, col| sum += size_col(col, anchor) }
         
     | 
| 
      
 2883 
     | 
    
         
            +
                          else
         
     | 
| 
      
 2884 
     | 
    
         
            +
                            # Optimisation for when the column widths haven't changed.
         
     | 
| 
      
 2885 
     | 
    
         
            +
                            DEFAULT_COL_PIXELS * col_start
         
     | 
| 
      
 2886 
     | 
    
         
            +
                          end
         
     | 
| 
      
 2887 
     | 
    
         
            +
                  x_abs += x1
         
     | 
| 
      
 2888 
     | 
    
         
            +
             
     | 
| 
      
 2889 
     | 
    
         
            +
                  # Calculate the absolute y offset of the top-left vertex.
         
     | 
| 
      
 2890 
     | 
    
         
            +
                  # Store the column change to allow optimisations.
         
     | 
| 
      
 2891 
     | 
    
         
            +
                  y_abs = if @row_size_changed
         
     | 
| 
      
 2892 
     | 
    
         
            +
                            (0..(row_start - 1)).inject(0) { |sum, row| sum += size_row(row, anchor) }
         
     | 
| 
      
 2893 
     | 
    
         
            +
                          else
         
     | 
| 
      
 2894 
     | 
    
         
            +
                            # Optimisation for when the row heights haven't changed.
         
     | 
| 
      
 2895 
     | 
    
         
            +
                            @default_row_pixels * row_start
         
     | 
| 
      
 2896 
     | 
    
         
            +
                          end
         
     | 
| 
      
 2897 
     | 
    
         
            +
                  y_abs += y1
         
     | 
| 
      
 2898 
     | 
    
         
            +
             
     | 
| 
      
 2899 
     | 
    
         
            +
                  # Adjust start column for offsets that are greater than the col width.
         
     | 
| 
      
 2900 
     | 
    
         
            +
                  while x1 >= size_col(col_start, anchor)
         
     | 
| 
      
 2901 
     | 
    
         
            +
                    x1 -= size_col(col_start)
         
     | 
| 
      
 2902 
     | 
    
         
            +
                    col_start += 1
         
     | 
| 
      
 2903 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2904 
     | 
    
         
            +
             
     | 
| 
      
 2905 
     | 
    
         
            +
                  # Adjust start row for offsets that are greater than the row height.
         
     | 
| 
      
 2906 
     | 
    
         
            +
                  while y1 >= size_row(row_start, anchor)
         
     | 
| 
      
 2907 
     | 
    
         
            +
                    y1 -= size_row(row_start)
         
     | 
| 
      
 2908 
     | 
    
         
            +
                    row_start += 1
         
     | 
| 
      
 2909 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2910 
     | 
    
         
            +
             
     | 
| 
      
 2911 
     | 
    
         
            +
                  # Initialise end cell to the same as the start cell.
         
     | 
| 
      
 2912 
     | 
    
         
            +
                  col_end = col_start
         
     | 
| 
      
 2913 
     | 
    
         
            +
                  row_end = row_start
         
     | 
| 
      
 2914 
     | 
    
         
            +
             
     | 
| 
      
 2915 
     | 
    
         
            +
                  # Only offset the image in the cell if the row/col isn't hidden.
         
     | 
| 
      
 2916 
     | 
    
         
            +
                  width  += x1 if size_col(col_start, anchor) > 0
         
     | 
| 
      
 2917 
     | 
    
         
            +
                  height += y1 if size_row(row_start, anchor) > 0
         
     | 
| 
      
 2918 
     | 
    
         
            +
             
     | 
| 
      
 2919 
     | 
    
         
            +
                  # Subtract the underlying cell widths to find the end cell of the object.
         
     | 
| 
      
 2920 
     | 
    
         
            +
                  while width >= size_col(col_end, anchor)
         
     | 
| 
      
 2921 
     | 
    
         
            +
                    width -= size_col(col_end, anchor)
         
     | 
| 
      
 2922 
     | 
    
         
            +
                    col_end += 1
         
     | 
| 
      
 2923 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2924 
     | 
    
         
            +
             
     | 
| 
      
 2925 
     | 
    
         
            +
                  # Subtract the underlying cell heights to find the end cell of the object.
         
     | 
| 
      
 2926 
     | 
    
         
            +
                  while height >= size_row(row_end, anchor)
         
     | 
| 
      
 2927 
     | 
    
         
            +
                    height -= size_row(row_end, anchor)
         
     | 
| 
      
 2928 
     | 
    
         
            +
                    row_end += 1
         
     | 
| 
      
 2929 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2930 
     | 
    
         
            +
             
     | 
| 
      
 2931 
     | 
    
         
            +
                  # The end vertices are whatever is left from the width and height.
         
     | 
| 
      
 2932 
     | 
    
         
            +
                  x2 = width
         
     | 
| 
      
 2933 
     | 
    
         
            +
                  y2 = height
         
     | 
| 
      
 2934 
     | 
    
         
            +
             
     | 
| 
      
 2935 
     | 
    
         
            +
                  [col_start, row_start, x1, y1, col_end, row_end, x2, y2, x_abs, y_abs]
         
     | 
| 
      
 2936 
     | 
    
         
            +
                end
         
     | 
| 
      
 2937 
     | 
    
         
            +
             
     | 
| 
      
 2938 
     | 
    
         
            +
                private
         
     | 
| 
      
 2939 
     | 
    
         
            +
             
     | 
| 
      
 2940 
     | 
    
         
            +
                #
         
     | 
| 
      
 2941 
     | 
    
         
            +
                # Convert the width of a cell from user's units to pixels. Excel rounds
         
     | 
| 
      
 2942 
     | 
    
         
            +
                # the column width to the nearest pixel. If the width hasn't been set
         
     | 
| 
      
 2943 
     | 
    
         
            +
                # by the user we use the default value. A hidden column is treated as
         
     | 
| 
      
 2944 
     | 
    
         
            +
                # having a width of zero unless it has the special "object_position" of
         
     | 
| 
      
 2945 
     | 
    
         
            +
                # 4 (size with cells).
         
     | 
| 
      
 2946 
     | 
    
         
            +
                #
         
     | 
| 
      
 2947 
     | 
    
         
            +
                def size_col(col, anchor = 0) # :nodoc:
         
     | 
| 
      
 2948 
     | 
    
         
            +
                  # Look up the cell value to see if it has been changed.
         
     | 
| 
      
 2949 
     | 
    
         
            +
                  if col_info[col]
         
     | 
| 
      
 2950 
     | 
    
         
            +
                    width  = col_info[col].width || @default_col_width
         
     | 
| 
      
 2951 
     | 
    
         
            +
                    hidden = col_info[col].hidden
         
     | 
| 
      
 2952 
     | 
    
         
            +
             
     | 
| 
      
 2953 
     | 
    
         
            +
                    # Convert to pixels.
         
     | 
| 
      
 2954 
     | 
    
         
            +
                    pixels = if hidden == 1 && anchor != 4
         
     | 
| 
      
 2955 
     | 
    
         
            +
                               0
         
     | 
| 
      
 2956 
     | 
    
         
            +
                             elsif width < 1
         
     | 
| 
      
 2957 
     | 
    
         
            +
                               ((width * (MAX_DIGIT_WIDTH + PADDING)) + 0.5).to_i
         
     | 
| 
      
 2958 
     | 
    
         
            +
                             else
         
     | 
| 
      
 2959 
     | 
    
         
            +
                               ((width * MAX_DIGIT_WIDTH) + 0.5).to_i + PADDING
         
     | 
| 
      
 2960 
     | 
    
         
            +
                             end
         
     | 
| 
      
 2961 
     | 
    
         
            +
                  else
         
     | 
| 
      
 2962 
     | 
    
         
            +
                    pixels = DEFAULT_COL_PIXELS
         
     | 
| 
      
 2963 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2964 
     | 
    
         
            +
                  pixels
         
     | 
| 
      
 2965 
     | 
    
         
            +
                end
         
     | 
| 
      
 2966 
     | 
    
         
            +
             
     | 
| 
      
 2967 
     | 
    
         
            +
                #
         
     | 
| 
      
 2968 
     | 
    
         
            +
                # Convert the height of a cell from user's units to pixels. If the height
         
     | 
| 
      
 2969 
     | 
    
         
            +
                # hasn't been set by the user we use the default value. A hidden row is
         
     | 
| 
      
 2970 
     | 
    
         
            +
                # treated as having a height of zero unless it has the special
         
     | 
| 
      
 2971 
     | 
    
         
            +
                # "object_position" of 4 (size with cells).
         
     | 
| 
      
 2972 
     | 
    
         
            +
                #
         
     | 
| 
      
 2973 
     | 
    
         
            +
                def size_row(row, anchor = 0) # :nodoc:
         
     | 
| 
      
 2974 
     | 
    
         
            +
                  # Look up the cell value to see if it has been changed
         
     | 
| 
      
 2975 
     | 
    
         
            +
                  if row_sizes[row]
         
     | 
| 
      
 2976 
     | 
    
         
            +
                    height, hidden = row_sizes[row]
         
     | 
| 
      
 2977 
     | 
    
         
            +
             
     | 
| 
      
 2978 
     | 
    
         
            +
                    pixels = if hidden == 1 && anchor != 4
         
     | 
| 
      
 2979 
     | 
    
         
            +
                               0
         
     | 
| 
      
 2980 
     | 
    
         
            +
                             else
         
     | 
| 
      
 2981 
     | 
    
         
            +
                               (4 / 3.0 * height).to_i
         
     | 
| 
      
 2982 
     | 
    
         
            +
                             end
         
     | 
| 
      
 2983 
     | 
    
         
            +
                  else
         
     | 
| 
      
 2984 
     | 
    
         
            +
                    pixels = (4 / 3.0 * default_row_height).to_i
         
     | 
| 
      
 2985 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2986 
     | 
    
         
            +
                  pixels
         
     | 
| 
      
 2987 
     | 
    
         
            +
                end
         
     | 
| 
      
 2988 
     | 
    
         
            +
             
     | 
| 
      
 2989 
     | 
    
         
            +
                #
         
     | 
| 
      
 2990 
     | 
    
         
            +
                # Compare adjacent column information structures.
         
     | 
| 
      
 2991 
     | 
    
         
            +
                #
         
     | 
| 
      
 2992 
     | 
    
         
            +
                def compare_col_info(col_options, previous_options)
         
     | 
| 
      
 2993 
     | 
    
         
            +
                  if !col_options.width.nil? != !previous_options.width.nil?
         
     | 
| 
      
 2994 
     | 
    
         
            +
                    return nil
         
     | 
| 
      
 2995 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2996 
     | 
    
         
            +
                  if col_options.width && previous_options.width &&
         
     | 
| 
      
 2997 
     | 
    
         
            +
                     col_options.width != previous_options.width
         
     | 
| 
      
 2998 
     | 
    
         
            +
                    return nil
         
     | 
| 
      
 2999 
     | 
    
         
            +
                  end
         
     | 
| 
      
 3000 
     | 
    
         
            +
             
     | 
| 
      
 3001 
     | 
    
         
            +
                  if !col_options.format.nil? != !previous_options.format.nil?
         
     | 
| 
      
 3002 
     | 
    
         
            +
                    return nil
         
     | 
| 
      
 3003 
     | 
    
         
            +
                  end
         
     | 
| 
      
 3004 
     | 
    
         
            +
                  if col_options.format && previous_options.format &&
         
     | 
| 
      
 3005 
     | 
    
         
            +
                     col_options.format != previous_options.format
         
     | 
| 
      
 3006 
     | 
    
         
            +
                    return nil
         
     | 
| 
      
 3007 
     | 
    
         
            +
                  end
         
     | 
| 
      
 3008 
     | 
    
         
            +
             
     | 
| 
      
 3009 
     | 
    
         
            +
                  return nil if col_options.hidden    != previous_options.hidden
         
     | 
| 
      
 3010 
     | 
    
         
            +
                  return nil if col_options.level     != previous_options.level
         
     | 
| 
      
 3011 
     | 
    
         
            +
                  return nil if col_options.collapsed != previous_options.collapsed
         
     | 
| 
      
 3012 
     | 
    
         
            +
             
     | 
| 
      
 3013 
     | 
    
         
            +
                  true
         
     | 
| 
      
 3014 
     | 
    
         
            +
                end
         
     | 
| 
      
 3015 
     | 
    
         
            +
             
     | 
| 
      
 3016 
     | 
    
         
            +
                def set_external_vml_links(vml_drawing_id) # :nodoc:
         
     | 
| 
      
 3017 
     | 
    
         
            +
                  @external_vml_links <<
         
     | 
| 
      
 3018 
     | 
    
         
            +
                    ['/vmlDrawing', "../drawings/vmlDrawing#{vml_drawing_id}.vml"]
         
     | 
| 
      
 3019 
     | 
    
         
            +
                end
         
     | 
| 
      
 3020 
     | 
    
         
            +
             
     | 
| 
      
 3021 
     | 
    
         
            +
                def set_external_comment_links(comment_id) # :nodoc:
         
     | 
| 
      
 3022 
     | 
    
         
            +
                  @external_comment_links <<
         
     | 
| 
      
 3023 
     | 
    
         
            +
                    ['/comments',   "../comments#{comment_id}.xml"]
         
     | 
| 
      
 3024 
     | 
    
         
            +
                end
         
     | 
| 
      
 3025 
     | 
    
         
            +
             
     | 
| 
      
 3026 
     | 
    
         
            +
                #
         
     | 
| 
      
 3027 
     | 
    
         
            +
                # Get the index used to address a drawing rel link.
         
     | 
| 
      
 3028 
     | 
    
         
            +
                #
         
     | 
| 
      
 3029 
     | 
    
         
            +
                def drawing_rel_index(target = nil)
         
     | 
| 
      
 3030 
     | 
    
         
            +
                  if !target
         
     | 
| 
      
 3031 
     | 
    
         
            +
                    # Undefined values for drawings like charts will always be unique.
         
     | 
| 
      
 3032 
     | 
    
         
            +
                    @drawing_rels_id += 1
         
     | 
| 
       2911 
3033 
     | 
    
         
             
                  elsif ptrue?(@drawing_rels[target])
         
     | 
| 
       2912 
3034 
     | 
    
         
             
                    @drawing_rels[target]
         
     | 
| 
       2913 
3035 
     | 
    
         
             
                  else
         
     | 
| 
         @@ -3185,12 +3307,13 @@ module Writexlsx 
     | 
|
| 
       3185 
3307 
     | 
    
         
             
                end
         
     | 
| 
       3186 
3308 
     | 
    
         | 
| 
       3187 
3309 
     | 
    
         
             
                #
         
     | 
| 
       3188 
     | 
    
         
            -
                # Calculate the vertices that define the position of a graphical object 
     | 
| 
       3189 
     | 
    
         
            -
                # the worksheet in EMUs.
         
     | 
| 
      
 3310 
     | 
    
         
            +
                # Calculate the vertices that define the position of a graphical object
         
     | 
| 
      
 3311 
     | 
    
         
            +
                # within the worksheet in EMUs.
         
     | 
| 
       3190 
3312 
     | 
    
         
             
                #
         
     | 
| 
       3191 
     | 
    
         
            -
                def position_object_emus( 
     | 
| 
      
 3313 
     | 
    
         
            +
                def position_object_emus(graphical_object) # :nodoc:
         
     | 
| 
      
 3314 
     | 
    
         
            +
                  go = graphical_object
         
     | 
| 
       3192 
3315 
     | 
    
         
             
                  col_start, row_start, x1, y1, col_end, row_end, x2, y2, x_abs, y_abs =
         
     | 
| 
       3193 
     | 
    
         
            -
                    position_object_pixels( 
     | 
| 
      
 3316 
     | 
    
         
            +
                    position_object_pixels(go.col, go.row, go.x_offset, go.y_offset, go.scaled_width, go.scaled_height, go.anchor)
         
     | 
| 
       3194 
3317 
     | 
    
         | 
| 
       3195 
3318 
     | 
    
         
             
                  # Convert the pixel values to EMUs. See above.
         
     | 
| 
       3196 
3319 
     | 
    
         
             
                  x1    = (0.5 + (9_525 * x1)).to_i
         
     | 
| 
         @@ -3203,54 +3326,6 @@ module Writexlsx 
     | 
|
| 
       3203 
3326 
     | 
    
         
             
                  [col_start, row_start, x1, y1, col_end, row_end, x2, y2, x_abs, y_abs]
         
     | 
| 
       3204 
3327 
     | 
    
         
             
                end
         
     | 
| 
       3205 
3328 
     | 
    
         | 
| 
       3206 
     | 
    
         
            -
                #
         
     | 
| 
       3207 
     | 
    
         
            -
                # Convert the width of a cell from user's units to pixels. Excel rounds the
         
     | 
| 
       3208 
     | 
    
         
            -
                # column width to the nearest pixel. If the width hasn't been set by the user
         
     | 
| 
       3209 
     | 
    
         
            -
                # we use the default value. A hidden column is treated as having a width of
         
     | 
| 
       3210 
     | 
    
         
            -
                # zero unless it has the special "object_position" of 4 (size with cells).
         
     | 
| 
       3211 
     | 
    
         
            -
                #
         
     | 
| 
       3212 
     | 
    
         
            -
                def size_col(col, anchor = 0) # :nodoc:
         
     | 
| 
       3213 
     | 
    
         
            -
                  # Look up the cell value to see if it has been changed.
         
     | 
| 
       3214 
     | 
    
         
            -
                  if @col_info[col]
         
     | 
| 
       3215 
     | 
    
         
            -
                    width  = @col_info[col].width || @default_col_width
         
     | 
| 
       3216 
     | 
    
         
            -
                    hidden = @col_info[col].hidden
         
     | 
| 
       3217 
     | 
    
         
            -
             
     | 
| 
       3218 
     | 
    
         
            -
                    # Convert to pixels.
         
     | 
| 
       3219 
     | 
    
         
            -
                    pixels = if hidden == 1 && anchor != 4
         
     | 
| 
       3220 
     | 
    
         
            -
                               0
         
     | 
| 
       3221 
     | 
    
         
            -
                             elsif width < 1
         
     | 
| 
       3222 
     | 
    
         
            -
                               ((width * (MAX_DIGIT_WIDTH + PADDING)) + 0.5).to_i
         
     | 
| 
       3223 
     | 
    
         
            -
                             else
         
     | 
| 
       3224 
     | 
    
         
            -
                               ((width * MAX_DIGIT_WIDTH) + 0.5).to_i + PADDING
         
     | 
| 
       3225 
     | 
    
         
            -
                             end
         
     | 
| 
       3226 
     | 
    
         
            -
                  else
         
     | 
| 
       3227 
     | 
    
         
            -
                    pixels = @default_col_pixels
         
     | 
| 
       3228 
     | 
    
         
            -
                  end
         
     | 
| 
       3229 
     | 
    
         
            -
                  pixels
         
     | 
| 
       3230 
     | 
    
         
            -
                end
         
     | 
| 
       3231 
     | 
    
         
            -
             
     | 
| 
       3232 
     | 
    
         
            -
                #
         
     | 
| 
       3233 
     | 
    
         
            -
                # Convert the height of a cell from user's units to pixels. If the height
         
     | 
| 
       3234 
     | 
    
         
            -
                # hasn't been set by the user we use the default value. A hidden row is
         
     | 
| 
       3235 
     | 
    
         
            -
                # treated as having a height of zero unless it has the special
         
     | 
| 
       3236 
     | 
    
         
            -
                # "object_position" of 4 (size with cells).
         
     | 
| 
       3237 
     | 
    
         
            -
                #
         
     | 
| 
       3238 
     | 
    
         
            -
                def size_row(row, anchor = 0) # :nodoc:
         
     | 
| 
       3239 
     | 
    
         
            -
                  # Look up the cell value to see if it has been changed
         
     | 
| 
       3240 
     | 
    
         
            -
                  if @row_sizes[row]
         
     | 
| 
       3241 
     | 
    
         
            -
                    height, hidden = @row_sizes[row]
         
     | 
| 
       3242 
     | 
    
         
            -
             
     | 
| 
       3243 
     | 
    
         
            -
                    pixels = if hidden == 1 && anchor != 4
         
     | 
| 
       3244 
     | 
    
         
            -
                               0
         
     | 
| 
       3245 
     | 
    
         
            -
                             else
         
     | 
| 
       3246 
     | 
    
         
            -
                               (4 / 3.0 * height).to_i
         
     | 
| 
       3247 
     | 
    
         
            -
                             end
         
     | 
| 
       3248 
     | 
    
         
            -
                  else
         
     | 
| 
       3249 
     | 
    
         
            -
                    pixels = (4 / 3.0 * @default_row_height).to_i
         
     | 
| 
       3250 
     | 
    
         
            -
                  end
         
     | 
| 
       3251 
     | 
    
         
            -
                  pixels
         
     | 
| 
       3252 
     | 
    
         
            -
                end
         
     | 
| 
       3253 
     | 
    
         
            -
             
     | 
| 
       3254 
3329 
     | 
    
         
             
                #
         
     | 
| 
       3255 
3330 
     | 
    
         
             
                # Convert the width of a cell from pixels to character units.
         
     | 
| 
       3256 
3331 
     | 
    
         
             
                #
         
     | 
| 
         @@ -3277,48 +3352,44 @@ module Writexlsx 
     | 
|
| 
       3277 
3352 
     | 
    
         
             
                #
         
     | 
| 
       3278 
3353 
     | 
    
         
             
                # Set up image/drawings.
         
     | 
| 
       3279 
3354 
     | 
    
         
             
                #
         
     | 
| 
       3280 
     | 
    
         
            -
                def prepare_image( 
     | 
| 
       3281 
     | 
    
         
            -
                   
     | 
| 
       3282 
     | 
    
         
            -
                   
     | 
| 
      
 3355 
     | 
    
         
            +
                def prepare_image(image, drawing_id, image_ids, image_ref_id) # :nodoc:
         
     | 
| 
      
 3356 
     | 
    
         
            +
                  image_type = image.type
         
     | 
| 
      
 3357 
     | 
    
         
            +
                  x_dpi  = image.x_dpi || 96
         
     | 
| 
      
 3358 
     | 
    
         
            +
                  y_dpi  = image.y_dpi || 96
         
     | 
| 
      
 3359 
     | 
    
         
            +
                  md5    = image.md5
         
     | 
| 
       3283 
3360 
     | 
    
         
             
                  drawing_type = 2
         
     | 
| 
       3284 
3361 
     | 
    
         | 
| 
       3285 
     | 
    
         
            -
                   
     | 
| 
       3286 
     | 
    
         
            -
                  x_scale, y_scale, url, tip, anchor, description, decorative = @images[index]
         
     | 
| 
      
 3362 
     | 
    
         
            +
                  @workbook.store_image_types(image_type)
         
     | 
| 
       3287 
3363 
     | 
    
         | 
| 
       3288 
     | 
    
         
            -
                   
     | 
| 
       3289 
     | 
    
         
            -
             
     | 
| 
       3290 
     | 
    
         
            -
             
     | 
| 
       3291 
     | 
    
         
            -
             
     | 
| 
       3292 
     | 
    
         
            -
             
     | 
| 
       3293 
     | 
    
         
            -
             
     | 
| 
       3294 
     | 
    
         
            -
                   
     | 
| 
      
 3364 
     | 
    
         
            +
                  if image_ids[md5]
         
     | 
| 
      
 3365 
     | 
    
         
            +
                    image_id = image_ids[md5]
         
     | 
| 
      
 3366 
     | 
    
         
            +
                  else
         
     | 
| 
      
 3367 
     | 
    
         
            +
                    image_ref_id += 1
         
     | 
| 
      
 3368 
     | 
    
         
            +
                    image_ids[md5] = image_id = image_ref_id
         
     | 
| 
      
 3369 
     | 
    
         
            +
                    @workbook.images << image
         
     | 
| 
      
 3370 
     | 
    
         
            +
                  end
         
     | 
| 
       3295 
3371 
     | 
    
         | 
| 
       3296 
     | 
    
         
            -
                   
     | 
| 
       3297 
     | 
    
         
            -
                  width  = (0.5 + (width  * 9_525)).to_i
         
     | 
| 
       3298 
     | 
    
         
            -
                  height = (0.5 + (height * 9_525)).to_i
         
     | 
| 
      
 3372 
     | 
    
         
            +
                  dimensions = position_object_emus(image)
         
     | 
| 
       3299 
3373 
     | 
    
         | 
| 
       3300 
3374 
     | 
    
         
             
                  # Create a Drawing object to use with worksheet unless one already exists.
         
     | 
| 
       3301 
     | 
    
         
            -
                  drawing = Drawing.new( 
     | 
| 
       3302 
     | 
    
         
            -
             
     | 
| 
       3303 
     | 
    
         
            -
                     
     | 
| 
       3304 
     | 
    
         
            -
             
     | 
| 
       3305 
     | 
    
         
            -
             
     | 
| 
       3306 
     | 
    
         
            -
             
     | 
| 
       3307 
     | 
    
         
            -
             
     | 
| 
       3308 
     | 
    
         
            -
                    @drawings =  
     | 
| 
      
 3375 
     | 
    
         
            +
                  drawing = Drawing.new(
         
     | 
| 
      
 3376 
     | 
    
         
            +
                    drawing_type, dimensions, image.width_emus, image.height_emus,
         
     | 
| 
      
 3377 
     | 
    
         
            +
                    nil, image.anchor, 0, 0, image.tip, image.name,
         
     | 
| 
      
 3378 
     | 
    
         
            +
                    image.description || image.name, image.decorative
         
     | 
| 
      
 3379 
     | 
    
         
            +
                  )
         
     | 
| 
      
 3380 
     | 
    
         
            +
                  unless drawings?
         
     | 
| 
      
 3381 
     | 
    
         
            +
                    @drawings = Drawings.new
         
     | 
| 
      
 3382 
     | 
    
         
            +
                    @drawings.embedded = true
         
     | 
| 
       3309 
3383 
     | 
    
         | 
| 
       3310 
3384 
     | 
    
         
             
                    @external_drawing_links << ['/drawing', "../drawings/drawing#{drawing_id}.xml"]
         
     | 
| 
       3311 
3385 
     | 
    
         
             
                  end
         
     | 
| 
       3312 
     | 
    
         
            -
                  drawings.add_drawing_object(drawing)
         
     | 
| 
       3313 
     | 
    
         
            -
             
     | 
| 
       3314 
     | 
    
         
            -
                  drawing.description = name unless description
         
     | 
| 
      
 3386 
     | 
    
         
            +
                  @drawings.add_drawing_object(drawing)
         
     | 
| 
       3315 
3387 
     | 
    
         | 
| 
       3316 
     | 
    
         
            -
                  if url
         
     | 
| 
       3317 
     | 
    
         
            -
                    rel_type = '/hyperlink'
         
     | 
| 
      
 3388 
     | 
    
         
            +
                  if image.url
         
     | 
| 
       3318 
3389 
     | 
    
         
             
                    target_mode = 'External'
         
     | 
| 
       3319 
     | 
    
         
            -
                    target = escape_url(url) if url =~ %r{^[fh]tt?ps?://} || url =~ /^mailto:/
         
     | 
| 
       3320 
     | 
    
         
            -
                    if url =~ /^external:/
         
     | 
| 
       3321 
     | 
    
         
            -
                      target = escape_url(url.sub(/^external:/, ''))
         
     | 
| 
      
 3390 
     | 
    
         
            +
                    target = escape_url(image.url) if image.url =~ %r{^[fh]tt?ps?://} || image.url =~ /^mailto:/
         
     | 
| 
      
 3391 
     | 
    
         
            +
                    if image.url =~ /^external:/
         
     | 
| 
      
 3392 
     | 
    
         
            +
                      target = escape_url(image.url.sub(/^external:/, ''))
         
     | 
| 
       3322 
3393 
     | 
    
         | 
| 
       3323 
3394 
     | 
    
         
             
                      # Additional escape not required in worksheet hyperlinks
         
     | 
| 
       3324 
3395 
     | 
    
         
             
                      target = target.gsub("#", '%23')
         
     | 
| 
         @@ -3331,8 +3402,8 @@ module Writexlsx 
     | 
|
| 
       3331 
3402 
     | 
    
         
             
                               end
         
     | 
| 
       3332 
3403 
     | 
    
         
             
                    end
         
     | 
| 
       3333 
3404 
     | 
    
         | 
| 
       3334 
     | 
    
         
            -
                    if url =~ /^internal:/
         
     | 
| 
       3335 
     | 
    
         
            -
                      target      = url.sub(/^internal:/, '#')
         
     | 
| 
      
 3405 
     | 
    
         
            +
                    if image.url =~ /^internal:/
         
     | 
| 
      
 3406 
     | 
    
         
            +
                      target      = image.url.sub(/^internal:/, '#')
         
     | 
| 
       3336 
3407 
     | 
    
         
             
                      target_mode = nil
         
     | 
| 
       3337 
3408 
     | 
    
         
             
                    end
         
     | 
| 
       3338 
3409 
     | 
    
         | 
| 
         @@ -3342,37 +3413,28 @@ Ignoring URL #{target} where link or anchor > 255 characters since it exceeds Ex 
     | 
|
| 
       3342 
3413 
     | 
    
         
             
            EOS
         
     | 
| 
       3343 
3414 
     | 
    
         
             
                    end
         
     | 
| 
       3344 
3415 
     | 
    
         | 
| 
       3345 
     | 
    
         
            -
                    @drawing_links << [ 
     | 
| 
       3346 
     | 
    
         
            -
                    drawing.url_rel_index = drawing_rel_index(url)
         
     | 
| 
      
 3416 
     | 
    
         
            +
                    @drawing_links << ['/hyperlink', target, target_mode] if target && !@drawing_rels[image.url]
         
     | 
| 
      
 3417 
     | 
    
         
            +
                    drawing.url_rel_index = drawing_rel_index(image.url)
         
     | 
| 
       3347 
3418 
     | 
    
         
             
                  end
         
     | 
| 
       3348 
3419 
     | 
    
         | 
| 
       3349 
3420 
     | 
    
         
             
                  @drawing_links << ['/image', "../media/image#{image_id}.#{image_type}"] unless @drawing_rels[md5]
         
     | 
| 
       3350 
3421 
     | 
    
         | 
| 
       3351 
3422 
     | 
    
         
             
                  drawing.rel_index = drawing_rel_index(md5)
         
     | 
| 
      
 3423 
     | 
    
         
            +
             
     | 
| 
      
 3424 
     | 
    
         
            +
                  image_ref_id
         
     | 
| 
       3352 
3425 
     | 
    
         
             
                end
         
     | 
| 
       3353 
     | 
    
         
            -
                public :prepare_image
         
     | 
| 
       3354 
3426 
     | 
    
         | 
| 
       3355 
     | 
    
         
            -
                def prepare_header_image(image_id,  
     | 
| 
      
 3427 
     | 
    
         
            +
                def prepare_header_image(image_id, image_property)
         
     | 
| 
       3356 
3428 
     | 
    
         
             
                  # Strip the extension from the filename.
         
     | 
| 
       3357 
     | 
    
         
            -
                  body = name.dup
         
     | 
| 
      
 3429 
     | 
    
         
            +
                  body = image_property.name.dup
         
     | 
| 
       3358 
3430 
     | 
    
         
             
                  body[/\.[^.]+$/, 0] = ''
         
     | 
| 
      
 3431 
     | 
    
         
            +
                  image_property.body = body
         
     | 
| 
       3359 
3432 
     | 
    
         | 
| 
       3360 
     | 
    
         
            -
                  @vml_drawing_links << ['/image', "../media/image#{image_id}.#{ 
     | 
| 
      
 3433 
     | 
    
         
            +
                  @vml_drawing_links << ['/image', "../media/image#{image_id}.#{image_property.type}"] unless @vml_drawing_rels[image_property.md5]
         
     | 
| 
       3361 
3434 
     | 
    
         | 
| 
       3362 
     | 
    
         
            -
                  ref_id = get_vml_drawing_rel_index(md5)
         
     | 
| 
       3363 
     | 
    
         
            -
                  @header_images_array <<  
     | 
| 
      
 3435 
     | 
    
         
            +
                  image_property.ref_id = get_vml_drawing_rel_index(image_property.md5)
         
     | 
| 
      
 3436 
     | 
    
         
            +
                  @header_images_array << image_property
         
     | 
| 
       3364 
3437 
     | 
    
         
             
                end
         
     | 
| 
       3365 
     | 
    
         
            -
                public :prepare_header_image
         
     | 
| 
       3366 
     | 
    
         
            -
             
     | 
| 
       3367 
     | 
    
         
            -
                #
         
     | 
| 
       3368 
     | 
    
         
            -
                # Set the background image for the worksheet.
         
     | 
| 
       3369 
     | 
    
         
            -
                #
         
     | 
| 
       3370 
     | 
    
         
            -
                def set_background(image)
         
     | 
| 
       3371 
     | 
    
         
            -
                  raise "Couldn't locate #{image}: $!" unless File.exist?(image)
         
     | 
| 
       3372 
     | 
    
         
            -
             
     | 
| 
       3373 
     | 
    
         
            -
                  @background_image = image
         
     | 
| 
       3374 
     | 
    
         
            -
                end
         
     | 
| 
       3375 
     | 
    
         
            -
                public :set_background
         
     | 
| 
       3376 
3438 
     | 
    
         | 
| 
       3377 
3439 
     | 
    
         
             
                #
         
     | 
| 
       3378 
3440 
     | 
    
         
             
                # Set up an image without a drawing object for the background image.
         
     | 
| 
         @@ -3381,78 +3443,25 @@ EOS 
     | 
|
| 
       3381 
3443 
     | 
    
         
             
                  @external_background_links <<
         
     | 
| 
       3382 
3444 
     | 
    
         
             
                    ['/image', "../media/image#{image_id}.#{image_type}"]
         
     | 
| 
       3383 
3445 
     | 
    
         
             
                end
         
     | 
| 
       3384 
     | 
    
         
            -
                public :prepare_background
         
     | 
| 
       3385 
3446 
     | 
    
         | 
| 
       3386 
     | 
    
         
            -
                 
     | 
| 
       3387 
     | 
    
         
            -
             
     | 
| 
       3388 
     | 
    
         
            -
             
     | 
| 
       3389 
     | 
    
         
            -
                #
         
     | 
| 
       3390 
     | 
    
         
            -
                # Insert a shape into the worksheet.
         
     | 
| 
       3391 
     | 
    
         
            -
                #
         
     | 
| 
       3392 
     | 
    
         
            -
                def insert_shape(
         
     | 
| 
       3393 
     | 
    
         
            -
                      row_start, column_start, shape = nil, x_offset = nil, y_offset = nil,
         
     | 
| 
       3394 
     | 
    
         
            -
                      x_scale = nil, y_scale = nil, anchor = nil
         
     | 
| 
       3395 
     | 
    
         
            -
                    )
         
     | 
| 
       3396 
     | 
    
         
            -
                  # Check for a cell reference in A1 notation and substitute row and column.
         
     | 
| 
       3397 
     | 
    
         
            -
                  if (row_col_array = row_col_notation(row_start))
         
     | 
| 
       3398 
     | 
    
         
            -
                    _row_start, _column_start = row_col_array
         
     | 
| 
       3399 
     | 
    
         
            -
                    _shape    = column_start
         
     | 
| 
       3400 
     | 
    
         
            -
                    _x_offset = shape
         
     | 
| 
       3401 
     | 
    
         
            -
                    _y_offset = x_offset
         
     | 
| 
       3402 
     | 
    
         
            -
                    _x_scale  = y_offset
         
     | 
| 
       3403 
     | 
    
         
            -
                    _y_scale  = x_scale
         
     | 
| 
       3404 
     | 
    
         
            -
                    _anchor   = y_scale
         
     | 
| 
       3405 
     | 
    
         
            -
                  else
         
     | 
| 
       3406 
     | 
    
         
            -
                    _row_start = row_start
         
     | 
| 
       3407 
     | 
    
         
            -
                    _column_start = column_start
         
     | 
| 
       3408 
     | 
    
         
            -
                    _shape = shape
         
     | 
| 
       3409 
     | 
    
         
            -
                    _x_offset = x_offset
         
     | 
| 
       3410 
     | 
    
         
            -
                    _y_offset = y_offset
         
     | 
| 
       3411 
     | 
    
         
            -
                    _x_scale = x_scale
         
     | 
| 
       3412 
     | 
    
         
            -
                    _y_scale = y_scale
         
     | 
| 
       3413 
     | 
    
         
            -
                    _anchor = anchor
         
     | 
| 
       3414 
     | 
    
         
            -
                  end
         
     | 
| 
       3415 
     | 
    
         
            -
                  raise "Insufficient arguments in insert_shape()" if [_row_start, _column_start, _shape].include?(nil)
         
     | 
| 
      
 3447 
     | 
    
         
            +
                def prepare_background_image(background_ids, image_ref_id)
         
     | 
| 
      
 3448 
     | 
    
         
            +
                  unless background_image.nil?
         
     | 
| 
      
 3449 
     | 
    
         
            +
                    @workbook.store_image_types(background_image.type)
         
     | 
| 
       3416 
3450 
     | 
    
         | 
| 
       3417 
     | 
    
         
            -
             
     | 
| 
       3418 
     | 
    
         
            -
             
     | 
| 
       3419 
     | 
    
         
            -
                    _x_scale, _y_scale, _anchor
         
     | 
| 
       3420 
     | 
    
         
            -
                  )
         
     | 
| 
       3421 
     | 
    
         
            -
                  # Assign a shape ID.
         
     | 
| 
       3422 
     | 
    
         
            -
                  while true
         
     | 
| 
       3423 
     | 
    
         
            -
                    id = _shape.id || 0
         
     | 
| 
       3424 
     | 
    
         
            -
                    used = @shape_hash[id]
         
     | 
| 
       3425 
     | 
    
         
            -
             
     | 
| 
       3426 
     | 
    
         
            -
                    # Test if shape ID is already used. Otherwise assign a new one.
         
     | 
| 
       3427 
     | 
    
         
            -
                    if !used && id != 0
         
     | 
| 
       3428 
     | 
    
         
            -
                      break
         
     | 
| 
      
 3451 
     | 
    
         
            +
                    if background_ids[background_image.md5]
         
     | 
| 
      
 3452 
     | 
    
         
            +
                      ref_id = background_ids[background_image.md5]
         
     | 
| 
       3429 
3453 
     | 
    
         
             
                    else
         
     | 
| 
       3430 
     | 
    
         
            -
                       
     | 
| 
       3431 
     | 
    
         
            -
                       
     | 
| 
      
 3454 
     | 
    
         
            +
                      image_ref_id += 1
         
     | 
| 
      
 3455 
     | 
    
         
            +
                      ref_id = image_ref_id
         
     | 
| 
      
 3456 
     | 
    
         
            +
                      background_ids[background_image.md5] = ref_id
         
     | 
| 
      
 3457 
     | 
    
         
            +
                      @workbook.images << background_image
         
     | 
| 
       3432 
3458 
     | 
    
         
             
                    end
         
     | 
| 
       3433 
     | 
    
         
            -
                  end
         
     | 
| 
       3434 
     | 
    
         
            -
             
     | 
| 
       3435 
     | 
    
         
            -
                  # Allow lookup of entry into shape array by shape ID.
         
     | 
| 
       3436 
     | 
    
         
            -
                  @shape_hash[_shape.id] = _shape.element = @shapes.size
         
     | 
| 
       3437 
3459 
     | 
    
         | 
| 
       3438 
     | 
    
         
            -
             
     | 
| 
       3439 
     | 
    
         
            -
             
     | 
| 
       3440 
     | 
    
         
            -
                             # used as a stencil. Previously stamped copies don't get modified
         
     | 
| 
       3441 
     | 
    
         
            -
                             # if the stencil is modified.
         
     | 
| 
       3442 
     | 
    
         
            -
                             _shape.dup
         
     | 
| 
       3443 
     | 
    
         
            -
                           else
         
     | 
| 
       3444 
     | 
    
         
            -
                             _shape
         
     | 
| 
       3445 
     | 
    
         
            -
                           end
         
     | 
| 
       3446 
     | 
    
         
            -
             
     | 
| 
       3447 
     | 
    
         
            -
                  # For connectors change x/y coords based on location of connected shapes.
         
     | 
| 
       3448 
     | 
    
         
            -
                  insert.auto_locate_connectors(@shapes, @shape_hash)
         
     | 
| 
      
 3460 
     | 
    
         
            +
                    prepare_background(ref_id, background_image.type)
         
     | 
| 
      
 3461 
     | 
    
         
            +
                  end
         
     | 
| 
       3449 
3462 
     | 
    
         | 
| 
       3450 
     | 
    
         
            -
                   
     | 
| 
       3451 
     | 
    
         
            -
                  # the parent shape is maintained.
         
     | 
| 
       3452 
     | 
    
         
            -
                  @shapes << insert
         
     | 
| 
       3453 
     | 
    
         
            -
                  insert
         
     | 
| 
      
 3463 
     | 
    
         
            +
                  image_ref_id
         
     | 
| 
       3454 
3464 
     | 
    
         
             
                end
         
     | 
| 
       3455 
     | 
    
         
            -
                public :insert_shape
         
     | 
| 
       3456 
3465 
     | 
    
         | 
| 
       3457 
3466 
     | 
    
         
             
                #
         
     | 
| 
       3458 
3467 
     | 
    
         
             
                # Set up drawing shapes
         
     | 
| 
         @@ -3463,7 +3472,7 @@ EOS 
     | 
|
| 
       3463 
3472 
     | 
    
         
             
                  # Create a Drawing object to use with worksheet unless one already exists.
         
     | 
| 
       3464 
3473 
     | 
    
         
             
                  unless drawings?
         
     | 
| 
       3465 
3474 
     | 
    
         
             
                    @drawings = Drawings.new
         
     | 
| 
       3466 
     | 
    
         
            -
                    @drawings.embedded =  
     | 
| 
      
 3475 
     | 
    
         
            +
                    @drawings.embedded = true
         
     | 
| 
       3467 
3476 
     | 
    
         
             
                    @external_drawing_links << ['/drawing', "../drawings/drawing#{drawing_id}.xml"]
         
     | 
| 
       3468 
3477 
     | 
    
         
             
                    @has_shapes = true
         
     | 
| 
       3469 
3478 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -3479,70 +3488,6 @@ EOS 
     | 
|
| 
       3479 
3488 
     | 
    
         
             
                  )
         
     | 
| 
       3480 
3489 
     | 
    
         
             
                  drawings.add_drawing_object(drawing)
         
     | 
| 
       3481 
3490 
     | 
    
         
             
                end
         
     | 
| 
       3482 
     | 
    
         
            -
                public :prepare_shape
         
     | 
| 
       3483 
     | 
    
         
            -
             
     | 
| 
       3484 
     | 
    
         
            -
                #
         
     | 
| 
       3485 
     | 
    
         
            -
                # This method handles the parameters passed to insert_button as well as
         
     | 
| 
       3486 
     | 
    
         
            -
                # calculating the button object position and vertices.
         
     | 
| 
       3487 
     | 
    
         
            -
                #
         
     | 
| 
       3488 
     | 
    
         
            -
                def button_params(row, col, params)
         
     | 
| 
       3489 
     | 
    
         
            -
                  button = Writexlsx::Package::Button.new
         
     | 
| 
       3490 
     | 
    
         
            -
             
     | 
| 
       3491 
     | 
    
         
            -
                  button_number = 1 + @buttons_array.size
         
     | 
| 
       3492 
     | 
    
         
            -
             
     | 
| 
       3493 
     | 
    
         
            -
                  # Set the button caption.
         
     | 
| 
       3494 
     | 
    
         
            -
                  caption = params[:caption] || "Button #{button_number}"
         
     | 
| 
       3495 
     | 
    
         
            -
             
     | 
| 
       3496 
     | 
    
         
            -
                  button.font = { _caption: caption }
         
     | 
| 
       3497 
     | 
    
         
            -
             
     | 
| 
       3498 
     | 
    
         
            -
                  # Set the macro name.
         
     | 
| 
       3499 
     | 
    
         
            -
                  button.macro = if params[:macro]
         
     | 
| 
       3500 
     | 
    
         
            -
                                   "[0]!#{params[:macro]}"
         
     | 
| 
       3501 
     | 
    
         
            -
                                 else
         
     | 
| 
       3502 
     | 
    
         
            -
                                   "[0]!Button#{button_number}_Click"
         
     | 
| 
       3503 
     | 
    
         
            -
                                 end
         
     | 
| 
       3504 
     | 
    
         
            -
             
     | 
| 
       3505 
     | 
    
         
            -
                  # Set the alt text for the button.
         
     | 
| 
       3506 
     | 
    
         
            -
                  button.description = params[:description]
         
     | 
| 
       3507 
     | 
    
         
            -
             
     | 
| 
       3508 
     | 
    
         
            -
                  # Ensure that a width and height have been set.
         
     | 
| 
       3509 
     | 
    
         
            -
                  default_width  = @default_col_pixels
         
     | 
| 
       3510 
     | 
    
         
            -
                  default_height = @default_row_pixels
         
     | 
| 
       3511 
     | 
    
         
            -
                  params[:width]  = default_width  unless params[:width]
         
     | 
| 
       3512 
     | 
    
         
            -
                  params[:height] = default_height unless params[:height]
         
     | 
| 
       3513 
     | 
    
         
            -
             
     | 
| 
       3514 
     | 
    
         
            -
                  # Set the x/y offsets.
         
     | 
| 
       3515 
     | 
    
         
            -
                  params[:x_offset] = 0 unless params[:x_offset]
         
     | 
| 
       3516 
     | 
    
         
            -
                  params[:y_offset] = 0 unless params[:y_offset]
         
     | 
| 
       3517 
     | 
    
         
            -
             
     | 
| 
       3518 
     | 
    
         
            -
                  # Scale the size of the button box if required.
         
     | 
| 
       3519 
     | 
    
         
            -
                  params[:width] = params[:width] * params[:x_scale] if params[:x_scale]
         
     | 
| 
       3520 
     | 
    
         
            -
                  params[:height] = params[:height] * params[:y_scale] if params[:y_scale]
         
     | 
| 
       3521 
     | 
    
         
            -
             
     | 
| 
       3522 
     | 
    
         
            -
                  # Round the dimensions to the nearest pixel.
         
     | 
| 
       3523 
     | 
    
         
            -
                  params[:width]  = (0.5 + params[:width]).to_i
         
     | 
| 
       3524 
     | 
    
         
            -
                  params[:height] = (0.5 + params[:height]).to_i
         
     | 
| 
       3525 
     | 
    
         
            -
             
     | 
| 
       3526 
     | 
    
         
            -
                  params[:start_row] = row
         
     | 
| 
       3527 
     | 
    
         
            -
                  params[:start_col] = col
         
     | 
| 
       3528 
     | 
    
         
            -
             
     | 
| 
       3529 
     | 
    
         
            -
                  # Calculate the positions of button object.
         
     | 
| 
       3530 
     | 
    
         
            -
                  vertices = position_object_pixels(
         
     | 
| 
       3531 
     | 
    
         
            -
                    params[:start_col],
         
     | 
| 
       3532 
     | 
    
         
            -
                    params[:start_row],
         
     | 
| 
       3533 
     | 
    
         
            -
                    params[:x_offset],
         
     | 
| 
       3534 
     | 
    
         
            -
                    params[:y_offset],
         
     | 
| 
       3535 
     | 
    
         
            -
                    params[:width],
         
     | 
| 
       3536 
     | 
    
         
            -
                    params[:height]
         
     | 
| 
       3537 
     | 
    
         
            -
                  )
         
     | 
| 
       3538 
     | 
    
         
            -
             
     | 
| 
       3539 
     | 
    
         
            -
                  # Add the width and height for VML.
         
     | 
| 
       3540 
     | 
    
         
            -
                  vertices << [params[:width], params[:height]]
         
     | 
| 
       3541 
     | 
    
         
            -
             
     | 
| 
       3542 
     | 
    
         
            -
                  button.vertices = vertices
         
     | 
| 
       3543 
     | 
    
         
            -
             
     | 
| 
       3544 
     | 
    
         
            -
                  button
         
     | 
| 
       3545 
     | 
    
         
            -
                end
         
     | 
| 
       3546 
3491 
     | 
    
         | 
| 
       3547 
3492 
     | 
    
         
             
                #
         
     | 
| 
       3548 
3493 
     | 
    
         
             
                # Hash a worksheet password. Based on the algorithm in ECMA-376-4:2016,
         
     | 
| 
         @@ -3868,7 +3813,7 @@ EOS 
     | 
|
| 
       3868 
3813 
     | 
    
         
             
                      end
         
     | 
| 
       3869 
3814 
     | 
    
         
             
                    else
         
     | 
| 
       3870 
3815 
     | 
    
         
             
                      # Row attributes only.
         
     | 
| 
       3871 
     | 
    
         
            -
                      write_empty_row(row_num, span,  
     | 
| 
      
 3816 
     | 
    
         
            +
                      write_empty_row(row_num, span, *@set_rows[row_num])
         
     | 
| 
       3872 
3817 
     | 
    
         
             
                    end
         
     | 
| 
       3873 
3818 
     | 
    
         
             
                  end
         
     | 
| 
       3874 
3819 
     | 
    
         
             
                end
         
     | 
| 
         @@ -4374,7 +4319,7 @@ EOS 
     | 
|
| 
       4374 
4319 
     | 
    
         
             
                  return unless outline_changed?
         
     | 
| 
       4375 
4320 
     | 
    
         | 
| 
       4376 
4321 
     | 
    
         
             
                  attributes = []
         
     | 
| 
       4377 
     | 
    
         
            -
                  attributes << ["applyStyles",  1] if @outline_style 
     | 
| 
      
 4322 
     | 
    
         
            +
                  attributes << ["applyStyles",  1] if @outline_style
         
     | 
| 
       4378 
4323 
     | 
    
         
             
                  attributes << ["summaryBelow", 0] if @outline_below == 0
         
     | 
| 
       4379 
4324 
     | 
    
         
             
                  attributes << ["summaryRight", 0] if @outline_right == 0
         
     | 
| 
       4380 
4325 
     | 
    
         
             
                  attributes << ["showOutlineSymbols", 0] if @outline_on == 0
         
     | 
| 
         @@ -4471,7 +4416,7 @@ EOS 
     | 
|
| 
       4471 
4416 
     | 
    
         
             
                # Write the <picture> element.
         
     | 
| 
       4472 
4417 
     | 
    
         
             
                #
         
     | 
| 
       4473 
4418 
     | 
    
         
             
                def write_picture
         
     | 
| 
       4474 
     | 
    
         
            -
                  return unless  
     | 
| 
      
 4419 
     | 
    
         
            +
                  return unless @background_image
         
     | 
| 
       4475 
4420 
     | 
    
         | 
| 
       4476 
4421 
     | 
    
         
             
                  # Increment the relationship id.
         
     | 
| 
       4477 
4422 
     | 
    
         
             
                  @rel_count += 1
         
     | 
| 
         @@ -4704,7 +4649,7 @@ EOS 
     | 
|
| 
       4704 
4649 
     | 
    
         
             
                def write_sparklines(sparkline)
         
     | 
| 
       4705 
4650 
     | 
    
         
             
                  # Write the sparkline elements.
         
     | 
| 
       4706 
4651 
     | 
    
         
             
                  @writer.tag_elements('x14:sparklines') do
         
     | 
| 
       4707 
     | 
    
         
            -
                    (0..sparkline[:count] - 1).each do |i|
         
     | 
| 
      
 4652 
     | 
    
         
            +
                    (0..(sparkline[:count] - 1)).each do |i|
         
     | 
| 
       4708 
4653 
     | 
    
         
             
                      range    = sparkline[:ranges][i]
         
     | 
| 
       4709 
4654 
     | 
    
         
             
                      location = sparkline[:locations][i]
         
     | 
| 
       4710 
4655 
     | 
    
         | 
| 
         @@ -4984,5 +4929,54 @@ EOS 
     | 
|
| 
       4984 
4929 
     | 
    
         | 
| 
       4985 
4930 
     | 
    
         
             
                  @writer.empty_tag('ignoredError', attributes)
         
     | 
| 
       4986 
4931 
     | 
    
         
             
                end
         
     | 
| 
      
 4932 
     | 
    
         
            +
             
     | 
| 
      
 4933 
     | 
    
         
            +
                def prepare_header_footer_image(image, header_image_ids, image_ref_id)
         
     | 
| 
      
 4934 
     | 
    
         
            +
                  @workbook.store_image_types(image.type)
         
     | 
| 
      
 4935 
     | 
    
         
            +
             
     | 
| 
      
 4936 
     | 
    
         
            +
                  if header_image_ids[image.md5]
         
     | 
| 
      
 4937 
     | 
    
         
            +
                    ref_id = header_image_ids[image.md5]
         
     | 
| 
      
 4938 
     | 
    
         
            +
                  else
         
     | 
| 
      
 4939 
     | 
    
         
            +
                    image_ref_id += 1
         
     | 
| 
      
 4940 
     | 
    
         
            +
                    header_image_ids[image.md5] = ref_id = image_ref_id
         
     | 
| 
      
 4941 
     | 
    
         
            +
                    @workbook.images << image
         
     | 
| 
      
 4942 
     | 
    
         
            +
                  end
         
     | 
| 
      
 4943 
     | 
    
         
            +
             
     | 
| 
      
 4944 
     | 
    
         
            +
                  prepare_header_image(ref_id, image)
         
     | 
| 
      
 4945 
     | 
    
         
            +
             
     | 
| 
      
 4946 
     | 
    
         
            +
                  image_ref_id
         
     | 
| 
      
 4947 
     | 
    
         
            +
                end
         
     | 
| 
      
 4948 
     | 
    
         
            +
             
     | 
| 
      
 4949 
     | 
    
         
            +
                def protect_default_settings  # :nodoc:
         
     | 
| 
      
 4950 
     | 
    
         
            +
                  {
         
     | 
| 
      
 4951 
     | 
    
         
            +
                    sheet:                 true,
         
     | 
| 
      
 4952 
     | 
    
         
            +
                    content:               false,
         
     | 
| 
      
 4953 
     | 
    
         
            +
                    objects:               false,
         
     | 
| 
      
 4954 
     | 
    
         
            +
                    scenarios:             false,
         
     | 
| 
      
 4955 
     | 
    
         
            +
                    format_cells:          false,
         
     | 
| 
      
 4956 
     | 
    
         
            +
                    format_columns:        false,
         
     | 
| 
      
 4957 
     | 
    
         
            +
                    format_rows:           false,
         
     | 
| 
      
 4958 
     | 
    
         
            +
                    insert_columns:        false,
         
     | 
| 
      
 4959 
     | 
    
         
            +
                    insert_rows:           false,
         
     | 
| 
      
 4960 
     | 
    
         
            +
                    insert_hyperlinks:     false,
         
     | 
| 
      
 4961 
     | 
    
         
            +
                    delete_columns:        false,
         
     | 
| 
      
 4962 
     | 
    
         
            +
                    delete_rows:           false,
         
     | 
| 
      
 4963 
     | 
    
         
            +
                    select_locked_cells:   true,
         
     | 
| 
      
 4964 
     | 
    
         
            +
                    sort:                  false,
         
     | 
| 
      
 4965 
     | 
    
         
            +
                    autofilter:            false,
         
     | 
| 
      
 4966 
     | 
    
         
            +
                    pivot_tables:          false,
         
     | 
| 
      
 4967 
     | 
    
         
            +
                    select_unlocked_cells: true
         
     | 
| 
      
 4968 
     | 
    
         
            +
                  }
         
     | 
| 
      
 4969 
     | 
    
         
            +
                end
         
     | 
| 
      
 4970 
     | 
    
         
            +
             
     | 
| 
      
 4971 
     | 
    
         
            +
                def expand_formula(formula, function, addition = '')
         
     | 
| 
      
 4972 
     | 
    
         
            +
                  if formula =~ /\b(#{function})/
         
     | 
| 
      
 4973 
     | 
    
         
            +
                    formula.gsub(
         
     | 
| 
      
 4974 
     | 
    
         
            +
                      ::Regexp.last_match(1),
         
     | 
| 
      
 4975 
     | 
    
         
            +
                      "_xlfn#{addition}.#{::Regexp.last_match(1)}"
         
     | 
| 
      
 4976 
     | 
    
         
            +
                    )
         
     | 
| 
      
 4977 
     | 
    
         
            +
                  else
         
     | 
| 
      
 4978 
     | 
    
         
            +
                    formula
         
     | 
| 
      
 4979 
     | 
    
         
            +
                  end
         
     | 
| 
      
 4980 
     | 
    
         
            +
                end
         
     | 
| 
       4987 
4981 
     | 
    
         
             
              end
         
     | 
| 
       4988 
4982 
     | 
    
         
             
            end
         
     |