rbpdf 1.21.3 → 1.21.4

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.
data/lib/rbpdf.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # coding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
  #============================================================+
3
4
  # File name : rbpdf.rb
4
5
  # Begin : 2002-08-03
@@ -59,6 +60,12 @@ rescue LoadError
59
60
  # MiniMagick is not available
60
61
  end
61
62
 
63
+ begin
64
+ require 'marcel' unless Object.const_defined?(:Marcel)
65
+ rescue LoadError
66
+ # Marcel is not available
67
+ end
68
+
62
69
  unless Object.const_defined?(:MiniMagick)
63
70
  begin
64
71
  # RMagick 2.14.0
@@ -336,7 +343,7 @@ class RBPDF
336
343
  @outlines ||= []
337
344
 
338
345
  # --- javascript and form ---
339
- @javascript ||= ''
346
+ @javascript ||= +''
340
347
  @js_objects ||= {}
341
348
  @js_start_obj_id ||= 300000
342
349
  @js_obj_id ||= 300000
@@ -448,7 +455,7 @@ class RBPDF
448
455
  if @diskcache
449
456
  @buffer ||= nil
450
457
  else
451
- @buffer ||= ''
458
+ @buffer ||= +''
452
459
  end
453
460
  @tmp_buffer = nil
454
461
  @pages ||= []
@@ -530,18 +537,9 @@ class RBPDF
530
537
  @href ||= {}
531
538
  @fontlist ||= []
532
539
  getFontsList()
533
- @fgcolor = ActiveSupport::OrderedHash.new
534
- @fgcolor['R'] = 0
535
- @fgcolor['G'] = 0
536
- @fgcolor['B'] = 0
537
- @strokecolor = ActiveSupport::OrderedHash.new
538
- @strokecolor['R'] = 0
539
- @strokecolor['G'] = 0
540
- @strokecolor['B'] = 0
541
- @bgcolor = ActiveSupport::OrderedHash.new
542
- @bgcolor['R'] = 255
543
- @bgcolor['G'] = 255
544
- @bgcolor['B'] = 255
540
+ @fgcolor = [0, 0, 0]
541
+ @strokecolor = [0, 0, 0]
542
+ @bgcolor = [255, 255, 255]
545
543
  @extgstates ||= []
546
544
 
547
545
  # user's rights
@@ -1457,7 +1455,7 @@ class RBPDF
1457
1455
  #
1458
1456
  # Defines the title of the document.
1459
1457
  # [@param string :title] The title.
1460
- # [@access public$
1458
+ # [@access public]
1461
1459
  # [@since 1.2]
1462
1460
  # [@see] SetAuthor(), SetCreator(), SetKeywords(), SetSubject()
1463
1461
  #
@@ -2300,20 +2298,15 @@ class RBPDF
2300
2298
  if (col2 == -1) and (col3 == -1) and (col4 == -1)
2301
2299
  # Grey scale
2302
2300
  @draw_color = sprintf('%.3f G', col1 / 255.0)
2303
- @strokecolor['G'] = col1
2301
+ @strokecolor = [col1]
2304
2302
  elsif col4 == -1
2305
2303
  # RGB
2306
2304
  @draw_color = sprintf('%.3f %.3f %.3f RG', col1 / 255.0, col2 / 255.0, col3 / 255.0)
2307
- @strokecolor['R'] = col1
2308
- @strokecolor['G'] = col2
2309
- @strokecolor['B'] = col3
2305
+ @strokecolor = [col1, col2, col3]
2310
2306
  else
2311
2307
  # CMYK
2312
2308
  @draw_color = sprintf('%.3f %.3f %.3f %.3f K', col1 / 100.0, col2 / 100.0, col3 / 100.0, col4 / 100.0)
2313
- @strokecolor['C'] = col1
2314
- @strokecolor['M'] = col2
2315
- @strokecolor['Y'] = col3
2316
- @strokecolor['K'] = col4
2309
+ @strokecolor = [col1, col2, col3, col4]
2317
2310
  end
2318
2311
  if (@page>0)
2319
2312
  out(@draw_color + ' ')
@@ -2373,20 +2366,15 @@ class RBPDF
2373
2366
  if (col2 == -1) and (col3 == -1) and (col4 == -1)
2374
2367
  # Grey scale
2375
2368
  @fill_color = sprintf('%.3f g', col1 / 255.0)
2376
- @bgcolor['G'] = col1
2369
+ @bgcolor = [col1]
2377
2370
  elsif col4 == -1
2378
2371
  # RGB
2379
2372
  @fill_color = sprintf('%.3f %.3f %.3f rg', col1 / 255.0, col2 / 255.0, col3 / 255.0)
2380
- @bgcolor['R'] = col1
2381
- @bgcolor['G'] = col2
2382
- @bgcolor['B'] = col3
2373
+ @bgcolor = [col1, col2, col3]
2383
2374
  else
2384
2375
  # CMYK
2385
2376
  @fill_color = sprintf('%.3f %.3f %.3f %.3f k', col1 / 100.0, col2 / 100.0, col3 / 100.0, col4 / 100.0)
2386
- @bgcolor['C'] = col1
2387
- @bgcolor['M'] = col2
2388
- @bgcolor['Y'] = col3
2389
- @bgcolor['K'] = col4
2377
+ @bgcolor = [col1, col2, col3, col4]
2390
2378
  end
2391
2379
 
2392
2380
  @color_flag = (@fill_color != @text_color)
@@ -2463,20 +2451,16 @@ class RBPDF
2463
2451
  if (col2 == -1) and (col3 == -1) and (col4 == -1)
2464
2452
  # Grey scale
2465
2453
  @text_color = sprintf('%.3f g', col1 / 255.0)
2466
- @fgcolor['G'] = col1
2454
+ @fgcolor = [col1]
2467
2455
  elsif col4 == -1
2468
2456
  # RGB
2469
2457
  @text_color = sprintf('%.3f %.3f %.3f rg', col1 / 255.0, col2 / 255.0, col3 / 255.0)
2470
- @fgcolor['R'] = col1
2471
- @fgcolor['G'] = col2
2472
- @fgcolor['B'] = col3
2458
+ @fgcolor = [col1, col2, col3]
2459
+
2473
2460
  else
2474
2461
  # CMYK
2475
2462
  @text_color = sprintf('%.3f %.3f %.3f %.3f k', col1 / 100.0, col2 / 100.0, col3 / 100.0, col4 / 100.0)
2476
- @fgcolor['C'] = col1
2477
- @fgcolor['M'] = col2
2478
- @fgcolor['Y'] = col3
2479
- @fgcolor['K'] = col4
2463
+ @fgcolor = [col1, col2, col3, col4]
2480
2464
  end
2481
2465
  @color_flag = (@fill_color != @text_color)
2482
2466
  end
@@ -2668,7 +2652,7 @@ class RBPDF
2668
2652
  end
2669
2653
 
2670
2654
  tempstyle = style.upcase
2671
- style = ''
2655
+ style = +''
2672
2656
  # underline
2673
2657
  if tempstyle.index('U') != nil
2674
2658
  @underline = true
@@ -3469,8 +3453,8 @@ class RBPDF
3469
3453
  # [@see] Cell()
3470
3454
  #
3471
3455
  def getCellCode(w, h=0, txt='', border=0, ln=0, align='', fill=0, link=nil, stretch=0, ignore_min_height=false, calign='T', valign='M')
3472
- txt = '' if txt.nil?
3473
- rs = "" # string to be returned
3456
+ txt = +'' if txt.nil?
3457
+ rs = +"" # string to be returned
3474
3458
  txt = removeSHY(txt)
3475
3459
  if !ignore_min_height
3476
3460
  min_cell_height = @font_size * @cell_height_ratio
@@ -3552,7 +3536,7 @@ class RBPDF
3552
3536
  w = @w - @r_margin - x
3553
3537
  end
3554
3538
  end
3555
- s = '';
3539
+ s = +'';
3556
3540
  # fill and borders
3557
3541
  if (fill == 1) or (border.to_i == 1)
3558
3542
  if (fill == 1)
@@ -4088,7 +4072,7 @@ class RBPDF
4088
4072
  # * T: top
4089
4073
  # * R: right
4090
4074
  # * B: bottom
4091
- # [@param string multicell position: 'start', 'middle', 'end'
4075
+ # [@param string multicell :position] 'start', 'middle', 'end'
4092
4076
  # [@return mixed] border mode
4093
4077
  # [@access protected]
4094
4078
  # [@since 4.4.002 (2008-12-09)]
@@ -4098,7 +4082,7 @@ class RBPDF
4098
4082
  return 1
4099
4083
  end
4100
4084
  return 0 if border == 0
4101
- cborder = ''
4085
+ cborder = +''
4102
4086
  case position
4103
4087
  when 'start'
4104
4088
  if border == 1
@@ -4693,7 +4677,7 @@ class RBPDF
4693
4677
  # [@access public]
4694
4678
  #
4695
4679
  def UTF8ArrSubString(strarr, start=0, last=strarr.size)
4696
- string = ""
4680
+ string = +""
4697
4681
  start.upto(last - 1) do |i|
4698
4682
  string << unichr(strarr[i])
4699
4683
  end
@@ -4711,7 +4695,7 @@ class RBPDF
4711
4695
  # [@since 4.5.037 (2009-04-07)]
4712
4696
  #
4713
4697
  def UniArrSubString(uniarr, start=0, last=uniarr.length)
4714
- string = ''
4698
+ string = +''
4715
4699
  start.upto(last - 1) do |i|
4716
4700
  string << uniarr[i]
4717
4701
  end
@@ -5163,7 +5147,7 @@ class RBPDF
5163
5147
  end
5164
5148
  bpc=!a['bits'].nil? ? a['bits'] : 8;
