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.
- checksums.yaml +4 -4
- data/CHANGELOG +9 -0
- data/README.md +1 -1
- data/lib/core/mini_magick.rb +12 -2
- data/lib/core/rmagick.rb +1 -0
- data/lib/htmlcolors.rb +1 -0
- data/lib/rbpdf/version.rb +3 -2
- data/lib/rbpdf.rb +585 -150
- data/rbpdf.gemspec +1 -1
- metadata +3 -6
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 =
|
534
|
-
@
|
535
|
-
@
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
2471
|
-
|
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
|
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
|
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
|
-
|
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
|
-
|
7539
|
+
|
7556
7540
|
# gradient patterns
|
7557
7541
|
if @gradients and !@gradients.empty?
|
7558
7542
|
out << ' /Pattern <<'
|
7559
|
-
@gradients.each_with_index
|
7560
|
-
|
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
|
7568
|
-
|
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
|
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
|
-
|
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
|
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 :
|
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
|
-
|
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
|
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=
|
9078
|
-
if style.is_a?
|
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
|
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'] =
|
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'] =
|
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'] =
|
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'] =
|
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'] =
|
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'] =
|
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'] =
|
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'] =
|
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
|
13186
|
-
|
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
|
-
|
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
|
-
|
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')
|