5165
5149
  #Read whole file
5166
- data='';
5150
+ data=+'';
5167
5151
  open(file,'rb') do |f|
5168
5152
  data << f.read()
5169
5153
  end
@@ -5276,9 +5260,9 @@ class RBPDF
5276
5260
  f.read(4)
5277
5261
  parms='/DecodeParms <</Predictor 15 /Colors ' + (ct == 2 ? 3 : 1).to_s + ' /BitsPerComponent ' + bpc.to_s + ' /Columns ' + w.to_s + '>>'
5278
5262
  # Scan chunks looking for palette, transparency and image data
5279
- pal = ''
5280
- trns = ''
5281
- data = ''
5263
+ pal = +''
5264
+ trns = +''
5265
+ data = +''
5282
5266
  begin
5283
5267
  n = freadint(f)
5284
5268
  type = f.read(4)
@@ -5711,7 +5695,7 @@ class RBPDF
5711
5695
  self.instance_variables.each { |val|
5712
5696
  if destroyall or ((val != '@internal_encoding') and (val != '@state') and (val != '@bufferlen') and (val != '@buffer') and (val != '@diskcache') and (val != '@sign') and (val != '@signature_data') and (val != '@signature_max_length') and (val != '@byterange_string'))
5713
5697
  if (!preserve_objcopy or (val.to_s != '@objcopy')) and !val.nil?
5714
- eval("#{val} = nil")
5698
+ instance_variable_set(val, nil)
5715
5699
  end
5716
5700
  end
5717
5701
  }
@@ -5873,7 +5857,7 @@ protected
5873
5857
  temppage = temppage.gsub(@epsmarker, '')
5874
5858
  #Page
5875
5859
  @page_obj_id[n] = newobj()
5876
- out = '<<'
5860
+ out = +'<<'
5877
5861
  out << ' /Type /Page'
5878
5862
  out << ' /Parent 1 0 R'
5879
5863
  out << ' /LastModified ' + datestring()
@@ -5963,7 +5947,7 @@ protected
5963
5947
  end
5964
5948
  #Pages root
5965
5949
  @offsets[1]=@bufferlen
5966
- out = '1 0 obj << /Type /Pages /Kids ['
5950
+ out = +'1 0 obj << /Type /Pages /Kids ['
5967
5951
  @page_obj_id.each { |page_obj|
5968
5952
  out << ' ' + page_obj.to_s + ' 0 R' unless page_obj.nil?
5969
5953
  }
@@ -5993,9 +5977,9 @@ protected
5993
5977
  #
5994
5978
  def getannotsrefs(n)
5995
5979
  unless @page_annots[n] or (@sign and @signature_data['cert_type'])
5996
- return ''
5980
+ return +''
5997
5981
  end
5998
- out = ' /Annots ['
5982
+ out = +' /Annots ['
5999
5983
  if @page_annots[n]
6000
5984
  num_annots = @page_annots[n].length
6001
5985
  0.upto(num_annots - 1) do |i|
@@ -6033,7 +6017,7 @@ protected
6033
6017
  @page_annots[n].each_with_index { |pl, key|
6034
6018
  # create annotation object for grouping radiobuttons
6035
6019
  if @radiobutton_groups[n] and @radiobutton_groups[n][pl['txt']] and @radiobutton_groups[n][pl['txt']].is_a?(Array)
6036
- annots = '<<'
6020
+ annots = +'<<'
6037
6021
  annots << ' /Type /Annot'
6038
6022
  annots << ' /Subtype /Widget'
6039
6023
  annots << ' /T ' + dataannobjstring(pl['txt'])
@@ -6069,7 +6053,7 @@ protected
6069
6053
  d = pl['h'] * @k
6070
6054
  rect = sprintf('%.2f %.2f %.2f %.2f', a, b, a + c, b + d)
6071
6055
  # create new annotation object
6072
- annots = '<</Type /Annot'
6056
+ annots = +'<</Type /Annot'
6073
6057
  annots << ' /Subtype /' + pl['opt']['subtype']
6074
6058
  annots << ' /Rect [' + rect + ']'
6075
6059
  ft = ['Btn', 'Tx', 'Ch', 'Sig']
@@ -6860,7 +6844,7 @@ protected
6860
6844
  subsetglyphs = subsetglyphs_tmp
6861
6845
 
6862
6846
  # build new glyf table with only used glyphs
6863
- glyf = ''
6847
+ glyf = +''
6864
6848
  glyfSize = 0
6865
6849
  # create new empty indexToLoc table
6866
6850
  newIndexToLoc = Array.new(indexToLoc.length, 0)
@@ -6876,7 +6860,7 @@ protected
6876
6860
  end
6877
6861
  }
6878
6862
  # build new loca table
6879
- loca = ''
6863
+ loca = +''
6880
6864
  if short_offset
6881
6865
  newIndexToLoc.each {|offset|
6882
6866
  loca << [offset / 2].pack('n')
@@ -6938,7 +6922,7 @@ protected
6938
6922
  table['glyf']['offset'] = offset
6939
6923
  table['glyf']['checkSum'] = getTTFtableChecksum(table['glyf']['data'], table['glyf']['length'])
6940
6924
  # rebuild font
6941
- font = ''
6925
+ font = +''
6942
6926
  font << [0x10000].pack('N') # sfnt version
6943
6927
  numTables = table.length
6944
6928
  font << [numTables].pack('n') # numTables
@@ -7079,7 +7063,7 @@ protected
7079
7063
  end
7080
7064
  }
7081
7065
  # output data
7082
- w = ''
7066
+ w = +''
7083
7067
  range.each_with_index {|ws, k|
7084
7068
  if ws and ws.uniq.length == 1
7085
7069
  # interval mode is more compact
@@ -7154,7 +7138,7 @@ protected
7154
7138
  end
7155
7139
  newobj()
7156
7140
  @font_files[file]['n'] = @n
7157
- out = '<</Length '+ font.length.to_s
7141
+ out = +'<</Length '+ font.length.to_s
7158
7142
  if compressed
7159
7143
  out << ' /Filter /FlateDecode'
7160
7144
  end
@@ -7177,7 +7161,7 @@ protected
7177
7161
  if (type=='core')
7178
7162
  # standard core font
7179
7163
  obj_id = newobj()
7180
- out = '<</Type /Font'
7164
+ out = +'<</Type /Font'
7181
7165
  out << ' /Subtype /Type1'
7182
7166
  out << ' /BaseFont /' + name
7183
7167
  out << ' /Name /F' + font['i'].to_s
@@ -7193,7 +7177,7 @@ protected
7193
7177
  elsif (type=='Type1' || type=='TrueType')
7194
7178
  # additional Type1 or TrueType font
7195
7179
  obj_id = newobj()
7196
- out = '<</Type /Font'
7180
+ out = +'<</Type /Font'
7197
7181
  out << ' /Subtype /' + type
7198
7182
  out << ' /BaseFont /' + name
7199
7183
  out << ' /Name /F' + font['i'].to_s
@@ -7253,7 +7237,7 @@ protected
7253
7237
  # [@since 1.52.0.TC005 (2005-01-05)]
7254
7238
  #
7255
7239
  def puttruetypeunicode(font)
7256
- fontname = ''
7240
+ fontname = +''
7257
7241
  if font['subset']
7258
7242
  # change name for font subsetting
7259
7243
  subtag = sprintf('%06u', font['i'])
@@ -7264,7 +7248,7 @@ protected
7264
7248
  # Type0 Font
7265
7249
  # A composite font composed of other fonts, organized hierarchically
7266
7250
  obj_id = newobj()
7267
- out = '<</Type /Font'
7251
+ out = +'<</Type /Font'
7268
7252
  out << ' /Subtype /Type0'
7269
7253
  out << ' /BaseFont /' + fontname + ''
7270
7254
  out << ' /Name /F' + font['i'].to_s
@@ -7285,7 +7269,7 @@ protected
7285
7269
  # CIDFontType2
7286
7270
  # A CIDFont whose glyph descriptions are based on TrueType font technology
7287
7271
  newobj();
7288
- out = '<</Type /Font'
7272
+ out = +'<</Type /Font'
7289
7273
  out << ' /Subtype /CIDFontType2'
7290
7274
  out << ' /BaseFont /' + fontname
7291
7275
 
@@ -7306,7 +7290,7 @@ protected
7306
7290
  # Font descriptor
7307
7291
  # A font descriptor describing the CIDFont default metrics other than its glyph widths
7308
7292
  newobj();
7309
- out = '<</Type /FontDescriptor'
7293
+ out = +'<</Type /FontDescriptor'
7310
7294
  out << ' /FontName /' + fontname
7311
7295
  font['desc'].each do |key, value|
7312
7296
  if value.is_a? Float
@@ -7344,7 +7328,7 @@ protected
7344
7328
  Error('Font file not found: ' + ctgfile)
7345
7329
  end
7346
7330
  size = File.size(fontfile)
7347
- out = '<</Length ' + size.to_s + ''
7331
+ out = +'<</Length ' + size.to_s + ''
7348
7332
  if (fontfile[-2,2] == '.z') # check file extension
7349
7333
  # Decompresses data encoded using the public-domain
7350
7334
  # zlib/deflate compression method, reproducing the
@@ -7397,7 +7381,7 @@ protected
7397
7381
  longname = name
7398
7382
  end
7399
7383
  obj_id = newobj()
7400
- out = '<</Type /Font'
7384
+ out = +'<</Type /Font'
7401
7385
  out << ' /Subtype /Type0'
7402
7386
  out << ' /BaseFont /' + longname
7403
7387
  out << ' /Name /F' + font['i'].to_s
@@ -7408,7 +7392,7 @@ protected
7408
7392
  out << ' >> endobj'
7409
7393
  out(out)
7410
7394
  newobj()
7411
- out = '<</Type /Font'
7395
+ out = +'<</Type /Font'
7412
7396
  out << ' /Subtype /CIDFontType0'
7413
7397
  out << ' /BaseFont /' + name
7414
7398
  cidinfo = '/Registry ' + datastring(font['cidinfo']['Registry'])
@@ -7445,7 +7429,7 @@ protected
7445
7429
  info = getImageBuffer(file)
7446
7430
  newobj();
7447
7431
  setImageSubBuffer(file, 'n', @n)
7448
- out = '<</Type /XObject'
7432
+ out = +'<</Type /XObject'
7449
7433
  out << ' /Subtype /Image'
7450
7434
  out << ' /Width ' + info['w'].to_s
7451
7435
  out << ' /Height ' + info['h'].to_s
@@ -7468,7 +7452,7 @@ protected
7468
7452
  out << ' ' + info['parms']
7469
7453
  end
7470
7454
  if (!info['trns'].nil? and info['trns'].kind_of?(Array))
7471
- trns='';
7455
+ trns=+'';
7472
7456
  count_info = info['trns'].length
7473
7457
  count_info.times do |i|
7474
7458
  trns << info['trns'][i].to_s + ' ' + info['trns'][i].to_s + ' '
@@ -7501,14 +7485,14 @@ protected
7501
7485
 
7502
7486
  #
7503
7487
  # Output Spot Colors Resources.
7504
- # [@access protected[
7488
+ # [@access protected]
7505
7489
  # [@since 4.0.024 (2008-09-12)]
7506
7490
  #
7507
7491
  def putspotcolors()
7508
7492
  @spot_colors.each { |name, color|
7509
7493
  newobj()
7510
7494
  @spot_colors[name]['n'] = @n
7511
- out = '[/Separation /' + name.gsub(' ', '#20')
7495
+ out = +'[/Separation /' + name.gsub(' ', '#20')
7512
7496
  out << ' /DeviceCMYK <<'
7513
7497
  out << ' /Range [0 1 0 1 0 1 0 1] /C0 [0 0 0 0]'
7514
7498
  out << ' ' + sprintf('/C1 [%.4f %.4f %.4f %.4f] ', color['c']/100.0, color['m']/100.0, color['y']/100.0, color['k']/100.0)
@@ -7523,7 +7507,7 @@ protected
7523
7507
  # [@access protected]
7524
7508
  #
7525
7509
  def putresourcedict()
7526
- out = '2 0 obj'
7510
+ out = +'2 0 obj'
7527
7511
  out << ' << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'
7528
7512
  out << ' /Font <<'
7529
7513
  @fontkeys.each do |fontkey|
@@ -7552,23 +7536,28 @@ protected
7552
7536
  end
7553
7537
  }
7554
7538
  out << ' >>'
7555
- =begin
7539
+
7556
7540
  # gradient patterns
7557
7541
  if @gradients and !@gradients.empty?
7558
7542
  out << ' /Pattern <<'
7559
- @gradients.each_with_index {|grad, id|
7560
- out << ' /p' + id + ' ' + grad['pattern'] + ' 0 R'
7561
- }
7543
+ @gradients.each_with_index do |grad, id|
7544
+ next unless grad
7545
+
7546
+ out << " /p#{id} #{grad['pattern']} 0 R"
7547
+ end
7562
7548
  out << ' >>'
7563
7549
  end
7564
7550
  # gradient shadings
7565
7551
  if @gradients and !@gradients.empty?
7566
7552
  out << ' /Shading <<'
7567
- @gradients.each_with_index {|grad, id|
7568
- out << ' /Sh' + id + ' ' + grad['id'] + ' 0 R'
7569
- }
7553
+ @gradients.each_with_index do |grad, id|
7554
+ next unless grad
7555
+
7556
+ out << " /Sh#{id} #{grad['id']} 0 R"
7557
+ end
7570
7558
  out << ' >>'
7571
7559
  end
7560
+ =begin
7572
7561
  # spot colors
7573
7562
  if @spot_colors and !@spot_colors.empty?
7574
7563
  out << ' /ColorSpace <<'
@@ -7590,13 +7579,14 @@ protected
7590
7579
  mapLinksToHtmlAnchors()
7591
7580
  putextgstates()
7592
7581
  putocg()
7593
- putfonts();
7594
- putimages();
7582
+ putfonts()
7583
+ putimages()
7595
7584
  putspotcolors()
7585
+ putshaders()
7596
7586
 
7597
7587
  #Resource dictionary
7598
7588
  @offsets[2]=@bufferlen
7599
- putresourcedict();
7589
+ putresourcedict()
7600
7590
  putbookmarks()
7601
7591
  putEmbeddedFiles()
7602
7592
  putannotsobjs()
@@ -7613,7 +7603,7 @@ protected
7613
7603
  #
7614
7604
  def putinfo()
7615
7605
  newobj()
7616
- out = '<<'
7606
+ out = +'<<'
7617
7607
  if !empty_string(@title)
7618
7608
  # The document's title.
7619
7609
  out << ' /Title ' + textstring(@title)
@@ -7657,7 +7647,7 @@ protected
7657
7647
  #
7658
7648
  def putcatalog()
7659
7649
  newobj()
7660
- out = '<< /Type /Catalog'
7650
+ out = +'<< /Type /Catalog'
7661
7651
  out << ' /Pages 1 0 R'
7662
7652
  if @zoom_mode == 'fullpage'
7663
7653
  out << ' /OpenAction [3 0 R /Fit]'
@@ -7696,7 +7686,7 @@ protected
7696
7686
  # AcroForm
7697
7687
  if !@form_obj_id.empty? || (@sign && @signature_data['cert_type'])
7698
7688
  out << ' /AcroForm<<'
7699
- objrefs = ''
7689
+ objrefs = +''
7700
7690
  if @sign && @signature_data['cert_type']
7701
7691
  objrefs << "#{@sig_obj_id} 0 R"
7702
7692
  end
@@ -7742,7 +7732,7 @@ protected
7742
7732
  # [@access protected]
7743
7733
  #
7744
7734
  def putviewerpreferences()
7745
- out = '/ViewerPreferences <<'
7735
+ out = +'/ViewerPreferences <<'
7746
7736
  if @rtl
7747
7737
  out << ' /Direction /R2L'
7748
7738
  else
@@ -7796,7 +7786,7 @@ protected
7796
7786
  end
7797
7787
  end
7798
7788
  if @viewer_preferences['PrintPageRange']
7799
- print_page_range_num = ''
7789
+ print_page_range_num = +''
7800
7790
  @viewer_preferences['PrintPageRange'].each { |v|
7801
7791
  print_page_range_num << ' ' + (v - 1).to_s + ''
7802
7792
  }
@@ -7815,7 +7805,7 @@ protected
7815
7805
  # [@access protected]
7816
7806
  #
7817
7807
  def puttrailer()
7818
- out = 'trailer <<'
7808
+ out = +'trailer <<'
7819
7809
  out << ' /Size ' + (@n+1).to_s
7820
7810
  out << ' /Root ' + @n.to_s + ' 0 R'
7821
7811
  out << ' /Info ' + (@n-1).to_s + ' 0 R'
@@ -7926,7 +7916,7 @@ protected
7926
7916
  #
7927
7917
  def beginpage(orientation='', format='')
7928
7918
  @page += 1;
7929
- setPageBuffer(@page, '')
7919
+ setPageBuffer(@page, +'')
7930
7920
  # initialize array for graphics tranformation positions inside a page buffer
7931
7921
  @state=2;
7932
7922
  if empty_string(orientation)
@@ -8078,7 +8068,6 @@ protected
8078
8068
  # [@access protected]
8079
8069
  #
8080
8070
  def escape(s)
8081
- # Add \ before \, ( and )
8082
8071
  s.gsub('\\','\\\\\\').gsub('(','\\(').gsub(')','\\)').gsub(13.chr, '\r')
8083
8072
  end
8084
8073
 
@@ -8200,7 +8189,7 @@ protected
8200
8189
  # [@access protected]
8201
8190
  #
8202
8191
  def out(s)
8203
- s.force_encoding('ASCII-8BIT') if s.respond_to?(:force_encoding)
8192
+ s = (+s).force_encoding('ASCII-8BIT') if s.respond_to?(:force_encoding)
8204
8193
 
8205
8194
  if @tmp_buffer
8206
8195
  @tmp_buffer << "#{s}\n"
@@ -8377,7 +8366,7 @@ protected
8377
8366
  if !@is_unicode
8378
8367
  return str # string is not in unicode
8379
8368
  end
8380
- outstr = '' # string to be returned
8369
+ outstr = +'' # string to be returned
8381
8370
  unicode = UTF8StringToArray(str) # array containing UTF-8 unicode values
8382
8371
  unicode.each {|char|
8383
8372
  if char < 256
@@ -8461,7 +8450,7 @@ protected
8461
8450
  # [@see] UTF8ToUTF16BE()
8462
8451
  #
8463
8452
  def arrUTF8ToUTF16BE(unicode, setbom=true)
8464
- outstr = ""; # string to be returned
8453
+ outstr = +""; # string to be returned
8465
8454
  if (setbom)
8466
8455
  outstr << "\xFE\xFF"; # Byte Order Mark (BOM)
8467
8456
  end
@@ -8667,7 +8656,16 @@ public
8667
8656
  # [@return array] RGB color or empty array in case of error.
8668
8657
  # [@access public]
8669
8658
  #
8670
- def convertHTMLColorToDec(color = "#FFFFFF")
8659
+ def convert_html_color_to_dec_array(color = "#FFFFFF")
8660
+ returncolor = _convert_html_color_to_dec(color)
8661
+ if returncolor.is_a? Hash
8662
+ returncolor.values
8663
+ else
8664
+ returncolor
8665
+ end
8666
+ end
8667
+
8668
+ private def _convert_html_color_to_dec(color = "#FFFFFF")
8671
8669
  color = color.gsub(/[\s]*/, '') # remove extra spaces
8672
8670
  color = color.downcase
8673
8671
  if !(dotpos = color.index('.')).nil?
@@ -8677,7 +8675,6 @@ public
8677
8675
  if color.length == 0
8678
8676
  return []
8679
8677
  end
8680
- returncolor = ActiveSupport::OrderedHash.new
8681
8678
  # RGB ARRAY
8682
8679
  if color[0,3] == 'rgb'
8683
8680
  codes = color.sub(/^rgb\(/, '')
@@ -8692,6 +8689,7 @@ public
8692
8689
  if color[0,4] == 'cmyk'
8693
8690
  codes = color.sub(/^cmyk\(/, '')
8694
8691
  codes = codes.gsub(')', '')
8692
+ returncolor = codes.split(',', 4)
8695
8693
  returncolor[0] = returncolor[0].to_i
8696
8694
  returncolor[1] = returncolor[1].to_i
8697
8695
  returncolor[2] = returncolor[2].to_i
@@ -8710,6 +8708,7 @@ public
8710
8708
  color_code = color.sub(/^#/, "")
8711
8709
  end
8712
8710
  # RGB VALUE
8711
+ returncolor = {}
8713
8712
  case color_code.length
8714
8713
  when 3
8715
8714
  # three-digit hexadecimal representation
@@ -8729,6 +8728,11 @@ public
8729
8728
  end
8730
8729
  return returncolor
8731
8730
  end
8731
+
8732
+ def convertHTMLColorToDec(color = "#FFFFFF")
8733
+ warn("#{__callee__} is deprecated, use convert_html_color_to_dec_array instead.", uplevel: 1)
8734
+ _convert_html_color_to_dec(color)
8735
+ end
8732
8736
  alias_method :convert_html_color_to_dec, :convertHTMLColorToDec
8733
8737
 
8734
8738
  #
@@ -8853,7 +8857,7 @@ public
8853
8857
  tm[5] = y - tm[0] * y - tm[1] * x
8854
8858
 
8855
8859
  # generate the transformation matrix
8856
- Transform(tm)
8860
+ transform(tm)
8857
8861
  end
8858
8862
  alias_method :rotate, :Rotate
8859
8863
 
@@ -8864,7 +8868,7 @@ public
8864
8868
  # [@since 2.1.000 (2008-01-07)]
8865
8869
  # [@see] StartTransform(), StopTransform()
8866
8870
  #
8867
- def Transform(tm)
8871
+ def transform(tm)
8868
8872
  out(sprintf('%.3f %.3f %.3f %.3f %.3f %.3f cm', tm[0], tm[1], tm[2], tm[3], tm[4], tm[5]))
8869
8873
  # add tranformation matrix
8870
8874
  @transfmatrix[@transfmatrix_key].push 'a' => tm[0], 'b' => tm[1], 'c' => tm[2], 'd' => tm[3], 'e' => tm[4], 'f' => tm[5]
@@ -8873,7 +8877,7 @@ public
8873
8877
  @transfmrk[@page] = @pagelen[@page]
8874
8878
  end
8875
8879
  end
8876
- protected :Transform
8880
+ protected :transform
8877
8881
 
8878
8882
  # END TRANSFORMATIONS SECTION -------------------------
8879
8883
 
@@ -8950,6 +8954,7 @@ public
8950
8954
  end
8951
8955
  if !style['dash'].nil?
8952
8956
  dash = style['dash']
8957
+ phase = style['phase'].to_i
8953
8958
  dash_string = ''
8954
8959
  if dash != 0 and dash != ''
8955
8960
  if dash.is_a?(String) && dash =~ /^.+,/
@@ -8957,15 +8962,17 @@ public
8957
8962
  else
8958
8963
  tab = [dash]
8959
8964
  end
8960
- dash_string = ''
8965
+ dash_string = +''
8961
8966
  tab.each_with_index { |v, i|
8962
8967
  if i != 0
8963
8968
  dash_string << ' '
8964
8969
  end
8965
8970
  dash_string << sprintf("%.2f", v.to_f)
8966
8971
  }
8972
+ else
8973
+ phase = 0
8967
8974
  end
8968
- phase = 0
8975
+
8969
8976
  @linestyle_dash = sprintf("[%s] %.2f d", dash_string, phase)
8970
8977
  out(@linestyle_dash)
8971
8978
  end
@@ -9069,13 +9076,13 @@ public
9069
9076
  # [@param float :y1] Ordinate of first point
9070
9077
  # [@param float :x2] Abscissa of second point
9071
9078
  # [@param float :y2]] Ordinate of second point
9072
- # [@param hash :style] Line style. Array like for {@link SetLineStyle SetLineStyle}. Default value: default line style (empty array).
9079
+ # [@param hash :style] Line style. Array like for {@link SetLineStyle SetLineStyle}. Default value: default line style (empty Hash).
9073
9080
  # [@access public]
9074
9081
  # [@since 1.0]
9075
9082
  # [@see] SetLineWidth(), SetDrawColor(), SetLineStyle()
9076
9083
  #
9077
- def Line(x1, y1, x2, y2, style=nil)
9078
- if style.is_a? Hash
9084
+ def Line(x1, y1, x2, y2, style={})
9085
+ if style.is_a?(Hash) && !style.empty?
9079
9086
  SetLineStyle(style)
9080
9087
  end
9081
9088
  outPoint(x1, y1)
@@ -9340,8 +9347,8 @@ public
9340
9347
  # * all: Line style of all lines. Array like for {@link SetLineStyle SetLineStyle}.
9341
9348
  # * 0 to (:np - 1): Line style of each line. Array like for {@link SetLineStyle SetLineStyle}.
9342
9349
  # If a key is not present or is null, not draws the line. Default value is default line style (empty array).
9343
- # [@param array :fill_color Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K). Default value: default color (empty array).
9344
- # [@param boolean :closed if true the polygon is closes, otherwise will remain open
9350
+ # [@param array :fill_color] Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K). Default value: default color (empty array).
9351
+ # [@param boolean :closed] if true the polygon is closes, otherwise will remain open
9345
9352
  # [@access public]
9346
9353
  # [@since 4.8.003 (2009-09-15)]
9347
9354
  #
@@ -10364,7 +10371,7 @@ public
10364
10371
 
10365
10372
  #
10366
10373
  # Create a bookmark PDF string.
10367
- # [@access private]
10374
+ # [@access protected]
10368
10375
  # [@author] Olivier Plathey, Nicola Asuni
10369
10376
  # [@since 2.1.002 (2008-02-12)]
10370
10377
  #
@@ -10472,7 +10479,7 @@ public
10472
10479
  @javascript = "#{jsa}\n#{@javascript}\n#{jsb}"
10473
10480
  end
10474
10481
  @n_js = newobj()
10475
- out = ' << /Names ['
10482
+ out = +' << /Names ['
10476
10483
  unless @javascript.empty?
10477
10484
  out << " (EmbeddedJS) #{@n + 1} 0 R"
10478
10485
  end
@@ -10486,7 +10493,7 @@ public
10486
10493
  # default Javascript object
10487
10494
  unless @javascript.empty?
10488
10495
  newobj()
10489
- out = '<< /S /JavaScript'
10496
+ out = +'<< /S /JavaScript'
10490
10497
  out << " /JS #{textstring(@javascript)}"
10491
10498
  out << ' >> endobj'
10492
10499
  out(out)
@@ -10500,11 +10507,12 @@ public
10500
10507
  }
10501
10508
  end
10502
10509
  end
10510
+ protected :putjavascript
10503
10511
 
10504
10512
  #
10505
10513
  # Convert color to javascript color.
10506
10514
  # [@param string :color] color name or #RRGGBB
10507
- # [@access protected}
10515
+ # [@access protected]
10508
10516
  # [@author Denis Van Nuffelen, Nicola Asuni]
10509
10517
  # [@since 2.1.002 (2008-02-12)]
10510
10518
  #
@@ -10641,7 +10649,7 @@ public
10641
10649
  if prop['fillColor'].is_a? Array
10642
10650
  opt['mk']['bg'] = prop['fillColor']
10643
10651
  else
10644
- opt['mk']['bg'] = convertHTMLColorToDec(prop['fillColor'])
10652
+ opt['mk']['bg'] = convert_html_color_to_dec_array(prop['fillColor'])
10645
10653
  end
10646
10654
  end
10647
10655
  # strokeColor: Specifies the stroke color for a field that is used to stroke the rectangle of the field with a line as large as the line width.
@@ -10649,7 +10657,7 @@ public
10649
10657
  if prop['strokeColor'].is_a? Array
10650
10658
  opt['mk']['bc'] = prop['strokeColor']
10651
10659
  else
10652
- opt['mk']['bc'] = convertHTMLColorToDec(prop['strokeColor'])
10660
+ opt['mk']['bc'] = convert_html_color_to_dec_array(prop['strokeColor'])
10653
10661
  end
10654
10662
  end
10655
10663
  # rotation: The rotation of a widget in counterclockwise increments.
@@ -10821,14 +10829,14 @@ public
10821
10829
 
10822
10830
  if opt['v'] && !empty_string(opt['v'])
10823
10831
  # set Appearances
10824
- popt['ap']['n'] = "/Tx BMC q #{fontstyle} "
10832
+ popt['ap']['n'] = +"/Tx BMC q #{fontstyle} "
10825
10833
  gvars = getGraphicVars()
10826
10834
  @h = h
10827
10835
  @w = w
10828
10836
  @t_margin = 0
10829
10837
  @c_margin = 0.2
10830
10838
 
10831
- @tmp_buffer = ''
10839
+ @tmp_buffer = +''
10832
10840
  multi_cell(w, h, opt['v'], 0, '', 0, 0, 0.2, 0, true, 0, false, true, 0)
10833
10841
  popt['ap']['n'] << @tmp_buffer
10834
10842
  @tmp_buffer = nil
@@ -10989,7 +10997,7 @@ public
10989
10997
 
10990
10998
  if js
10991
10999
  addfield('listbox', name, x, y, w, h, prop)
10992
- s = ''
11000
+ s = +''
10993
11001
  values.each {|v|
10994
11002
  if v.is_a?(Array)
10995
11003
  s << "['#{v[0]}','#{v[1]}'],"
@@ -11010,7 +11018,7 @@ public
11010
11018
  unless @annotation_fonts.include? fontkey
11011
11019
  @annotation_fonts[font] = fontkey
11012
11020
  end
11013
- s = ''
11021
+ s = +''
11014
11022
  values.each {|v|
11015
11023
  if v.is_a?(Array)
11016
11024
  s << "#{v[1]}\n"
@@ -11023,14 +11031,14 @@ public
11023
11031
  popt['da'] = fontstyle
11024
11032
  popt['ap'] = {}
11025
11033
  # set Appearances
11026
- popt['ap']['n'] = "/Tx BMC q #{fontstyle} "
11034
+ popt['ap']['n'] = +"/Tx BMC q #{fontstyle} "
11027
11035
  gvars = getGraphicVars()
11028
11036
  @h = h
11029
11037
  @w = w
11030
11038
  @t_margin = 0
11031
11039
  @c_margin = 0.2
11032
11040
 
11033
- @tmp_buffer = ''
11041
+ @tmp_buffer = +''
11034
11042
  multi_cell(w, h, s, 0, '', 0, 0, 0.2, 0, true, 0, false, true, 0)
11035
11043
  popt['ap']['n'] << @tmp_buffer
11036
11044
  popt['ap']['n'] << 'Q EMC'
@@ -11076,7 +11084,7 @@ public
11076
11084
 
11077
11085
  if js
11078
11086
  addfield('combobox', name, x, y, w, h, prop)
11079
- s = ''
11087
+ s = +''
11080
11088
  values.each {|v|
11081
11089
  if v.is_a?(Array)
11082
11090
  s << "['#{v[0]}','#{v[1]}'],"
@@ -11099,7 +11107,7 @@ public
11099
11107
  @annotation_fonts[font] = fontkey
11100
11108
  end
11101
11109
 
11102
- s = ''
11110
+ s = +''
11103
11111
  values.each {|v|
11104
11112
  if v.is_a?(Array)
11105
11113
  s << "#{v[1]}\n"
@@ -11111,14 +11119,14 @@ public
11111
11119
  popt['da'] = fontstyle
11112
11120
  popt['ap'] = {}
11113
11121
  # set Appearances
11114
- popt['ap']['n'] = "/Tx BMC q #{fontstyle} "
11122
+ popt['ap']['n'] = +"/Tx BMC q #{fontstyle} "
11115
11123
  gvars = getGraphicVars()
11116
11124
  @h = h
11117
11125
  @w = w
11118
11126
  @t_margin = 0
11119
11127
  @c_margin = 0.2
11120
11128
 
11121
- @tmp_buffer = ''
11129
+ @tmp_buffer = +''
11122
11130
  multi_cell(w, h, s, 0, '', 0, 0, 0.2, 0, true, 0, false, true, 0)
11123
11131
  popt['ap']['n'] << @tmp_buffer
11124
11132
  popt['ap']['n'] << 'Q EMC'
@@ -11262,14 +11270,14 @@ public
11262
11270
  popt['da'] = fontstyle
11263
11271
  popt['ap'] = {}
11264
11272
  # set Appearances
11265
- popt['ap']['n'] = "/Tx BMC q #{fontstyle} 0.800 g\n"
11273
+ popt['ap']['n'] = +"/Tx BMC q #{fontstyle} 0.800 g\n"
11266
11274
 
11267
11275
  gvars = getGraphicVars()
11268
11276
  @h = h
11269
11277
  @w = w
11270
11278
  @c_margin *= 1.6
11271
11279
 
11272
- @tmp_buffer = ''
11280
+ @tmp_buffer = +''
11273
11281
  SetLineStyle({'width' => 1.0, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => [231]})
11274
11282
  SetFillColor(204)
11275
11283
  multi_cell(w, h, caption, 1, 'C', 1, 0, 0, 0, true)
@@ -11290,7 +11298,7 @@ public
11290
11298
  unless action.empty?
11291
11299
  if action.is_a?(Hash)
11292
11300
  # form action options as on section 12.7.5 of PDF32000_2008.
11293
- opt['aa'] = '/D <<'
11301
+ opt['aa'] = +'/D <<'
11294
11302
  bmode = ['SubmitForm', 'ResetForm', 'ImportData']
11295
11303
  action.each {|key, val|
11296
11304
  if (key == 'S') && bmode.include?(val)
@@ -11601,7 +11609,7 @@ public
11601
11609
  newobj()
11602
11610
  @extgstates[i] ||= {}
11603
11611
  @extgstates[i]['n'] = @n
11604
- out = '<< /Type /ExtGState'
11612
+ out = +'<< /Type /ExtGState'
11605
11613
  if @extgstates[i]['parms']
11606
11614
  @extgstates[i]['parms'].each {|k, v|
11607
11615
  if v.is_a? Float
@@ -11735,6 +11743,434 @@ public
11735
11743
  end
11736
11744
  alias_method :set_viewer_preferences, :setViewerPreferences
11737
11745
 
11746
+ #
11747
+ # Paints a linear colour gradient.
11748
+ # [@param float :x] abscissa of the top left corner of the rectangle.
11749
+ # [@param float :y] ordinate of the top left corner of the rectangle.
11750
+ # [@param float :w] width of the rectangle.
11751
+ # [@param float :h] height of the rectangle.
11752
+ # [@param array :col1] first color (Grayscale, RGB or CMYK components).
11753
+ # [@param array :col2] second color (Grayscale, RGB or CMYK components).
11754
+ # [@param array :coords] array of the form (x1, y1, x2, y2) which defines the gradient vector (see linear_gradient_coords.jpg). The default value is from left to right (x1=0, y1=0, x2=1, y2=0).
11755
+ # [@since 3.1.000 (2008-06-09)]
11756
+ # [@access public]
11757
+ #
11758
+ def LinearGradient(x, y, w, h, col1=[], col2=[], coords=[0,0,1,0])
11759
+ Clip(x, y, w, h)
11760
+ Gradient(2, coords, [{'color' => col1, 'offset' => 0, 'exponent' => 1}, {'color' => col2, 'offset' => 1, 'exponent' => 1}], [], false)
11761
+ end
11762
+ alias_method :linear_gradient, :LinearGradient
11763
+
11764
+ #
11765
+ # Paints a radial colour gradient.
11766
+ # [@param float :x] abscissa of the top left corner of the rectangle.
11767
+ # [@param float :y] ordinate of the top left corner of the rectangle.
11768
+ # [@param float :w] width of the rectangle.
11769
+ # [@param float :h] height of the rectangle.
11770
+ # [@param array :col1] first color (Grayscale, RGB or CMYK components).
11771
+ # [@param array :col2] second color (Grayscale, RGB or CMYK components).
11772
+ # [@param array :coords] array of the form (fx, fy, cx, cy, r) where (fx, fy) is the starting point of the gradient with color1, (cx, cy) is the center of the circle with color2, and r is the radius of the circle (see radial_gradient_coords.jpg). (fx, fy) should be inside the circle, otherwise some areas will not be defined.
11773
+ # [@since 3.1.000 (2008-06-09)]
11774
+ # [@access public]
11775
+ #
11776
+ def RadialGradient(x, y, w, h, col1=[], col2=[], coords=[0.5,0.5,0.5,0.5,1])
11777
+ Clip(x, y, w, h)
11778
+ Gradient(3, coords, [{'color' => col1, 'offset' => 0, 'exponent' => 1}, {'color' => col2, 'offset' => 1, 'exponent' => 1}], [], false)
11779
+ end
11780
+ alias_method :radial_gradient, :RadialGradient
11781
+
11782
+ #
11783
+ # Paints a coons patch mesh.
11784
+ # [@param float :x] abscissa of the top left corner of the rectangle.
11785
+ # [@param float :y] ordinate of the top left corner of the rectangle.
11786
+ # [@param float :w] width of the rectangle.
11787
+ # [@param float :h] height of the rectangle.
11788
+ # [@param array :col1] first color (lower left corner) (RGB components).
11789
+ # [@param array :col2] second color (lower right corner) (RGB components).
11790
+ # [@param array :col3] third color (upper right corner) (RGB components).
11791
+ # [@param array :col4] fourth color (upper left corner) (RGB components).
11792
+ # [@param array :coords] <ul><li>for one patch mesh: array(float x1, float y1, .... float x12, float y12): 12 pairs of coordinates (normally from 0 to 1) which specify the Bezier control points that define the patch. First pair is the lower left edge point, next is its right control point (control point 2). Then the other points are defined in the order: control point 1, edge point, control point 2 going counter-clockwise around the patch. Last (x12, y12) is the first edge point's left control point (control point 1).</li><li>for two or more patch meshes: array[number of patches]: arrays with the following keys for each patch: f: where to put that patch (0 = first patch, 1, 2, 3 = right, top and left of precedent patch - I didn't figure this out completely - just try and error ;-) points: 12 pairs of coordinates of the Bezier control points as above for the first patch, 8 pairs of coordinates for the following patches, ignoring the coordinates already defined by the precedent patch (I also didn't figure out the order of these - also: try and see what's happening) colors: must be 4 colors for the first patch, 2 colors for the following patches</li></ul>
11793
+ # [@param array :coords_min] minimum value used by the coordinates. If a coordinate's value is smaller than this it will be cut to coords_min. default: 0
11794
+ # [@param array :coords_max] maximum value used by the coordinates. If a coordinate's value is greater than this it will be cut to coords_max. default: 1
11795
+ # [@param boolean :antialias] A flag indicating whether to filter the shading function to prevent aliasing artifacts.
11796
+ # [@since 3.1.000 (2008-06-09)]
11797
+ # [@access public]
11798
+ #
11799
+ def CoonsPatchMesh(x, y, w, h, col1=[], col2=[], col3=[], col4=[], coords=[0.00,0.0,0.33,0.00,0.67,0.00,1.00,0.00,1.00,0.33,1.00,0.67,1.00,1.00,0.67,1.00,0.33,1.00,0.00,1.00,0.00,0.67,0.00,0.33], coords_min=0, coords_max=1, antialias=false)
11800
+ Clip(x, y, w, h)
11801
+ n = @gradients.size + 1
11802
+ @gradients[n] = {}
11803
+ @gradients[n]['type'] = 6 #coons patch mesh
11804
+ @gradients[n]['coords'] = []
11805
+ @gradients[n]['antialias'] = antialias
11806
+ @gradients[n]['colors'] = []
11807
+ @gradients[n]['transparency'] = false
11808
+ # check the coords array if it is the simple array or the multi patch array
11809
+ if coords[0].is_a? Hash
11810
+ # multi patch array
11811
+ patch_array = coords
11812
+ else
11813
+ # simple array -> convert to multi patch array
11814
+ if col1[1].nil?
11815
+ col1[1] = col1[2] = col1[0]
11816
+ end
11817
+ if col2[1].nil?
11818
+ col2[1] = col2[2] = col2[0]
11819
+ end
11820
+ if col3[1].nil?
11821
+ col3[1] = col3[2] = col3[0]
11822
+ end
11823
+ if col4[1].nil?
11824
+ col4[1] = col4[2] = col4[0]
11825
+ end
11826
+ patch_array = []
11827
+ patch_array[0] = {}
11828
+ patch_array[0]['f'] = 0
11829
+ patch_array[0]['points'] = coords
11830
+ patch_array[0]['colors'] = []
11831
+ patch_array[0]['colors'][0] = {}
11832
+ patch_array[0]['colors'][0]['r'] = col1[0]
11833
+ patch_array[0]['colors'][0]['g'] = col1[1]
11834
+ patch_array[0]['colors'][0]['b'] = col1[2]
11835
+ patch_array[0]['colors'][1] = {}
11836
+ patch_array[0]['colors'][1]['r'] = col2[0]
11837
+ patch_array[0]['colors'][1]['g'] = col2[1]
11838
+ patch_array[0]['colors'][1]['b'] = col2[2]
11839
+ patch_array[0]['colors'][2] = {}
11840
+ patch_array[0]['colors'][2]['r'] = col3[0]
11841
+ patch_array[0]['colors'][2]['g'] = col3[1]
11842
+ patch_array[0]['colors'][2]['b'] = col3[2]
11843
+ patch_array[0]['colors'][3] = {}
11844
+ patch_array[0]['colors'][3]['r'] = col4[0]
11845
+ patch_array[0]['colors'][3]['g'] = col4[1]
11846
+ patch_array[0]['colors'][3]['b'] = col4[2]
11847
+ end
11848
+ bpcd = 65535 #16 bits per coordinate
11849
+ # build the data stream
11850
+ @gradients[n]['stream'] = +''
11851
+ count_patch = patch_array.size
11852
+ count_patch.times do |i|
11853
+ @gradients[n]['stream'] << (patch_array[i]['f']).chr # start with the edge flag as 8 bit
11854
+ count_points = patch_array[i]['points'].size
11855
+ count_points.times do |j|
11856
+ # each point as 16 bit
11857
+ patch_array[i]['points'][j] = ((patch_array[i]['points'][j] - coords_min) / (coords_max - coords_min)) * bpcd
11858
+ if patch_array[i]['points'][j] < 0
11859
+ patch_array[i]['points'][j] = 0
11860
+ end
11861
+ if patch_array[i]['points'][j] > bpcd
11862
+ patch_array[i]['points'][j] = bpcd
11863
+ end
11864
+ @gradients[n]['stream'] << ((patch_array[i]['points'][j] / 256.0).floor).chr
11865
+ @gradients[n]['stream'] << ((patch_array[i]['points'][j] % 256.0).floor).chr
11866
+ end
11867
+ count_cols = patch_array[i]['colors'].size
11868
+ count_cols.times do |j|
11869
+ # each color component as 8 bit
11870
+ @gradients[n]['stream'] << (patch_array[i]['colors'][j]['r']).chr
11871
+ @gradients[n]['stream'] << (patch_array[i]['colors'][j]['g']).chr
11872
+ @gradients[n]['stream'] << (patch_array[i]['colors'][j]['b']).chr
11873
+ end
11874
+ end
11875
+ # paint the gradient
11876
+ out("/Sh#{n} sh")
11877
+ # restore previous Graphic State
11878
+ out('Q')
11879
+ end
11880
+ alias_method :coons_patch_mesh, :CoonsPatchMesh
11881
+
11882
+ #
11883
+ # Set a rectangular clipping area.
11884
+ # [@param float :x] abscissa of the top left corner of the rectangle (or top right corner for RTL mode).
11885
+ # [@param float :y] ordinate of the top left corner of the rectangle.
11886
+ # [@param float :w] width of the rectangle.
11887
+ # [@param float :h] height of the rectangle.
11888
+ # [@since 3.1.000 (2008-06-09)]
11889
+ # [@access protected]
11890
+ #
11891
+ def Clip(x, y, w, h)
11892
+ x = @w - x - w if @rtl
11893
+
11894
+ # save current Graphic State
11895
+ s = +'q'
11896
+ # set clipping area
11897
+ s << sprintf(' %.2f %.2f %.2f %.2f re W n', x * @k, (@h - y) * @k, w * @k, -h * @k)
11898
+ # set up transformation matrix for gradient
11899
+ s << sprintf(' %.3f 0 0 %.3f %.3f %.3f cm', w * @k, h * @k, x * @k, (@h - (y + h)) * @k)
11900
+ out(s)
11901
+ end
11902
+ protected :Clip
11903
+
11904
+ #
11905
+ # Output gradient.
11906
+ # [@param int :type] type of gradient (1 Function-based shading; 2 Axial shading; 3 Radial shading; 4 Free-form Gouraud-shaded triangle mesh; 5 Lattice-form Gouraud-shaded triangle mesh; 6 Coons patch mesh; 7 Tensor-product patch mesh). (Not all types are currently supported)
11907
+ # [@param array :coords] array of coordinates.
11908
+ # [@param array :stops] array gradient color components: color = array of GRAY, RGB or CMYK color components; offset = (0 to 1) represents a location along the gradient vector; exponent = exponent of the exponential interpolation function (default = 1).
11909
+ # [@param array :background] An array of colour components appropriate to the colour space, specifying a single background colour value.
11910
+ # [@param boolean :antialias] A flag indicating whether to filter the shading function to prevent aliasing artifacts.
11911
+ # [@since 3.1.000 (2008-06-09)]
11912
+ # [@access public]
11913
+ #
11914
+ def Gradient(type, coords, stops, background=[], antialias=false)
11915
+ n = @gradients.size + 1
11916
+ @gradients[n] = {}
11917
+ @gradients[n]['type'] = type
11918
+ @gradients[n]['coords'] = coords
11919
+ @gradients[n]['antialias'] = antialias
11920
+ @gradients[n]['colors'] = []
11921
+ @gradients[n]['transparency'] = false
11922
+ # color space
11923
+ numcolspace = stops[0]['color'].size
11924
+ bcolor = background
11925
+ case numcolspace
11926
+ when 4 # CMYK
11927
+ @gradients[n]['colspace'] = 'DeviceCMYK'
11928
+ unless background.empty?
11929
+ @gradients[n]['background'] = sprintf('%.3f %.3f %.3f %.3f', bcolor[0]/100.0, bcolor[1]/100.0, bcolor[2]/100.0, bcolor[3]/100.0)
11930
+ end
11931
+ when 3 # RGB
11932
+ @gradients[n]['colspace'] = 'DeviceRGB'
11933
+ unless background.empty?
11934
+ @gradients[n]['background'] = sprintf('%.3f %.3f %.3f', bcolor[0]/255.0, bcolor[1]/255.0, bcolor[2]/255.0)
11935
+ end
11936
+ when 1 # Gray scale
11937
+ @gradients[n]['colspace'] = 'DeviceGray'
11938
+ unless background.empty?
11939
+ @gradients[n]['background'] = sprintf('%.3f', bcolor[0]/255.0)
11940
+ end
11941
+ end
11942
+ num_stops = stops.size
11943
+ last_stop_id = num_stops - 1
11944
+ stops.each_with_index do |stop, key|
11945
+ @gradients[n]['colors'][key] = {}
11946
+ # offset represents a location along the gradient vector
11947
+ if stop['offset']
11948
+ @gradients[n]['colors'][key]['offset'] = stop['offset']
11949
+ else
11950
+ if key == 0
11951
+ @gradients[n]['colors'][key]['offset'] = 0
11952
+ elsif key == last_stop_id
11953
+ @gradients[n]['colors'][key]['offset'] = 1
11954
+ else
11955
+ offsetstep = (1 - @gradients[n]['colors'][key - 1]['offset']) / (num_stops - key)
11956
+ @gradients[n]['colors'][key]['offset'] = @gradients[n]['colors'][key - 1]['offset'] + offsetstep
11957
+ end
11958
+ end
11959
+ if stop['opacity']
11960
+ @gradients[n]['colors'][key]['opacity'] = stop['opacity']
11961
+ if stop['opacity'] < 1
11962
+ @gradients[n]['transparency'] = true
11963
+ end
11964
+ else
11965
+ @gradients[n]['colors'][key]['opacity'] = 1
11966
+ end
11967
+ # exponent for the exponential interpolation function
11968
+ if stop['exponent']
11969
+ @gradients[n]['colors'][key]['exponent'] = stop['exponent']
11970
+ else
11971
+ @gradients[n]['colors'][key]['exponent'] = 1
11972
+ end
11973
+ # set colors
11974
+ color = stop['color']
11975
+ case numcolspace
11976
+ when 4 # CMYK
11977
+ @gradients[n]['colors'][key]['color'] = sprintf('%.3f %.3f %.3f %.3f', color[0]/100.0, color[1]/100.0, color[2]/100.0, color[3]/100.0)
11978
+ when 3 # RGB
11979
+ @gradients[n]['colors'][key]['color'] = sprintf('%.3f %.3f %.3f', color[0]/255.0, color[1]/255.0, color[2]/255.0)
11980
+ when 1 # Gray scale
11981
+ @gradients[n]['colors'][key]['color'] = sprintf('%.3f', color[0]/255.0)
11982
+ end
11983
+ end
11984
+ if @gradients[n]['transparency']
11985
+ # paint luminosity gradient
11986
+ out("/TGS#{n} gs")
11987
+ end
11988
+ # paint the gradient
11989
+ out("/Sh#{n} sh")
11990
+ # restore previous Graphic State
11991
+ out('Q')
11992
+ end
11993
+ alias_method :gradient, :Gradient
11994
+
11995
+ #
11996
+ # Output gradient shaders.
11997
+ # [@since 3.1.000 (2008-06-09)]
11998
+ # [@access protected]
11999
+ #
12000
+ def putshaders()
12001
+ idt = @gradients.size #index for transparency gradients
12002
+ @gradients.each_with_index do |grad, id|
12003
+ next unless grad
12004
+
12005
+ if (grad['type'] == 2) || (grad['type'] == 3)
12006
+ newobj()
12007
+ fc = @n
12008
+ out = +'<<'
12009
+ out << ' /FunctionType 3'
12010
+ out << ' /Domain [0 1]'
12011
+ functions = +''
12012
+ bounds = +''
12013
+ encode = +''
12014
+ i = 1
12015
+ num_cols = grad['colors'].size
12016
+ lastcols = num_cols - 1
12017
+ 1.upto(num_cols - 1) do |i|
12018
+ functions << "#{fc + i} 0 R "
12019
+ if i < lastcols
12020
+ bounds << sprintf('%.3f ', grad['colors'][i]['offset'])
12021
+ end
12022
+ encode << '0 1 '
12023
+ end
12024
+ out << " /Functions [#{functions.strip}]"
12025
+ out << " /Bounds [#{bounds.strip}]"
12026
+ out << " /Encode [#{encode.strip}]"
12027
+ out << ' >>'
12028
+ out << ' endobj'
12029
+ out(out)
12030
+ 1.upto(num_cols - 1) do |i|
12031
+ newobj()
12032
+ out = +'<<'
12033
+ out << ' /FunctionType 2'
12034
+ out << ' /Domain [0 1]'
12035
+ out << " /C0 [#{grad['colors'][i - 1]['color']}]"
12036
+ out << " /C1 [#{grad['colors'][i]['color']}]"
12037
+ out << " /N #{grad['colors'][i]['exponent']}"
12038
+ out << ' >>'
12039
+ out << ' endobj'
12040
+ out(out)
12041
+ end
12042
+ # set transparency fuctions
12043
+ if grad['transparency']
12044
+ newobj()
12045
+ ft = @n
12046
+ out = +'<<'
12047
+ out << ' /FunctionType 3'
12048
+ out << ' /Domain [0 1]'
12049
+ functions = +''
12050
+ i = 1
12051
+ num_cols = grad['colors'].size
12052
+ 1.upto(num_cols - 1) do |i|
12053
+ functions << "#{ft + i} 0 R "
12054
+ end
12055
+ out << " /Functions [#{functions.strip}]"
12056
+ out << " /Bounds [#{bounds.strip}]"
12057
+ out << " /Encode [#{encode.strip}]"
12058
+ out << ' >>'
12059
+ out << ' endobj'
12060
+ out(out)
12061
+ 1.upto(num_cols - 1) do |i|
12062
+ newobj()
12063
+ out = +'<<'
12064
+ out << ' /FunctionType 2'
12065
+ out << ' /Domain [0 1]'
12066
+ out << " /C0 [#{grad['colors'][(i - 1)]['opacity']}]"
12067
+ out << " /C1 [#{grad['colors'][i]['opacity']}]"
12068
+ out << " /N #{grad['colors'][i]['exponent']}"
12069
+ out << ' >>'
12070
+ out << ' endobj'
12071
+ out(out)
12072
+ end
12073
+ end
12074
+ end
12075
+ # set shading object
12076
+ newobj()
12077
+ out = +"<< /ShadingType #{grad['type']}"
12078
+ if grad['colspace']
12079
+ out << " /ColorSpace /#{grad['colspace']}"
12080
+ else
12081
+ out << ' /ColorSpace /DeviceRGB'
12082
+ end
12083
+ if grad['background'] && !grad['background'].empty?
12084
+ out << " /Background [#{grad['background']}]"
12085
+ end
12086
+ if grad['antialias'] == true
12087
+ out << ' /AntiAlias true'
12088
+ end
12089
+ case grad['type']
12090
+ when 2
12091
+ out << sprintf(' /Coords [%.3f %.3f %.3f %.3f]', grad['coords'][0], grad['coords'][1], grad['coords'][2], grad['coords'][3])
12092
+ out << ' /Domain [0 1]'
12093
+ out << " /Function #{fc} 0 R"
12094
+ out << ' /Extend [true true]'
12095
+ out << ' >>'
12096
+ when 3
12097
+ # x0, y0, r0, x1, y1, r1
12098
+ # at this this time radius of inner circle is 0
12099
+ out << sprintf(' /Coords [%.3f %.3f 0 %.3f %.3f %.3f]', grad['coords'][0], grad['coords'][1], grad['coords'][2], grad['coords'][3], grad['coords'][4])
12100
+ out << ' /Domain [0 1]'
12101
+ out << " /Function #{fc} 0 R"
12102
+ out << ' /Extend [true true]'
12103
+ out << ' >>'
12104
+ when 6
12105
+ out << ' /BitsPerCoordinate 16'
12106
+ out << ' /BitsPerComponent 8'
12107
+ out << ' /Decode[0 1 0 1 0 1 0 1 0 1]'
12108
+ out << ' /BitsPerFlag 8'
12109
+ out << " /Length #{grad['stream'].length} >> "
12110
+ out << getstream(grad['stream'])
12111
+ end
12112
+ out << ' endobj'
12113
+ out(out)
12114
+ if grad['transparency']
12115
+ shading_transparency = out.gsub(%r{/ColorSpace /[^\s]+}mi, '/ColorSpace /DeviceGray')
12116
+ shading_transparency = shading_transparency.gsub(%r{/Function [0-9]+ }mi, "/Function #{ft} ")
12117
+ end
12118
+ @gradients[id]['id'] = @n
12119
+ # set pattern object
12120
+ newobj()
12121
+ out = +'<< /Type /Pattern /PatternType 2'
12122
+ out << " /Shading #{@gradients[id]['id']} 0 R"
12123
+ out << ' >> endobj'
12124
+ out(out)
12125
+ @gradients[id]['pattern'] = @n
12126
+ # set shading and pattern for transparency mask
12127
+ if grad['transparency']
12128
+ # luminosity pattern
12129
+ idgs = id + idt
12130
+ newobj()
12131
+ out(shading_transparency)
12132
+ @gradients[idgs] = {}
12133
+ @gradients[idgs]['id'] = @n
12134
+ newobj()
12135
+ out = +'<< /Type /Pattern /PatternType 2'
12136
+ out << " /Shading #{@gradients[idgs]['id']} 0 R"
12137
+ out << ' >> endobj'
12138
+ out(out)
12139
+ @gradients[idgs]['pattern'] = @n
12140
+ # luminosity XObject
12141
+ newobj()
12142
+ filter = ''
12143
+ stream = "q /a0 gs /Pattern cs /p#{idgs} scn 0 0 #{@w_pt} #{@h_pt} re f Q"
12144
+ if @compress
12145
+ filter = ' /Filter /FlateDecode'
12146
+ stream = Zlib::Deflate.deflate(stream)
12147
+ end
12148
+ out = +"<< /Type /XObject /Subtype /Form /FormType 1#{filter}"
12149
+ out << " /Length #{stream.length}"
12150
+ out << " /BBox [0 0 #{@w_pt} #{@h_pt}]"
12151
+ out << ' /Group << /Type /Group /S /Transparency /CS /DeviceGray >>'
12152
+ out << ' /Resources <<'
12153
+ out << ' /ExtGState << /a0 << /ca 1 /CA 1 >> >>'
12154
+ out << " /Pattern << /p#{idgs} #{@gradients[idgs]['pattern']} 0 R >>"
12155
+ out << ' >>'
12156
+ out << ' >> '
12157
+ out << getstream(stream)
12158
+ out << ' endobj'
12159
+ out(out)
12160
+ # SMask
12161
+ newobj()
12162
+ out = +"<< /Type /Mask /S /Luminosity /G #{@n - 1} 0 R >> endobj"
12163
+ out(out)
12164
+ # ExtGState
12165
+ newobj()
12166
+ out = +"<< /Type /ExtGState /SMask #{@n - 1} 0 R /AIS false >> endobj"
12167
+ out(out)
12168
+ @extgstates << {'n' => @n, 'name' => "TGS#{id}"}
12169
+ end
12170
+ end
12171
+ end
12172
+ protected :putshaders
12173
+
11738
12174
  #
11739
12175
  # Draw the sector of a circle.
11740
12176
  # It can be used for instance to render pie charts.
@@ -12086,7 +12522,6 @@ protected
12086
12522
  if dom[key]['attribute'] and dom[key]['attribute']['class'] and !dom[key]['attribute']['class'].empty?
12087
12523
  selector_class = dom[key]['attribute']['class'].downcase
12088
12524
  end
12089
- id = ''
12090
12525
  if dom[key]['attribute'] and dom[key]['attribute']['id'] and !dom[key]['attribute']['id'].empty?
12091
12526
  selector_id = dom[key]['attribute']['id'].downcase
12092
12527
  end
@@ -12203,7 +12638,7 @@ protected
12203
12638
  # [@since 5.1.000 (2010-05-25)]
12204
12639
  #
12205
12640
  def getTagStyleFromCSS(dom, key, css)
12206
- tagstyle = '' # style to be returned
12641
+ tagstyle = +'' # style to be returned
12207
12642
  # get all styles that apply
12208
12643
  css.each { |selector, style|
12209
12644
  # remove specificity
@@ -12273,7 +12708,7 @@ protected
12273
12708
  uri.split('/').each {|path|
12274
12709
  uri_path = uri_path.join(path)
12275
12710
  }
12276
- cssdata = ''
12711
+ cssdata = +''
12277
12712
  next unless File.exist?(uri_path)
12278
12713
 
12279
12714
  open(uri_path) do |f|
@@ -12426,7 +12861,7 @@ protected
12426
12861
  dom[key]['fill'] = ((@textrendermode % 2) == 0)
12427
12862
  dom[key]['clip'] = (@textrendermode > 3)
12428
12863
  dom[key]['line-height'] = @cell_height_ratio
12429
- dom[key]['bgcolor'] = ActiveSupport::OrderedHash.new
12864
+ dom[key]['bgcolor'] = []
12430
12865
  dom[key]['fgcolor'] = @fgcolor.dup # color
12431
12866
  dom[key]['strokecolor'] = @strokecolor.dup
12432
12867
 
@@ -12491,7 +12926,7 @@ protected
12491
12926
  dom[grandparent]['cols'] = dom[(dom[key]['parent'])]['cols']
12492
12927
  end
12493
12928
  if (dom[key]['value'] == 'td') or (dom[key]['value'] == 'th')
12494
- dom[(dom[key]['parent'])]['content'] = ''
12929
+ dom[(dom[key]['parent'])]['content'] = +''
12495
12930
  (dom[key]['parent'] + 1).upto(key - 1) do |i|
12496
12931
  dom[(dom[key]['parent'])]['content'] << a[dom[i]['elkey']]
12497
12932
  end
@@ -12644,7 +13079,7 @@ protected
12644
13079
  end
12645
13080
  end
12646
13081
  # font style
12647
- dom[key]['fontstyle'] ||= ""
13082
+ dom[key]['fontstyle'] ||= +""
12648
13083
  if !dom[key]['style']['font-weight'].nil? and (dom[key]['style']['font-weight'][0,1].downcase == 'b')
12649
13084
  dom[key]['fontstyle'] << 'B'
12650
13085
  end
@@ -12653,13 +13088,13 @@ protected
12653
13088
  end
12654
13089
  # font color
12655
13090
  if !empty_string(dom[key]['style']['color'])
12656
- dom[key]['fgcolor'] = convertHTMLColorToDec(dom[key]['style']['color'])
13091
+ dom[key]['fgcolor'] = convert_html_color_to_dec_array(dom[key]['style']['color'])
12657
13092
  elsif dom[key]['value'] == 'a'
12658
13093
  dom[key]['fgcolor'] = @html_link_color_array
12659
13094
  end
12660
13095
  # background color
12661
13096
  if !empty_string(dom[key]['style']['background-color'])
12662
- dom[key]['bgcolor'] = convertHTMLColorToDec(dom[key]['style']['background-color'])
13097
+ dom[key]['bgcolor'] = convert_html_color_to_dec_array(dom[key]['style']['background-color'])
12663
13098
  end
12664
13099
  # text-decoration
12665
13100
  if !dom[key]['style']['text-decoration'].nil?
@@ -12822,17 +13257,17 @@ protected
12822
13257
  end
12823
13258
  # set foreground color attribute
12824
13259
  if !empty_string(dom[key]['attribute']['color'])
12825
- dom[key]['fgcolor'] = convertHTMLColorToDec(dom[key]['attribute']['color'])
13260
+ dom[key]['fgcolor'] = convert_html_color_to_dec_array(dom[key]['attribute']['color'])
12826
13261
  elsif (dom[key]['style'].nil? or dom[key]['style']['color'].nil?) and (dom[key]['value'] == 'a')
12827
13262
  dom[key]['fgcolor'] = @html_link_color_array
12828
13263
  end
12829
13264
  # set background color attribute
12830
13265
  if !empty_string(dom[key]['attribute']['bgcolor'])
12831
- dom[key]['bgcolor'] = convertHTMLColorToDec(dom[key]['attribute']['bgcolor'])
13266
+ dom[key]['bgcolor'] = convert_html_color_to_dec_array(dom[key]['attribute']['bgcolor'])
12832
13267
  end
12833
13268
  # set stroke color attribute
12834
13269
  if !empty_string(dom[key]['attribute']['strokecolor'])
12835
- dom[key]['strokecolor'] = convertHTMLColorToDec(dom[key]['attribute']['strokecolor'])
13270
+ dom[key]['strokecolor'] = convert_html_color_to_dec_array(dom[key]['attribute']['strokecolor'])
12836
13271
  end
12837
13272
  # check for width attribute
12838
13273
  if !dom[key]['attribute']['width'].nil?
@@ -13182,8 +13617,8 @@ public
13182
13617
  # restore previous object
13183
13618
  rollbackTransaction(true)
13184
13619
  # restore previous values
13185
- this_method_vars.each {|vkey , vval|
13186
- eval("#{vkey} = vval")
13620
+ this_method_vars.each {|vkey, vval|
13621
+ binding.local_variable_set(vkey, vval)
13187
13622
  }
13188
13623
  # add a page (or trig AcceptPageBreak() for multicolumn mode)
13189
13624
  pre_y = @y
@@ -13956,7 +14391,7 @@ public
13956
14391
  len1 = dom[key]['value'].length
13957
14392
  lsp = len1 - dom[key]['value'].lstrip.length
13958
14393
  rsp = len1 - dom[key]['value'].rstrip.length
13959
- tmpstr = ''
14394
+ tmpstr = +''
13960
14395
  if rsp > 0
13961
14396
  tmpstr << dom[key]['value'][-rsp..-1]
13962
14397
  end
@@ -14046,7 +14481,7 @@ public
14046
14481
  rollbackTransaction(true)
14047
14482
  # restore previous values
14048
14483
  this_method_vars.each {|vkey , vval|
14049
- eval("#{vkey} = vval")
14484
+ binding.local_variable_set(vkey, vval)
14050
14485
  }
14051
14486
  # add a page (or trig AcceptPageBreak() for multicolumn mode)
14052
14487
  pre_y = @y
@@ -15294,7 +15729,7 @@ protected
15294
15729
  #
15295
15730
  def putHtmlListBullet(listdepth, listtype='', size=10)
15296
15731
  size /= @k
15297
- fill = ''
15732
+ fill = +''
15298
15733
  color = @fgcolor
15299
15734
  width = 0
15300
15735
  textitem = ''
@@ -15313,7 +15748,7 @@ protected
15313
15748
  # unordered types
15314
15749
  when 'none'
15315
15750
  when 'disc', 'circle'
15316
- fill = 'F' if listtype == 'disc'
15751
+ fill = +'F' if listtype == 'disc'
15317
15752
  fill << 'D'
15318
15753
  r = size / 6.0
15319
15754
  lspace += 2 * r
@@ -15526,7 +15961,7 @@ protected
15526
15961
  #
15527
15962
  def readDiskCache(filename)
15528
15963
  filename = filename.path
15529
- data = ''
15964
+ data = +''
15530
15965
  open( filename,'rb') do |f|
15531
15966
  data << f.read()
15532
15967
  end
@@ -16352,7 +16787,7 @@ public
16352
16787
  if this_self
16353
16788
  objvars = @objcopy.instance_variables
16354
16789
  objvars.each {|key|
16355
- eval("#{key} = @objcopy.instance_variable_get(key)") if key.to_s != '@objcopy'
16790
+ instance_variable_set(key, @objcopy.instance_variable_get(key)) if key.to_s != '@objcopy'
16356
16791
  }
16357
16792
  end
16358
16793
  return @objcopy
@@ -16489,7 +16924,7 @@ public
16489
16924
  # [@param string :default] default style
16490
16925
  # [@param boolean :mode] if true enable rasterization, false otherwise.
16491
16926
  # [@author] Nicola Asuni
16492
- # [@access protected:
16927
+ # [@access protected]
16493
16928
  # [@since 5.0.000 (2010-04-30)]
16494
16929
  #
16495
16930
  def getPathPaintOperator(style, default='S')