Class: RBPDF

Inherits:
Object
  • Object
show all
Includes:
ActionView::Helpers, Html_colors, Rbpdf, Unicode_data
Defined in:
lib/rbpdf.rb

Constant Summary collapse

@@version =
"5.1.002"
@@fpdf_charwidths =
{}
@@k_cell_height_ratio =
1.25
@@k_blank_image =
""
@@k_small_ratio =
2/3.0
@@k_path_images =
""
@@k_thai_topchars =
nil

Constants included from Rbpdf

Rbpdf::VERSION

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Rbpdf

#getimagesize

Constructor Details

#initialize(orientation = 'P', unit = 'mm', format = 'A4', unicode = true, encoding = "UTF-8", diskcache = false) ⇒ RBPDF

This is the class constructor. It allows to set up the page format, the orientation and the measure unit used in all the methods (except for the font sizes).

@since 1.0
@param string :orientation

page orientation. Possible values are (case insensitive):

  • P or Portrait (default)

  • L or Landscape

@param string :unit

User measure unit. Possible values are:

  • pt: point

  • mm: millimeter (default)

  • cm: centimeter

  • in: inch

A point equals 1/72 of inch, that is to say about 0.35 mm (an inch being 2.54 cm). This is a very common unit in typography; font sizes are expressed in that unit.

@param mixed :format

The format used for pages. It can be either: A string indicating the page format:

  • 4A0,2A0,A0,A1,A2,A3,A4 (default),A5,A6,A7,A8,A9,A10

  • B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10

  • C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10

  • RA0,RA1,RA2,RA3,RA4

  • SRA0,SRA1,SRA2,SRA3,SRA4

  • LETTER,LEGAL,EXECUTIVE,FOLIO

An array containing page measures and advanced options: see setPageFormat()

@param boolean :unicode

TRUE means that the input text is unicode (default = true)

@param String :encoding

charset encoding; default is UTF-8

@param boolean :diskcache

if TRUE reduce the RAM memory usage by caching temporary data on filesystem (slower).

@access public


263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
# File 'lib/rbpdf.rb', line 263

def initialize(orientation = 'P',  unit = 'mm', format = 'A4', unicode = true, encoding = "UTF-8", diskcache = false)

  # Set internal character encoding to ASCII#
  #FIXME 2007-05-25 (EJM) Level=0 -
  # if (respond_to?("mb_internal_encoding") and mb_internal_encoding())
  #   @internal_encoding = mb_internal_encoding();
  #   mb_internal_encoding("ASCII");
  # }

  if defined? Rails.root
    @@k_path_cache = Rails.root.join('tmp').to_s
    @@k_path_main = Rails.root.join('tmp').to_s
    @@k_path_url = Rails.root.join('tmp').to_s
  else
    # This particular error will occur when the test suite is run from outside a Rails environment.
    # We want to use the system's temp directory in that case.
    require 'tmpdir'
    @@k_path_cache = Dir.tmpdir
    @@k_path_main = Dir.tmpdir
    @@k_path_url = Dir.tmpdir
  end

  @@k_path_fonts = RBPDFFontDescriptor.getfontpath

  # set disk caching
  @diskcache = diskcache ? true : false

  # set language direction
  @rtl = false
  @tmprtl = false

  @x ||= 0
  @y ||= 0

  #######################
  @offsets ||= []

  @alias_nb_pages = '{nb}'
  @alias_num_page = '{pnb}'
  @img_scale ||= 1
  @r_margin ||= 0
  @l_margin ||= 0
  @original_r_margin ||= nil
  @original_l_margin ||= nil
  @t_margin ||= nil
  @b_margin ||= nil
  @auto_page_break ||= nil
  @page_annots ||= []

  @header_font ||= ['', '', 10]
  @footer_font ||= ['', '', 8]
  @l ||= {}

  @header_margin ||= 10
  @footer_margin ||= 10

  @barcode ||= false
  @print_header ||= true
  @print_footer ||= true
  @header_width ||= 0
  @header_logo ||= ""
  @header_logo_width ||= 30
  @header_title ||= ""
  @header_string ||= ""
  @listordered ||= []
  @listcount ||= []
  @listnum ||= 0
  @listindent ||= 0
  @listindentlevel ||= 0
  @lispacer ||= ""
  @li_position_x = nil

  # bookmark
  @outlines ||= []

  # --- javascript and form ---
  @javascript ||= ''
  @js_objects ||= {}
  @js_start_obj_id ||= 300000
  @js_obj_id ||= 300000

  @dpi = 72.0
  @newpagegroup ||= []
  @pagegroups ||= {}
  @currpagegroup ||= nil
  @visibility ||= 'all'
  @cell_height_ratio = @@k_cell_height_ratio
  @viewer_preferences ||= {}

  @intmrk ||= []
  @cntmrk ||= []
  @footerpos ||= []
  @footerlen ||= []
  @newline ||= true
  @endlinex ||= 0

  @open_marked_content ||= false
  @htmlvspace ||= 0
  @spot_colors ||= {}
  @lisymbol ||= ''
  @epsmarker ||= 'x#!#EPS#!#x'
  @transfmatrix ||= []
  @transfmatrix_key ||= 0
  @booklet ||= false
  @feps ||= 0.005
  @tagvspaces ||= {}
  @customlistindent ||= -1
  @opencell = true
  @embeddedfiles ||= {}

  @html_link_color_array ||= [0, 0, 255]
  @html_link_font_style ||= 'U'
  @numpages ||= 0
  @pagelen ||= []
  @numimages ||= 0
  @imagekeys ||= []
  @bufferlen ||= 0

  @numfonts ||= 0
  @fontkeys ||= []
  @font_obj_ids ||= {}
  @pageopen ||= [] # Store the fage status (true when opened, false when closed).
  @default_monospaced_font = 'courier'


  @cache_file_length = {}
  @thead ||= ''
  @thead_margins ||= {}
  @cache_utf8_string_to_array = {}
  @cache_maxsize_utf8_string_to_array = 8
  @cache_size_utf8_string_to_array = 0

  @signature_data ||= {}
  @sig_annot_ref ||= '***SIGANNREF*** 0 R'
  @page_obj_id ||= []
  @embedded_start_obj_id ||= 100000
  @form_obj_id ||= []
  @default_form_prop ||= {'lineWidth'=>1, 'borderStyle'=>'solid', 'fillColor'=>[255, 255, 255], 'strokeColor'=>[128, 128, 128]}
  @apxo_start_obj_id ||= 400000
  @apxo_obj_id ||= 400000
  @annotation_fonts ||= {}
  @radiobutton_groups ||= []
  @radio_groups ||= []
  @textindent ||= 0

  @start_transaction_y ||= 0
  @in_thead ||= false
  @columns ||= []
  @num_columns ||= 0
  @current_column ||= 0
  @column_start_page ||= 0
  @cur_orientation ||= nil

  # Text rendering mode:
  # 0 = Fill text;
  # 1 =            Stroke text;
  # 2 = Fill, then stroke text;
  # 3 = Neither fill nor stroke text (invisible);
  # 4 =              Fill text and add to path for clipping;
  # 5 =            Stroke text and add to path for clipping;
  # 6 = Fill, then stroke text and add to path for clipping;
  # 7 = Add text to path for clipping.
  @textrendermode ||= 0
  @textstrokewidth ||= 0

  @pdfunit ||= 'mm'
  @tocpage ||= false

  #######################

  #Some checks
  dochecks();

  begin
    @@decoder = HTMLEntities.new
  rescue
    @@decoder = nil
  end

  #Initialization of properties
  @is_unicode = unicode
  @page ||= 0
  @transfmrk ||= []
  @pagedim ||= []
  @n ||= 2
  if @diskcache
    @buffer ||= nil
  else
    @buffer ||= ''
  end
  @tmp_buffer = nil
  @pages ||= []
  @prev_pages ||= []
  @state ||= 0
  @fonts ||= {}
  @font_files ||= {}
  @diffs ||= []
  @images ||= {}
  @links ||= [] # array of internal links
  @html_anchor ||= nil
  @html_anchors ||= {}
  @html_anchor_links ||= {}
  @gradients ||= []
  @in_footer ||= false
  @lasth ||= 0
  @font_family ||= 'helvetica'
  @font_style ||= ''
  @font_size_pt ||= 12
  @font_subsetting ||= true
  @underline ||= false
  @overline ||= false
  @linethrough ||= false
  @draw_color ||= '0 G'
  @fill_color ||= '0 g'
  @text_color ||= '0 g'
  @color_flag ||= false
  @title ||= nil
  @author ||= nil
  @subject ||= nil
  @keywords ||= nil
  @creator ||= nil

  # encryption values
  @encrypted ||= false
  @last_enc_key ||= ''

  # Standard Unicode fonts
  @core_fonts = {
  'courier'=>'Courier',
  'courierB'=>'Courier-Bold',
  'courierI'=>'Courier-Oblique',
  'courierBI'=>'Courier-BoldOblique',
  'helvetica'=>'Helvetica',
  'helveticaB'=>'Helvetica-Bold',
  'helveticaI'=>'Helvetica-Oblique',
  'helveticaBI'=>'Helvetica-BoldOblique',
  'times'=>'Times-Roman',
  'timesB'=>'Times-Bold',
  'timesI'=>'Times-Italic',
  'timesBI'=>'Times-BoldItalic',
  'symbol'=>'Symbol',
  'zapfdingbats'=>'ZapfDingbats'}

  # Set scale factor
  setPageUnit(unit)
  # set page format and orientation
  setPageFormat(format, orientation)
  # Page margins (1 cm)
  margin = 28.35/@k
  SetMargins(margin, margin)
  #Interior cell margin (1 mm)
  @c_margin = margin / 10
  #Line width (0.2 mm)
  @line_width = 0.57 / @k
  @linestyle_width ||= sprintf('%.2f w', (@line_width * @k))
  @linestyle_cap ||= '0 J'
  @linestyle_join ||= '0 j'
  @linestyle_dash ||= '[] 0 d'
  #Automatic page break
  SetAutoPageBreak(true, 2 * margin)
  #Full width display mode
  SetDisplayMode('fullwidth')
  #Compression
  SetCompression(true)
  #Set default PDF version number
  @pdf_version ||= "1.7"
  @encoding = encoding
  @href ||= {}
  @fontlist ||= []
  getFontsList()
  @fgcolor = ActiveSupport::OrderedHash.new
  @fgcolor['R'] = 0
  @fgcolor['G'] = 0
  @fgcolor['B'] = 0
  @strokecolor = ActiveSupport::OrderedHash.new
  @strokecolor['R'] = 0
  @strokecolor['G'] = 0
  @strokecolor['B'] = 0
  @bgcolor = ActiveSupport::OrderedHash.new
  @bgcolor['R'] = 255
  @bgcolor['G'] = 255
  @bgcolor['B'] = 255
  @extgstates ||= []

  # user's rights
  @sign ||= false
  @ur = false
  @ur_document = "/FullSave"
  @ur_annots = "/Create/Delete/Modify/Copy/Import/Export"
  @ur_form = "/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate"
  @ur_signature = "/Modify"

  # set default JPEG quality
  @jpeg_quality ||= 75

  # initialize some settings
#    utf8Bidi([''], '')
  # set default font
  SetFont(@font_family, @font_style, @font_size_pt)

  @annots_start_obj_id ||= 200000
  @annot_obj_id ||= @annots_start_obj_id
  @curr_annot_obj_id ||= @annots_start_obj_id
  @apxo_obj_id ||= @apxo_start_obj_id
  @objcopy ||= nil
end

Instance Attribute Details

#barcodeObject

Returns the value of attribute barcode.



151
152
153
# File 'lib/rbpdf.rb', line 151

def barcode
  @barcode
end

#bufferObject

Returns the value of attribute buffer.



153
154
155
# File 'lib/rbpdf.rb', line 153

def buffer
  @buffer
end

#cache_file_lengthObject

Returns the value of attribute cache_file_length.



229
230
231
# File 'lib/rbpdf.rb', line 229

def cache_file_length
  @cache_file_length
end

#color_flagObject

Returns the value of attribute color_flag.



157
158
159
# File 'lib/rbpdf.rb', line 157

def color_flag
  @color_flag
end

#default_fontObject

Returns the value of attribute default_font.



159
160
161
# File 'lib/rbpdf.rb', line 159

def default_font
  @default_font
end

#diffsObject

Returns the value of attribute diffs.



155
156
157
# File 'lib/rbpdf.rb', line 155

def diffs
  @diffs
end

#diskcacheObject

Returns the value of attribute diskcache.



227
228
229
# File 'lib/rbpdf.rb', line 227

def diskcache
  @diskcache
end

#draw_colorObject

Returns the value of attribute draw_color.



161
162
163
# File 'lib/rbpdf.rb', line 161

def draw_color
  @draw_color
end

#encodingObject

Returns the value of attribute encoding.



163
164
165
# File 'lib/rbpdf.rb', line 163

def encoding
  @encoding
end

#fill_colorObject

Returns the value of attribute fill_color.



165
166
167
# File 'lib/rbpdf.rb', line 165

def fill_color
  @fill_color
end

#font_familyObject

Returns the value of attribute font_family.



169
170
171
# File 'lib/rbpdf.rb', line 169

def font_family
  @font_family
end

#font_filesObject

Returns the value of attribute font_files.



171
172
173
# File 'lib/rbpdf.rb', line 171

def font_files
  @font_files
end

#font_size_ptObject

Returns the value of attribute font_size_pt.



177
178
179
# File 'lib/rbpdf.rb', line 177

def font_size_pt
  @font_size_pt
end

#font_styleObject

Returns the value of attribute font_style.



175
176
177
# File 'lib/rbpdf.rb', line 175

def font_style
  @font_style
end

#fontsObject

Returns the value of attribute fonts.



167
168
169
# File 'lib/rbpdf.rb', line 167

def fonts
  @fonts
end

#header_logoObject

Returns the value of attribute header_logo.



181
182
183
# File 'lib/rbpdf.rb', line 181

def 
  @header_logo
end

#header_logo_widthObject

Returns the value of attribute header_logo_width.



183
184
185
# File 'lib/rbpdf.rb', line 183

def header_logo_width
  @header_logo_width
end

#header_stringObject

Returns the value of attribute header_string.



187
188
189
# File 'lib/rbpdf.rb', line 187

def header_string
  @header_string
end

#header_titleObject

Returns the value of attribute header_title.



185
186
187
# File 'lib/rbpdf.rb', line 185

def header_title
  @header_title
end

#header_widthObject

Returns the value of attribute header_width.



179
180
181
# File 'lib/rbpdf.rb', line 179

def header_width
  @header_width
end

#imagesObject

Returns the value of attribute images.



189
190
191
# File 'lib/rbpdf.rb', line 189

def images
  @images
end

#img_scaleObject

Returns the value of attribute img_scale.



191
192
193
# File 'lib/rbpdf.rb', line 191

def img_scale
  @img_scale
end

Returns the value of attribute in_footer.



193
194
195
# File 'lib/rbpdf.rb', line 193

def in_footer
  @in_footer
end

#is_unicodeObject

Returns the value of attribute is_unicode.



195
196
197
# File 'lib/rbpdf.rb', line 195

def is_unicode
  @is_unicode
end

#lasthObject

Returns the value of attribute lasth.



197
198
199
# File 'lib/rbpdf.rb', line 197

def lasth
  @lasth
end

Returns the value of attribute links.



199
200
201
# File 'lib/rbpdf.rb', line 199

def links
  @links
end

#lispacerObject

Returns the value of attribute lispacer.



205
206
207
# File 'lib/rbpdf.rb', line 205

def lispacer
  @lispacer
end

#listcountObject

Returns the value of attribute listcount.



203
204
205
# File 'lib/rbpdf.rb', line 203

def listcount
  @listcount
end

#listorderedObject

Returns the value of attribute listordered.



201
202
203
# File 'lib/rbpdf.rb', line 201

def listordered
  @listordered
end

#nObject

Returns the value of attribute n.



207
208
209
# File 'lib/rbpdf.rb', line 207

def n
  @n
end

#offsetsObject

Returns the value of attribute offsets.



209
210
211
# File 'lib/rbpdf.rb', line 209

def offsets
  @offsets
end

#pageObject

Returns the value of attribute page.



211
212
213
# File 'lib/rbpdf.rb', line 211

def page
  @page
end

#pagesObject

Returns the value of attribute pages.



213
214
215
# File 'lib/rbpdf.rb', line 213

def pages
  @pages
end

#pdf_versionObject

Returns the value of attribute pdf_version.



215
216
217
# File 'lib/rbpdf.rb', line 215

def pdf_version
  @pdf_version
end

#prev_pagesObject

Returns the value of attribute prev_pages.



231
232
233
# File 'lib/rbpdf.rb', line 231

def prev_pages
  @prev_pages
end

Returns the value of attribute print_footer.



219
220
221
# File 'lib/rbpdf.rb', line 219

def print_footer
  @print_footer
end

Returns the value of attribute print_header.



217
218
219
# File 'lib/rbpdf.rb', line 217

def print_header
  @print_header
end

#stateObject

Returns the value of attribute state.



221
222
223
# File 'lib/rbpdf.rb', line 221

def state
  @state
end

#text_colorObject

Returns the value of attribute text_color.



223
224
225
# File 'lib/rbpdf.rb', line 223

def text_color
  @text_color
end

#underlineObject

Returns the value of attribute underline.



225
226
227
# File 'lib/rbpdf.rb', line 225

def underline
  @underline
end

Instance Method Details

#AcceptPageBreakObject Also known as: accept_page_break

Whenever a page break condition is met, the method is called, and the break is issued or not depending on the returned value. The default implementation returns a value according to the mode selected by SetAutoPageBreak(). This method is called automatically and should not be called directly by the application.

@return boolean
@access public
@since 1.4
@see

SetAutoPageBreak()



3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
# File 'lib/rbpdf.rb', line 3246

def AcceptPageBreak()
  #if @num_columns > 1
  #  # multi column mode
  #  if @current_column < (@num_columns - 1)
  #    # go to next column
  #    selectColumn(@current_column + 1)
  #  else
  #    # add a new page
  #    AddPage()
  #    # set first column
  #    selectColumn(0)
  #  end
  #  # avoid page breaking from checkPageBreak()
  #  return false
  #end
  return @auto_page_break;
end

#AddFont(family, style = '', fontfile = '', subset = nil) ⇒ Object Also known as: add_font

Imports a TrueType, Type1, core, or CID0 font and makes it available. It is necessary to generate a font definition file first with the makefont.rb utility. The definition file (and the font file itself when embedding) must be present either in the current directory or in the one indicated by FPDF_FONTPATH if the constant is defined. If it could not be found, the error “Could not include font definition file” is generated.

Example

:pdf.add_font('Comic','I')
# is equivalent to:
:pdf.add_font('Comic','I','comici.rb')
@param string :family

Font family. The name can be chosen arbitrarily. If it is a standard family name, it will override the corresponding font.

@param string :style

Font style. Possible values are (case insensitive):

  • empty string: regular (default)

  • B: bold

  • I: italic

  • BI or IB: bold italic

@param string :fontfile

The font definition file. By default, the name is built from the family and style, in lower case with no space.

@return array

containing the font data, or false in case of error.

@param boolean :subset

if true embedd only a subset of the font (stores only the information related to the used characters); this option is valid only for TrueTypeUnicode fonts. If you want to enable users to change the document, set this parameter to false. If you subset the font, the person who receives your PDF would need to have your same font in order to make changes to your PDF. The file size of the PDF would also be smaller because you are embedding only part of a font.

@access public
@since 1.5
@see

SetFont()



2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
# File 'lib/rbpdf.rb', line 2652

def AddFont(family, style='', fontfile='', subset=nil)
  if empty_string(family)
    if !empty_string(@font_family)
      family = @font_family
    else
      Error('Empty font family')
    end
  end
  subset = @font_subsetting if subset.nil?

  family = family.downcase
  if ((!@is_unicode) and (family == 'arial'))
    family = 'helvetica';
  end
  if (family == "symbol") or (family == "zapfdingbats")
    style = ''
  end

  tempstyle = style.upcase
  style = ''
  # underline
  if tempstyle.index('U') != nil
    @underline = true
  else
    @underline = false
  end
  # line-through (deleted)
  if tempstyle.index('D') != nil
    @linethrough = true
  else
    @linethrough = false
  end
  # overline
  if tempstyle.index('O') != nil
    @overline = true
  else
    @overline = false
  end
  # bold
  if tempstyle.index('B') != nil
    style << 'B';
  end
  # oblique
  if tempstyle.index('I') != nil
    style << 'I';
  end
  bistyle = style
  fontkey = family + style;
  font_style = style + (@underline ? 'U' : '') + (@linethrough ? 'D' : '') + (@overline ? 'O' : '')
  fontdata = {'fontkey' => fontkey, 'family' => family, 'style' => font_style}
  # check if the font has been already added
  if getFontBuffer(fontkey) != false
    return fontdata
  end

  # get specified font directory (if any)
  fontdir = false
  if !empty_string(fontfile)
    fontdir = File.dirname(fontfile)
    if empty_string(fontdir) or (fontdir == '.')
      fontdir = ''
    else
      fontdir << '/'
    end
  end

  fontname = family.gsub(' ', '') + style.downcase

  # search and include font file
  if empty_string(fontfile)
    # build a standard filenames for specified font
    fontfile1 = fontname + '.rb'
    fontfile2 = family.gsub(' ', '') + '.rb'
    # search files on various directories
    if (fontdir != false) and File.exist?(fontdir + fontfile1)
      fontfile = fontdir + fontfile1
      fontname = fontfile1
    elsif fontfile = getfontpath(fontfile1)
      fontname = fontfile1
    elsif File.exist?(fontfile1)
      fontfile = fontfile1
      fontname = fontfile1
    elsif (fontdir != false) and File.exist?(fontdir + fontfile2)
      fontfile = fontdir + fontfile2
      fontname = fontfile2
    elsif fontfile = getfontpath(fontfile2)
      fontname = fontfile2
    else
      fontfile = fontfile2
      fontname = fontfile2
    end
  end

  # include font file
  if File.exist?(fontfile)
    require(fontfile)
  else
    Error('Could not include font definition file: ' + family + '')
  end

  font_desc = RBPDFFontDescriptor.font(fontname).dup
  if font_desc[:desc].nil?
    desc = {}
  else
    desc = font_desc[:desc].dup
  end

  # check font parameters
  if font_desc[:type].nil? or font_desc[:cw].nil?
    Error('The font definition file has a bad format: ' + fontfile + '')
  end

  # SET default parameters
  font_desc[:file] ||= ''
  font_desc[:enc] ||= ''
  if font_desc[:cidinfo].nil?
    font_desc[:cidinfo] = {'Registry'=>'Adobe', 'Ordering'=>'Identity', 'Supplement'=>0}
    font_desc[:cidinfo]['uni2cid'] = {}
  end
  font_desc[:ctg] ||= ''
  font_desc[:up] ||= -100
  font_desc[:ut] ||= 50
  font_desc[:cw] ||= {}

  if empty_string(font_desc[:dw])
    # set default width
    if !desc['MissingWidth'].nil? and (desc['MissingWidth'] > 0)
      font_desc[:dw] = desc['MissingWidth']
    elsif font_desc[:cw][32]
      font_desc[:dw] = font_desc[:cw][32]
    else
      font_desc[:dw] = 600
    end
  end

  @numfonts += 1
  if font_desc[:type] == 'cidfont0'
    #  register CID font (all styles at once)
    styles = {'' => '', 'B' => ',Bold', 'I' => ',Italic', 'BI' => ',BoldItalic'}
    font_desc[:name] = font_desc[:name] + styles[bistyle]
    # artificial bold
    if bistyle.index('B') != nil
      if desc['StemV']
        desc['StemV'] *= 2
      else
        desc['StemV'] = 120
      end
    end
    # artificial italic
    if bistyle.index('I') != nil
      if desc['ItalicAngle']
        desc['ItalicAngle'] -= 11
      else
        desc['ItalicAngle'] = -11
      end
    end
  elsif font_desc[:type] == 'core'
    font_desc[:name] = @core_fonts[fontkey]
    subset = false
  elsif (font_desc[:type] == 'TrueType') or (font_desc[:type] == 'Type1')
    # ...
    subset = false
  elsif font_desc[:type] == 'TrueTypeUnicode'
    font_desc[:enc] = 'Identity-H'
  else
    Error('Unknow font type: ' + font_desc[:type] + '')
  end
  # initialize subsetchars to contain default ASCII values (0-255)
  subsetchars = Array.new(256, true)

  setFontBuffer(fontkey, {'fontkey' => fontkey, 'i' => @numfonts, 'type' => font_desc[:type], 'name' => font_desc[:name], 'desc' => desc, 'up' => font_desc[:up], 'ut' => font_desc[:ut], 'cw' => font_desc[:cw], 'dw' => font_desc[:dw], 'enc' => font_desc[:enc], 'cidinfo' => font_desc[:cidinfo], 'file' => font_desc[:file], 'ctg' => font_desc[:ctg], 'subset' => subset, 'subsetchars' => subsetchars})

  if (!font_desc[:diff].nil? and (!font_desc[:diff].empty?))
    #Search existing encodings
    d=0;
    nb=@diffs.length;
    1.upto(nb) do |i|
      if (@diffs[i]== font_desc[:diff])
        d = i;
        break;
      end
    end
    if (d==0)
      d = nb+1;
      @diffs[d] = font_desc[:diff];
    end
    setFontSubBuffer(fontkey, 'diff', d)
  end
  if !empty_string(font_desc[:file])
    if @font_files[font_desc[:file]].nil?
      if (font_desc[:type] == 'TrueType') or (font_desc[:type] == 'TrueTypeUnicode')
        @font_files[font_desc[:file]] = {'length1' => font_desc[:originalsize], 'fontdir' => fontdir, 'subset' => subset, 'fontkeys' => [fontkey]}
      elsif font_desc[:type] != 'core'
        @font_files[font_desc[:file]] = {'length1' => font_desc[:size1], 'length2' => font_desc[:size2], 'fontdir' => fontdir, 'subset' => subset, 'fontkeys' => [fontkey]}
      end
    else
      # update fontkeys that are sharing this font file
      @font_files[font_desc[:file]]['subset'] = (@font_files[font_desc[:file]]['subset'] and subset)
      unless @font_files[font_desc[:file]]['fontkeys'].include? fontkey
        @font_files[font_desc[:file]]['fontkeys'] ||= []
        @font_files[font_desc[:file]]['fontkeys'].push fontkey
      end
    end
  end
  return fontdata
end

#addHtmlAnchor(anchor) ⇒ Object Also known as: add_html_anchor

Adds HTML anchor and remembers it’s position

@param string :anchor

html anchor id

@access public


8648
8649
8650
# File 'lib/rbpdf.rb', line 8648

def addHtmlAnchor(anchor)
  @html_anchors[anchor] = [@page, @y]
end

Output anchor link.

@param string :url

link URL or internal link (i.e.: <a href=“#23”>link to page 23</a>)

@param string :name

link name

@param int :fill

Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.

@param boolean :firstline

if true prints only the first line and return the remaining string.

@param array :color

array of RGB text color

@param string :style

font style (U, D, B, I)

@param boolean :firstblock

if true the string is the starting of a line.

@return

the number of cells used or the remaining text if :firstline = true

@access public


8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
# File 'lib/rbpdf.rb', line 8613

def addHtmlLink(url, name, fill=0, firstline=false, color='', style=-1, firstblock=false)
  if !empty_string(url) and (url[0, 1] == '#')
    # convert url to internal link
    anchor = url.sub(/^#/, "")
    page = anchor.to_i
    url = AddLink()
    @html_anchor_links[url] = anchor
    SetLink(url, 0, page)
  end
  # store current settings
  prevcolor = @fgcolor
  prevstyle = @font_style
  if color.empty?
    SetTextColorArray(@html_link_color_array)
  else
    SetTextColorArray(color)
  end
  if style == -1
    SetFont('', @font_style + @html_link_font_style)
  else
    SetFont('', @font_style + style)
  end
  ret = Write(@lasth, name, url, fill, '', false, 0, firstline, firstblock, 0)
  # restore settings
  SetFont('', prevstyle)
  SetTextColorArray(prevcolor)
  return ret
end

#addHTMLTOC(page = '', toc_name = 'TOC', templates = [], correct_align = true) ⇒ Object Also known as: add_html_toc

Output a Table Of Content Index (TOC) using HTML templates. Before calling this method you have to open the page using the addTOCPage() method. After calling this method you have to call endTOCPage() to close the TOC page.

@param int :page

page number where this TOC should be inserted (leave empty for current page).

@param string :toc_name

name to use for TOC bookmark.

@param array :templates

array of html templates. Use: #TOC_DESCRIPTION# for bookmark title, #TOC_PAGE_NUMBER# for page number.

@parma boolean :correct_align

if true correct the number alignment (numbers must be in monospaced font like courier and right aligned on LTR, or left aligned on RTL)

@access public
@author

Nicola Asuni

@since 5.0.001 (2010-05-06)
@see

addTOCPage(), endTOCPage(), addTOC()



16198
16199
16200
16201
16202
16203
16204
16205
16206
16207
16208
16209
16210
16211
16212
16213
16214
16215
16216
16217
16218
16219
16220
16221
16222
16223
16224
16225
16226
16227
16228
16229
16230
16231
16232
16233
16234
16235
16236
16237
16238
16239
16240
16241
16242
16243
16244
16245
16246
16247
16248
16249
16250
16251
16252
16253
16254
16255
16256
16257
16258
16259
16260
16261
16262
16263
16264
16265
16266
16267
16268
16269
16270
16271
16272
16273
16274
16275
16276
16277
16278
16279
16280
16281
16282
16283
16284
16285
16286
16287
16288
16289
16290
# File 'lib/rbpdf.rb', line 16198

def addHTMLTOC(page='', toc_name='TOC', templates=[], correct_align=true)
  prev_htmlLinkColorArray = @html_link_color_array
  prev_htmlLinkFontStyle = @html_link_font_style
  # set new style for link
  @html_link_color_array = []
  @html_link_font_style = ''
  page_first = getPage()
  # sort outlines by page and original position
  @outlines = @outlines.sort_by {|x| [x[:p], x[:y]] }
  @outlines.each_with_index do |outline, key|
    if empty_string(page)
      pagenum = outline[:p].to_s
    else
      # placemark to be replaced with the correct number
      pagenum = '{#' + outline[:p].to_s + '}'
      if (@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont0')
        pagenum = '{' + pagenum + '}'
      end
    end
    # get HTML template
    row = templates[outline[:l]]
    # replace templates with current values
    row = row.gsub('#TOC_DESCRIPTION#', outline[:t])
    row = row.gsub('#TOC_PAGE_NUMBER#', pagenum)
    # add link to page
    row = '<a href="#' + outline[:p].to_s + '">' + row + '</a>'
    # write bookmark entry
    writeHTML(row, false, false, true, false, '')
  end
  # restore link styles
  @html_link_color_array = prev_htmlLinkColorArray
  @html_link_font_style = prev_htmlLinkFontStyle
  # move TOC page and replace numbers
  page_last = getPage()
  numpages = page_last - page_first + 1
  if !empty_string(page)
    page_first.upto(page_last) do |p|
      # get page data
      temppage = getPageBuffer(p)
      1.upto(@numpages) do |n|
        # update page numbers
        k = '{#' + n.to_s + '}'
        ku = '{' + k + '}'
        alias_a = escape(k)
        alias_au = escape('{' + k + '}')
        if @is_unicode
          alias_b = escape(UTF8ToLatin1(k))
          alias_bu = escape(UTF8ToLatin1(ku))
          alias_c = escape(utf8StrRev(k, false, rtl_text_dir))
          alias_cu = escape(utf8StrRev(ku, false, rtl_text_dir))
        end
        if n >= page
          np = n + numpages
        else
          np = n
        end
        ns = formatTOCPageNumber(np)
        nu = ns
        if correct_align
          sdiff = k.length - ns.length
          sdiffu = ku.length - ns.length
          sfill = ' ' * sdiff
          sfillu = ' ' * sdiffu
          if @rtl
            ns = ns + sfill
            nu = nu + sfillu
          else
            ns = sfill + ns
            nu = sfillu + nu
          end
        end
        nu = UTF8ToUTF16BE(nu, false)
        temppage = temppage.gsub(alias_au, nu)
        if @is_unicode
          temppage = temppage.gsub(alias_bu, nu)
          temppage = temppage.gsub(alias_cu, nu)
          temppage = temppage.gsub(alias_b, ns)
          temppage = temppage.gsub(alias_c, ns)
        end
        temppage = temppage.gsub(alias_a, ns)
      end
      # save changes
      setPageBuffer(p, temppage)
    end
    # move pages
    Bookmark(toc_name, 0, 0, page_first)
    0.upto(numpages - 1) do |i|
      movePage(page_last, page)
    end
  end
rescue => err
  Error('addHTMLTOC Error.', err)
end

#addJavascriptObject(script, onload = false) ⇒ Object

Adds a javascript object and return object ID

@param string :script

Javascript code

@param boolean :onload

if true executes this object when opening the document

@return int

internal object ID

@access public
@author Nicola Asuni
@since 4.8.000 (2009-09-07)


10450
10451
10452
10453
10454
# File 'lib/rbpdf.rb', line 10450

def addJavascriptObject(script, onload = false)
  @js_obj_id += 1
  @js_objects[@js_obj_id] = {'js' => script, 'onload' => onload}
  @js_obj_id
end

Creates a new internal link and returns its identifier. An internal link is a clickable area which directs to another place within the document. The identifier can then be passed to Cell(), Write(), Image() or Link(). The destination is defined with SetLink().

@access public
@since 1.5
@see

Cell(), Write(), Image(), Link(), SetLink()



3008
3009
3010
3011
3012
3013
# File 'lib/rbpdf.rb', line 3008

def AddLink()
  #Create a new internal link
  n = @links.length + 1
  @links[n]=[0,0];
  return n;
end

#AddPage(orientation = '', format = '', keepmargins = false, tocpage = false) ⇒ Object Also known as: add_page

Adds a new page to the document. If a page is already present, the Footer() method is called first to output the footer (if enabled). Then the page is added, the current position set to the top-left corner according to the left and top margins (or top-right if in RTL mode), and Header() is called to display the header (if enabled). The origin of the coordinate system is at the top-left corner (or top-right for RTL) and increasing ordinates go downwards.

@param string :orientation

page orientation. Possible values are (case insensitive):

  • P or PORTRAIT (default)

  • L or LANDSCAPE

@param mixed :format

The format used for pages. It can be either: A string indicating the page format:

  • 4A0,2A0,A0,A1,A2,A3,A4 (default),A5,A6,A7,A8,A9,A10

  • B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10

  • C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10

  • RA0,RA1,RA2,RA3,RA4

  • SRA0,SRA1,SRA2,SRA3,SRA4

  • LETTER,LEGAL,EXECUTIVE,FOLIO

An array containing page measures and advanced options: see setPageFormat()

@param boolean :keepmargins

if true overwrites the default page margins with the current margin

@param boolean :tocpage

if true set the tocpage state to true (the added page will be used to display Table Of Content).

@access public
@since 1.0
@see

startPage, endPage(), addTOCPage(), endTOCPage()



1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
# File 'lib/rbpdf.rb', line 1726

def AddPage(orientation='', format='', keepmargins=false, tocpage=false)
  if @original_l_margin.nil? or keepmargins
    @original_l_margin = @l_margin
  end
  if @original_r_margin.nil? or keepmargins
    @original_r_margin = @r_margin
  end
  # terminate previous page
  endPage()
  # start new page
  startPage(orientation, format, tocpage)
end

#AddSpotColor(name, c, m, y, k) ⇒ Object Also known as: add_spot_color

Defines a new spot color. It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.

@param int :c

Cyan color for CMYK. Value between 0 and 255

@param int :m

Magenta color for CMYK. Value between 0 and 255

@param int :y

Yellow color for CMYK. Value between 0 and 255

@param int :k

Key (Black) color for CMYK. Value between 0 and 255

@access public
@since 4.0.024 (2008-09-12)
@see

SetDrawSpotColor(), SetFillSpotColor(), SetTextSpotColor()



2244
2245
2246
2247
2248
2249
# File 'lib/rbpdf.rb', line 2244

def AddSpotColor(name, c, m, y, k)
  if @spot_colors[name].nil?
    i = 1 + @spot_colors.length
    @spot_colors[name] = {'i' => i, 'c' => c, 'm' => m, 'y' => y, 'k' => k}
  end
end

#addTOC(page = '', numbersfont = '', filler = '.', toc_name = 'TOC') ⇒ Object Also known as: add_toc

Output a Table of Content Index (TOC). Before calling this method you have to open the page using the addTOCPage() method. After calling this method you have to call endTOCPage() to close the TOC page. You can override this method to achieve different styles.

@param int :page

page number where this TOC should be inserted (leave empty for current page).

@param string :numbersfont

set the font for page numbers (please use monospaced font for better alignment).

@param string :filler

string used to fill the space between text and page number.

@param string :toc_name

name to use for TOC bookmark.

@access public
@author

Nicola Asuni

@since 4.5.000 (2009-01-02)
@see

addTOCPage(), endTOCPage(), addHTMLTOC()



16043
16044
16045
16046
16047
16048
16049
16050
16051
16052
16053
16054
16055
16056
16057
16058
16059
16060
16061
16062
16063
16064
16065
16066
16067
16068
16069
16070
16071
16072
16073
16074
16075
16076
16077
16078
16079
16080
16081
16082
16083
16084
16085
16086
16087
16088
16089
16090
16091
16092
16093
16094
16095
16096
16097
16098
16099
16100
16101
16102
16103
16104
16105
16106
16107
16108
16109
16110
16111
16112
16113
16114
16115
16116
16117
16118
16119
16120
16121
16122
16123
16124
16125
16126
16127
16128
16129
16130
16131
16132
16133
16134
16135
16136
16137
16138
16139
16140
16141
16142
16143
16144
16145
16146
16147
16148
16149
16150
16151
16152
16153
16154
16155
16156
16157
16158
16159
16160
16161
16162
16163
16164
16165
16166
16167
16168
16169
16170
16171
16172
16173
16174
16175
16176
16177
16178
16179
16180
16181
16182
# File 'lib/rbpdf.rb', line 16043

def addTOC(page='', numbersfont='', filler='.', toc_name='TOC')
  fontsize = @font_size_pt
  fontfamily = @font_family
  fontstyle = @font_style
  w = @w - @l_margin - @r_margin
  spacer = GetStringWidth(32.chr) * 4
  page_first = getPage()
  lmargin = @l_margin
  rmargin = @r_margin
  x_start = GetX()
  if empty_string(numbersfont)
    numbersfont = @default_monospaced_font
  end
  if empty_string(filler)
    filler = ' '
  end
  if empty_string(page)
    gap = ' '
  else
    gap = ''
  end
  # sort outlines by page and original position
  @outlines = @outlines.sort_by {|x| [x[:p], x[:y]] }
  @outlines.each_with_index do |outline, key|
    if @rtl
      aligntext = 'R'
      alignnum = 'L'
    else
      aligntext = 'L'
      alignnum = 'R'
    end
    if outline[:l] == 0
      SetFont(fontfamily, fontstyle + 'B', fontsize)
    else
      SetFont(fontfamily, fontstyle, fontsize - outline[:l])
    end
    indent = spacer * outline[:l]
    if @rtl
      @r_margin += indent
      @x -= indent
    else
      @l_margin += indent
      @x += indent
    end
    link = AddLink()
    SetLink(link, 0, outline[:p])
    # write the text
    Write(0, outline[:t], link, 0, aligntext, false, 0, false, false, 0)
    SetFont(numbersfont, fontstyle, fontsize)
    if empty_string(page)
      pagenum = outline[:p]
    else
      # placemark to be replaced with the correct number
      pagenum = '{#' + outline[:p].to_s + '}'
      if (@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont0')
        pagenum = '{' + pagenum + '}'
      end
    end
    numwidth = GetStringWidth(pagenum)
    if @rtl
      tw = @x - @l_margin
    else
      tw = @w - @r_margin - @x
    end
    fw = tw - numwidth - GetStringWidth(32.chr)
    numfills = (fw / GetStringWidth(filler)).floor
    if numfills > 0
      rowfill = filler * numfills
    else
      rowfill = ''
    end
    if @rtl
      pagenum = pagenum + gap + rowfill + ' '
    else
      pagenum = ' ' + rowfill + gap + pagenum
    end
    # write the number
    Cell(tw, 0, pagenum, 0, 1, alignnum, 0, link, 0)
    SetX(x_start)
    @l_margin = lmargin
    @r_margin = rmargin
  end
  page_last = getPage()
  numpages = page_last - page_first + 1
  if !empty_string(page)
    page_first.upto(page_last) do |p|
      # get page data
      temppage = getPageBuffer(p)
      1.upto(@numpages) do |n|
        # update page numbers
        k = '{#' + n.to_s + '}'
        ku = '{' + k + '}'
        alias_a = escape(k)
        alias_au = escape('{' + k + '}')
        if @is_unicode
          alias_b = escape(UTF8ToLatin1(k))
          alias_bu = escape(UTF8ToLatin1(ku))
          alias_c = escape(utf8StrRev(k, false, rtl_text_dir))
          alias_cu = escape(utf8StrRev(ku, false, rtl_text_dir))
        end
        if n >= page
          np = n + numpages
        else
          np = n
        end
        ns = formatTOCPageNumber(np)
        nu = ns
        sdiff = k.length - ns.length - 1
        sdiffu = ku.length - ns.length - 1
        sfill = filler * sdiff
        sfillu = filler * sdiffu
        if @rtl
          ns = ns + ' ' + sfill
          nu = nu + ' ' + sfillu
        else
          ns = sfill + ' ' + ns
          nu = sfillu + ' ' + nu
        end
        nu = UTF8ToUTF16BE(nu, false)
        temppage = temppage.gsub(alias_au, nu)
        if @is_unicode
          temppage = temppage.gsub(alias_bu, nu)
          temppage = temppage.gsub(alias_cu, nu)
          temppage = temppage.gsub(alias_b, ns)
          temppage = temppage.gsub(alias_c, ns)
        end
        temppage = temppage.gsub(alias_a, ns)
      end
      # save changes
      setPageBuffer(p, temppage)
    end
    # move pages
    Bookmark(toc_name, 0, 0, page_first)
    0.upto(numpages - 1) do |i|
      movePage(page_last, page)
    end
  end
rescue => err
  Error('addTOC Error.', err)
end

#addTOCPage(orientation = '', format = '', keepmargins = false) ⇒ Object Also known as: add_toc_page

Adds a new TOC (Table Of Content) page to the document.

@param string :orientation

page orientation.

@param boolean :keepmargins

if true overwrites the default page margins with the current margins

@access public
@since 5.0.001 (2010-05-06)
@see

AddPage(), startPage(), endPage(), endTOCPage()



1688
1689
1690
# File 'lib/rbpdf.rb', line 1688

def addTOCPage(orientation='', format='', keepmargins=false)
  AddPage(orientation, format, keepmargins, true)
end

#AliasNbPages(alias_nb = '{nb}') ⇒ Object Also known as: alias_nb_pages

Defines an alias for the total number of pages. It will be substituted as the document is closed.

@param string :alias

The alias.

@access public
@since 1.4
@see

getAliasNbPages(), PageNo(), Footer()



11373
11374
11375
# File 'lib/rbpdf.rb', line 11373

def AliasNbPages(alias_nb ='{nb}')
  @alias_nb_pages = alias_nb
end

#AliasNumPage(alias_num = '{pnb}') ⇒ Object Also known as: alias_num_page

Defines an alias for the page number. It will be substituted as the document is closed.

@param string :alias

The alias.

@access public
@since 4.5.000 (2009-01-02)
@see

getAliasNbPages(), PageNo(), Footer()



11402
11403
11404
11405
# File 'lib/rbpdf.rb', line 11402

def AliasNumPage(alias_num='{pnb}')
  # Define an alias for total number of pages
  @alias_num_page = alias_num
end

#Annotation(x, y, w, h, text, opt = {'Subtype'=>'Text'}, spaces = 0) ⇒ Object Also known as: annotation

Puts a markup annotation on a rectangular area of the page.

  • !!!!THE ANNOTATION SUPPORT IS NOT YET FULLY IMPLEMENTED !!!!

@param float :x

Abscissa of the upper-left corner of the rectangle

@param float :y

Ordinate of the upper-left corner of the rectangle

@param float :w

Width of the rectangle

@param float :h

Height of the rectangle

@param mixed :text

annotation text or alternate content

@param array :opt

array of options (see section 8.4 of PDF reference 1.7).

@param int :spaces

number of spaces on the text to link

@access public
@since 4.0.018 (2008-08-06)


3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
# File 'lib/rbpdf.rb', line 3067

def Annotation(x, y, w, h, text, opt={'Subtype'=>'Text'}, spaces=0)
  x = @x if x == ''
  y = @y if y == ''

  # recalculate coordinates to account for graphic transformations
  if !@transfmatrix.nil?
    @transfmatrix_key.downto(1) do |i|
      maxid = @transfmatrix[i].length - 1
      maxid.downto(0) do |j|
        ctm = @transfmatrix[i][j]
        if !ctm['a'].nil?
          x = x * @k
          y = (@h - y) * @k
          w = w * @k
          h = h * @k
          # top left
          xt = x
          yt = y
          x1 = (ctm['a'] * xt) + (ctm['c'] * yt) + ctm['e']
          y1 = (ctm['b'] * xt) + (ctm['d'] * yt) + ctm['f']
          # top right
          xt = x + w
          yt = y
          x2 = (ctm['a'] * xt) + (ctm['c'] * yt) + ctm['e']
          y2 = (ctm['b'] * xt) + (ctm['d'] * yt) + ctm['f']
          # bottom left
          xt = x
          yt = y - h
          x3 = (ctm['a'] * xt) + (ctm['c'] * yt) + ctm['e']
          y3 = (ctm['b'] * xt) + (ctm['d'] * yt) + ctm['f']
          # bottom right
          xt = x + w
          yt = y - h
          x4 = (ctm['a'] * xt) + (ctm['c'] * yt) + ctm['e']
          y4 = (ctm['b'] * xt) + (ctm['d'] * yt) + ctm['f']
          # new coordinates (rectangle area)
          x = [x1, x2, x3, x4].min
          y = [y1, y2, y3, y4].max
          w = ([x1, x2, x3, x4].max - x) / @k
          h = (y - [y1, y2, y3, y4].min) / @k
          x = x / @k
          y = @h - (y / @k)
        end
      end
    end
  end
  if @page <= 0
    page = 1
  else
    page = @page
  end
  @page_annots[page] ||= []
  @page_annots[page].push 'x' => x, 'y' => y, 'w' => w, 'h' => h, 'txt' => text, 'opt' => opt, 'numspaces' => spaces
  if ((opt['Subtype'] == 'FileAttachment') or (opt['Subtype'] == 'Sound')) and !empty_string(opt['FS']) and File.exist?(opt['FS']) and @embeddedfiles[File.basename(opt['FS'])].nil?
    @embeddedfiles[File.basename(opt['FS'])] = {'file' => opt['FS'], 'n' => (@embeddedfiles.length + @embedded_start_obj_id)}
  end
  # Add widgets annotation's icons
  if opt['mk'] and opt['mk']['i'] and File.exist?(opt['mk']['i'])
    Image(opt['mk']['i'], '', '', 10, 10, '', '', '', false, 300, '', false, false, 0, false, true)
  end
  if opt['mk'] and opt['mk']['ri'] and File.exist?(opt['mk']['ri'])
    Image(opt['mk']['ri'], '', '', 0, 0, '', '', '', false, 300, '', false, false, 0, false, true)
  end
  if opt['mk'] and opt['mk']['ix'] and File.exist?(opt['mk']['ix'])
    Image(opt['mk']['ix'], '', '', 0, 0, '', '', '', false, 300, '', false, false, 0, false, true)
  end
  @annot_obj_id += 1
end

#Arrow(x0, y0, x1, y1, head_style = 0, arm_size = 5, arm_angle = 15) ⇒ Object Also known as: arrow

Draws a grahic arrow.

@parameter float :x0

Abscissa of first point.

@parameter float :y0

Ordinate of first point.

@parameter float :x0

Abscissa of second point.

@parameter float :y1

Ordinate of second point.

@parameter int :head_style

(0 = draw only arrowhead arms, 1 = draw closed arrowhead, but no fill, 2 = closed and filled arrowhead, 3 = filled arrowhead)

@parameter float :arm_size

length of arrowhead arms

@parameter int :arm_angle

angle between an arm and the shaft

@author

Piotr Galecki, Nicola Asuni, Andy Meier

@access public
@since 4.6.018 (2009-07-10)


9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661
9662
9663
9664
9665
9666
9667
9668
9669
9670
9671
9672
9673
9674
9675
9676
9677
9678
9679
9680
9681
9682
9683
9684
9685
9686
9687
9688
9689
9690
9691
9692
# File 'lib/rbpdf.rb', line 9651

def Arrow(x0, y0, x1, y1, head_style=0, arm_size=5, arm_angle=15)
  # getting arrow direction angle
  # 0 deg angle is when both arms go along X axis. angle grows clockwise.
  dir_angle = ::Math.atan2(y0 - y1, x0 - x1)
  if dir_angle < 0
    dir_angle += 2 * ::Math::PI
  end
  arm_angle = arm_angle * ::Math::PI / 180 # deg2rad
  sx1 = x1
  sy1 = y1
  if head_style > 0
    # calculate the stopping point for the arrow shaft
    sx1 = x1 + (arm_size - @line_width) * ::Math.cos(dir_angle)
    sy1 = y1 + (arm_size - @line_width) * ::Math.sin(dir_angle)
  end
  # main arrow line / shaft
  Line(x0, y0, sx1, sy1)
  # left arrowhead arm tip
  x2L = x1 + (arm_size * ::Math.cos(dir_angle + arm_angle))
  y2L = y1 + (arm_size * ::Math.sin(dir_angle + arm_angle))
  # right arrowhead arm tip
  x2R = x1 + (arm_size * ::Math.cos(dir_angle - arm_angle))
  y2R = y1 + (arm_size * ::Math.sin(dir_angle - arm_angle))
  mode = 'D'
  style = []
  case head_style
  when 0
    # draw only arrowhead arms
    mode = 'D'
    style = [1, 1, 0]
  when 1
    # draw closed arrowhead, but no fill
    mode = 'D'
  when 2
    # closed and filled arrowhead
    mode = 'DF'
  when 3
    # filled arrowhead
    mode = 'F'
  end
  Polygon([x2L, y2L, x1, y1, x2R, y2R], mode, style, nil)
end

#Bookmark(txt, level = 0, y = -1,, page = nil) ⇒ Object Also known as: bookmark

Adds a bookmark.

@param string :txt

bookmark description.

@param int :level

bookmark level.

@param float :y

Ordinate of the boorkmark position (default = -1 = current position).

@param int :page

target page number (leave empty for current page).

@access public
@author

Olivier Plathey, Nicola Asuni

@since 2.1.002 (2008-02-12)


10342
10343
10344
10345
10346
10347
10348
10349
10350
10351
10352
10353
10354
10355
10356
10357
10358
10359
10360
10361
10362
# File 'lib/rbpdf.rb', line 10342

def Bookmark(txt, level=0, y=-1, page=nil)
  if level < 0
    level = 0
  end
  if @outlines[0]
    lastoutline = @outlines[-1]
    maxlevel = lastoutline[:l] + 1
  else
    maxlevel = 0
  end
  if level > maxlevel
    level = maxlevel
  end
  if y == -1
    y = GetY()
  end
  if page.nil?
    page = PageNo()
  end
  @outlines.push :t => txt, :l => level, :y => y, :p => page
end

#BreakThePage?(h) ⇒ Boolean Also known as: break_the_page?

Returns:

  • (Boolean)


3312
3313
3314
3315
3316
3317
3318
3319
# File 'lib/rbpdf.rb', line 3312

def BreakThePage?(h)
  warn "[DEPRECATION] 'BreakThePage/break_the_page' is deprecated. Please don't Use."
  if ((@y + h) > @page_break_trigger and !@in_footer and AcceptPageBreak())
    true
  else
    false
  end
end

#Button(name, w, h, caption, action, prop = {}, opt = {}, x = '', y = '', js = false) ⇒ Object Also known as: button

Creates a button field

@param string :name

field name

@param int :w

width

@param int :h

height

@param string :caption

caption.

@param mixed :action

action triggered by pressing the button. Use a string to specify a javascript action. Use an array to specify a form action options as on section 12.7.5 of PDF32000_2008.

@param array :prop

javascript field properties. Possible values are described on official Javascript for Acrobat API reference.

@param array :opt

annotation parameters. Possible values are described on official PDF32000_2008 reference.

@param float :x

Abscissa of the upper-left corner of the rectangle

@param float :y

Ordinate of the upper-left corner of the rectangle

@param boolean :js

if true put the field using JavaScript (requires Acrobat Writer to be rendered).

@access public
@author Nicola Asuni
@since 4.8.000 (2009-09-07)


11232
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
11260
11261
11262
11263
11264
11265
11266
11267
11268
11269
11270
11271
11272
11273
11274
11275
11276
11277
11278
11279
11280
11281
11282
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294
11295
11296
11297
11298
11299
11300
11301
11302
11303
11304
11305
11306
11307
11308
11309
11310
11311
11312
11313
11314
11315
11316
11317
11318
11319
11320
11321
11322
11323
11324
11325
11326
11327
11328
11329
11330
11331
11332
11333
11334
11335
11336
11337
11338
11339
11340
11341
11342
11343
11344
11345
# File 'lib/rbpdf.rb', line 11232

def Button(name, w, h, caption, action, prop = {}, opt = {}, x = '', y = '', js = false)
  x = @x if x == ''
  y = @y if y == ''

  if js
    addfield('button', name, x, y, w, h, prop)
    @javascript << "f#{name}.buttonSetCaption('#{caption}');\n"
    @javascript << "f#{name}.setAction('MouseUp','#{action}');\n"
    @javascript << "f#{name}.highlight='push';\n"
    @javascript << "f#{name}.print=false;\n"
    return
  end
  # get default style
  prop = getFormDefaultProp.merge prop
  prop['Pushbutton'] = 'true'
  prop['highlight'] = 'push'
  prop['display'] = 'display.noPrint'
  # get annotation data
  popt = getAnnotOptFromJSProp(prop)
  # set additional default options
  popt['mk'] ||= {}
  popt['mk']['ca'] = textstring(caption)
  popt['mk']['rc'] = textstring(caption)
  popt['mk']['ac'] = textstring(caption)
  font = @font_family
  fontkey = @fontkeys.index font
  unless @annotation_fonts.include? fontkey
    @annotation_fonts[font] = fontkey
  end
  fontstyle = sprintf('/F%d %.2f Tf %s', fontkey + 1, @font_size_pt, @text_color)
  popt['da'] = fontstyle
  popt['ap'] = {}
  # set Appearances
  popt['ap']['n'] = "/Tx BMC q #{fontstyle} 0.800 g\n"

  gvars = getGraphicVars()
  @h = h
  @w = w
  @c_margin *= 1.6

  @tmp_buffer = ''
  SetLineStyle({'width' => 1.0, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => [231]})
  SetFillColor(204)
  multi_cell(w, h, caption, 1, 'C', 1, 0, 0, 0, true)
  popt['ap']['n'] << @tmp_buffer
  popt['ap']['n'] << 'Q EMC'
  @tmp_buffer = nil

  # restore previous values
  setGraphicVars(gvars, true)

  # merge options
  opt = popt.merge opt
  # set remaining annotation data
  opt['Subtype'] = 'Widget'
  opt['ft'] = 'Btn'
  opt['t'] = caption
  opt['v'] = name
  unless action.empty?
    if action.is_a?(Hash)
      # form action options as on section 12.7.5 of PDF32000_2008.
      opt['aa'] = '/D <<'
      bmode = ['SubmitForm', 'ResetForm', 'ImportData']
      action.each {|key, val|
        if (key == 'S') && bmode.include?(val)
          opt['aa'] << " /S /#{val}"
        elsif (key == 'F') && !val.empty?
          opt['aa'] << " /F #{datastring(val)}"
        elsif (key == 'Fields') && val.is_a?(Array) && !val.empty?
          opt['aa'] << ' /Fields ['
          val.each {|field|
            opt['aa'] << " #{textstring(field)}"
          }
          opt['aa'] << ']'
        elsif key == 'Flags'
          ff = 0
          if val.is_a?(Array)
            val.each {|flag|
              case flag
              when 'Include/Exclude';      ff |= 1 << 0
              when 'IncludeNoValueFields'; ff |= 1 << 1
              when 'ExportFormat';         ff |= 1 << 2
              when 'GetMethod';            ff |= 1 << 3
              when 'SubmitCoordinates';    ff |= 1 << 4
              when 'XFDF';                 ff |= 1 << 5
              when 'IncludeAppendSaves';   ff |= 1 << 6
              when 'IncludeAnnotations';   ff |= 1 << 7
              when 'SubmitPDF';            ff |= 1 << 8
              when 'CanonicalFormat';      ff |= 1 << 9
              when 'ExclNonUserAnnots';    ff |= 1 << 10
              when 'ExclFKey';             ff |= 1 << 11
              when 'EmbedForm';            ff |= 1 << 13
              end
            }
          else
            ff = val.to_i
          end
          opt['aa'] << " /Flags #{ff}"
        end
      }
      opt['aa'] << ' >>'
    else
      # Javascript action or raw action command
      js_obj_id = addJavascriptObject(action)
      opt['aa'] = "/D #{js_obj_id} 0 R"
    end
  end
  Annotation(x, y, w, h, name, opt, 0)
  if @rtl
    @x -= w
  else
    @x += w
  end
end

#Cell(w, h = 0, txt = '', border = 0, ln = 0, align = '', fill = 0, link = nil, stretch = 0, ignore_min_height = false, calign = 'T', valign = 'M') ⇒ Object Also known as: cell

Prints a cell (rectangular area) with optional borders, background color and character string. The upper-left corner of the cell corresponds to the current position. The text can be aligned or centered. After the call, the current position moves to the right or to the next line. It is possible to put a link on the text. If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting.

@param float :w

Cell width. If 0, the cell extends up to the right margin.

@param float :h

Cell height. Default value: 0.

@param string :txt

String to print. Default value: empty string.

@param mixed :border

Indicates if borders must be drawn around the cell. The value can be either a number:

  • 0: no border (default)

  • 1: frame

or a string containing some or all of the following characters (in any order):

  • L: left

  • T: top

  • R: right

  • B: bottom

@param int :ln

Indicates where the current position should go after the call. Possible values are:

  • 0: to the right

  • 1: to the beginning of the next line

  • 2: below

Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.

@param string :align

Allows to center or align the text. Possible values are:

  • L or empty string: left align (default value)

  • C: center

  • R: right align

@param int :fill

Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.

@param mixed :link

URL or identifier returned by AddLink().

@param int :stretch

stretch carachter mode:

  • 0 = disabled

  • 1 = horizontal scaling only if necessary

  • 2 = forced horizontal scaling

  • 3 = character spacing only if necessary

  • 4 = forced character spacing

@param boolean :ignore_min_height

if true ignore automatic minimum height value.

@param string :calign

cell vertical alignment relative to the specified Y value. Possible values are:

  • T : cell top

  • C : center

  • B : cell bottom

  • A : font top

  • L : font baseline

  • D : font bottom

@param string :valign

text vertical alignment inside the cell. Possible values are:

  • T : top

  • M : middle

  • B : bottom

@access public
@since 1.0
@see

SetFont(), SetDrawColor(), SetFillColor(), SetTextColor(), SetLineWidth(), AddLink(), Ln(), MultiCell(), Write(), SetAutoPageBreak()



3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
# File 'lib/rbpdf.rb', line 3403

def Cell(w, h=0, txt='', border=0, ln=0, align='', fill=0, link=nil, stretch=0, ignore_min_height=false, calign='T', valign='M')
  if !ignore_min_height
    min_cell_height = @font_size * @cell_height_ratio
    if h < min_cell_height
      h = min_cell_height
    end
  end
  checkPageBreak(h)
  out(getCellCode(w, h, txt, border, ln, align, fill, link, stretch, ignore_min_height, calign, valign))
rescue => err
  Error('Cell Error.', err)
end

#CheckBox(name, w, checked = false, prop = {}, opt = {}, onvalue = 'Yes', x = '', y = '', js = false) ⇒ Object Also known as: check_box

Creates a CheckBox field

@param string :name

field name

@param int :w

width

@param boolean :checked

define the initial state.

@param array :prop

javascript field properties. Possible values are described on official Javascript for Acrobat API reference.

@param array :opt

annotation parameters. Possible values are described on official PDF32000_2008 reference.

@param string :onvalue

value to be returned if selected.

@param float :x

Abscissa of the upper-left corner of the rectangle

@param float :y

Ordinate of the upper-left corner of the rectangle

@param boolean :js

if true put the field using JavaScript (requires Acrobat Writer to be rendered).

@access public
@author Nicola Asuni
@since 4.8.000 (2009-09-07)


11161
11162
11163
11164
11165
11166
11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182
11183
11184
11185
11186
11187
11188
11189
11190
11191
11192
11193
11194
11195
11196
11197
11198
11199
11200
11201
11202
11203
11204
11205
11206
11207
11208
11209
11210
11211
11212
11213
# File 'lib/rbpdf.rb', line 11161

def CheckBox(name, w, checked=false, prop = {}, opt = {}, onvalue = 'Yes', x = '', y = '', js = false)
  x = @x if x == ''
  y = @y if y == ''

  if js
    addfield('checkbox', name, x, y, w, w, prop)
    return
  end

  prop['value'] ||= ['Yes']
  # get default style
  prop = getFormDefaultProp.merge prop
  prop['borderStyle'] = 'inset'
  # get annotation data
  popt = getAnnotOptFromJSProp(prop)
  # set additional default options
  font = 'zapfdingbats'
  AddFont(font)
  fontkey = @fontkeys.index font
  unless @annotation_fonts.include? fontkey
    @annotation_fonts[font] = fontkey
  end
  fontstyle = sprintf('/F%d %.2f Tf', fontkey + 1, @font_size_pt)
  popt['da'] = "#{fontstyle} #{@text_color}"
  popt['ap'] = {}
  popt['ap']['n'] = {}
  popt['ap']['n']['Yes'] = "q #{@text_color} BT #{fontstyle} 0 0 Td (n) Tj ET Q"
  popt['ap']['n']['Off'] = "q #{@text_color} BT #{fontstyle} 0 0 Td (o) Tj ET Q"

  # merge options
  opt = popt.merge opt
  # set remaining annotation data
  opt['Subtype'] = 'Widget'
  opt['ft'] = 'Btn'
  opt['t'] = name
  if empty_string(onvalue)
    onvalue = 'Yes'
  end
  opt['opt'] = [onvalue]
  if checked
    opt['v'] = ['/Yes']
    opt['as'] = 'Yes'
  else
    opt['v'] = ['/Off']
    opt['as'] = 'Off'
  end
  Annotation(x, y, w, w, name, opt, 0)
  if @rtl
    @x -= w
  else
    @x += w
  end
end

#Circle(x0, y0, r, angstr = 0, angend = 360, style = '', line_style = nil, fill_color = nil, nc = 2) ⇒ Object Also known as: circle

Draws a circle. A circle is formed from n Bezier curves.

@param float :x0

Abscissa of center point.

@param float :y0

Ordinate of center point.

@param float :r

Radius.

@param float :angstr

Angle start of draw line. Default value: 0.

@param float :angend

Angle finish of draw line. Default value: 360.

@param string :style

Style of rendering. See the getPathPaintOperator() function for more information.

@param array :line_style

Line style of circle. Array like for SetLineStyle SetLineStyle. Default value: default line style (empty array).

@param array :fill_color

Fill color. Format: array(red, green, blue). Default value: default color (empty array).

@param integer :nc

Number of curves used to draw a 90 degrees portion of circle.

@access public
@since 2.1.000 (2008-01-08)


9329
9330
9331
# File 'lib/rbpdf.rb', line 9329

def Circle(x0, y0, r, angstr=0, angend=360, style='', line_style=nil, fill_color=nil, nc=2)
  Ellipse(x0, y0, r, r, 0, angstr, angend, style, line_style, fill_color, nc)
end

#CloseObject

Terminates the PDF document. It is not necessary to call this method explicitly because Output() does it automatically. If the document contains no page, AddPage() is called to prevent from getting an invalid document.

@since 1.0
@see

Open(), Output()



1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
# File 'lib/rbpdf.rb', line 1562

def Close()
  #Terminate document
  if (@state==3)
    return;
  end
  if (@page==0)
    AddPage();
  end
  # close page
  endPage()
  lastPage()
  resetLinksAfterCurrentPage()

  @state = 2
  SetAutoPageBreak(false)
  @y = @h - (1 / @k)
  @r_margin = 0
  out('q')
  setVisibility('screen')
  SetFont('helvetica', '', 1)
  SetTextColor(127,127,127)
  setAlpha(0)
  msg = "\x50\x6f\x77\x65\x72\x65\x64\x20\x62\x79\x20\x54\x43\x50\x44\x46\x20\x28\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67\x29"
  lnk = "\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67"
  Cell(0, 0, msg, 0, 0, 'R', 0, lnk, 0, false, 'D', 'B')
  out('Q')
  setVisibility('all')
  @state = 1
  # close document
  enddoc();
end

#ComboBox(name, w, h, values, prop = {}, opt = {}, x = '', y = '', js = false) ⇒ Object Also known as: combo_box

Creates a Combo-box field

@param string :name

field name

@param int :w

width

@param int :h

height

@param array :values

array containing the list of values.

@param array :prop

javascript field properties. Possible values are described on official Javascript for Acrobat API reference.

@param array :opt

annotation parameters. Possible values are described on official PDF32000_2008 reference.

@param float :x

Abscissa of the upper-left corner of the rectangle

@param float :y

Ordinate of the upper-left corner of the rectangle

@param boolean :js

if true put the field using JavaScript (requires Acrobat Writer to be rendered).

@access public
@author Nicola Asuni
@since 4.8.000 (2009-09-07)


11073
11074
11075
11076
11077
11078
11079
11080
11081
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11095
11096
11097
11098
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124
11125
11126
11127
11128
11129
11130
11131
11132
11133
11134
11135
11136
11137
11138
11139
11140
11141
11142
11143
# File 'lib/rbpdf.rb', line 11073

def ComboBox(name, w, h, values, prop = {}, opt = {}, x = '', y = '', js = false)
  x = @x if x == ''
  y = @y if y == ''

  if js
    addfield('combobox', name, x, y, w, h, prop)
    s = ''
    values.each {|v|
      if v.is_a?(Array)
        s << "['#{v[0]}','#{v[1]}'],"
      else
        s << "'#{v}',"
      end
    }
    @javascript << "f#{name}.setItems([#{s[0...-1]}]);\n"
    return
  end
  # get default style
  prop = getFormDefaultProp.merge prop
  prop['Combo'] = 'true'
  # get annotation data
  popt = getAnnotOptFromJSProp(prop)
  # set additional default options
  font = @font_family
  fontkey = @fontkeys.index font
  unless @annotation_fonts.include? fontkey
    @annotation_fonts[font] = fontkey
  end

  s = ''
  values.each {|v|
    if v.is_a?(Array)
      s << "#{v[1]}\n"
    else
      s << "#{v}\n"
    end
  }
  fontstyle = sprintf('/F%d %.2f Tf %s', fontkey + 1, @font_size_pt, @text_color)
  popt['da'] = fontstyle
  popt['ap'] = {}
  # set Appearances
  popt['ap']['n'] = "/Tx BMC q #{fontstyle} "
  gvars = getGraphicVars()
  @h = h
  @w = w
  @t_margin = 0
  @c_margin = 0.2

  @tmp_buffer = ''
  multi_cell(w, h, s, 0, '', 0, 0, 0.2, 0, true, 0, false, true, 0)
  popt['ap']['n'] << @tmp_buffer
  popt['ap']['n'] << 'Q EMC'
  @tmp_buffer = nil

  # restore previous values
  setGraphicVars(gvars, true)

  # merge options
  opt = popt.merge opt
  # set remaining annotation data
  opt['Subtype'] = 'Widget'
  opt['ft'] = 'Ch'
  opt['t'] = name
  opt['opt'] = values
  Annotation(x, y, w, h, name, opt, 0)
  if @rtl
    @x -= w
  else
    @x += w
  end
end

#commitTransactionObject Also known as: commit_transaction

Delete the copy of the current RBPDF object used for undo operation.

@access public
@since 4.5.029 (2009-03-19)


16316
16317
16318
16319
16320
16321
16322
16323
16324
16325
16326
16327
16328
# File 'lib/rbpdf.rb', line 16316

def commitTransaction()
  if @objcopy
    if @objcopy.diskcache
      @prev_pages.compact.each do |file|
        File.delete(file.path)
      end
      @prev_pages = []
    end

    @objcopy.destroy(true, true)
    @objcopy = nil
  end
end

#convertHTMLColorToDec(color = "#FFFFFF") ⇒ Object Also known as: convert_html_color_to_dec

Returns an associative array (keys: R,G,B) from an html color name or a six-digit or three-digit hexadecimal color representation (i.e. #3FE5AA or #7FF).

@param string :color

html color

@return array

RGB color or empty array in case of error.

@access public


8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
8728
8729
8730
8731
# File 'lib/rbpdf.rb', line 8670

def convertHTMLColorToDec(color = "#FFFFFF")
  color = color.gsub(/[\s]*/, '') # remove extra spaces
  color = color.downcase
  if !(dotpos = color.index('.')).nil?
    # remove class parent (i.e.: color.red)
    color = color[(dotpos + 1)..-1]
  end
  if color.length == 0
    return []
  end
  returncolor = ActiveSupport::OrderedHash.new
  #  RGB ARRAY
  if color[0,3] == 'rgb'
    codes = color.sub(/^rgb\(/, '')
    codes = codes.gsub(')', '')
    returncolor = codes.split(',', 3)
    returncolor[0] = returncolor[0].to_i
    returncolor[1] = returncolor[1].to_i
    returncolor[2] = returncolor[2].to_i
    return returncolor
  end
  # CMYK ARRAY
  if color[0,4] == 'cmyk'
    codes = color.sub(/^cmyk\(/, '')
    codes = codes.gsub(')', '')
    returncolor[0] = returncolor[0].to_i
    returncolor[1] = returncolor[1].to_i
    returncolor[2] = returncolor[2].to_i
    returncolor[3] = returncolor[3].to_i
    return returncolor
  end
  # COLOR NAME
  if color[0].chr != "#"
    # decode color name
    if @@webcolor[color]
      color_code = @@webcolor[color]
    else
      return []
    end
  else
    color_code = color.sub(/^#/, "")
  end
  # RGB VALUE
  case color_code.length
  when 3
    # three-digit hexadecimal representation
    r = color_code[0]
    g = color_code[1]
    b = color_code[2]
    returncolor['R'] = (r + r).hex
    returncolor['G'] = (g + g).hex
    returncolor['B'] = (b + b).hex
  when 6
    # six-digit hexadecimal representation
    returncolor['R'] = color_code[0,2].hex
    returncolor['G'] = color_code[2,2].hex
    returncolor['B'] = color_code[4,2].hex
  else
    returncolor = []
  end
  return returncolor
end

#Curve(x0, y0, x1, y1, x2, y2, x3, y3, style = '', line_style = nil, fill_color = nil) ⇒ Object Also known as: curve

Draws a Bezier curve. The Bezier curve is a tangent to the line between the control points at either end of the curve.

@param float :x0

Abscissa of start point.

@param float :y0

Ordinate of start point.

@param float :x1

Abscissa of control point 1.

@param float :y1

Ordinate of control point 1.

@param float :x2

Abscissa of control point 2.

@param float :y2

Ordinate of control point 2.

@param float :x3

Abscissa of end point.

@param float :y3

Ordinate of end point.

@param string :style

Style of rendering. See the getPathPaintOperator() function for more information.

@param array :line_style

Line style of curve. Array like for SetLineStyle SetLineStyle. Default value: default line style (empty array).

@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).

@access public
@see

SetLineStyle()

@since 2.1.000 (2008-01-08)


9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
# File 'lib/rbpdf.rb', line 9161

def Curve(x0, y0, x1, y1, x2, y2, x3, y3, style='', line_style=nil, fill_color=nil)
  if style and (style.index('F') != nil) and fill_color
    SetFillColorArray(fill_color)
  end
  op = getPathPaintOperator(style)
  if line_style
    SetLineStyle(line_style)
  end
  outPoint(x0, y0)
  outCurve(x1, y1, x2, y2, x3, y3)
  out(op)
end

#deletePage(page) ⇒ Object Also known as: delete_page

Remove the specified page.

@param int :page

page to remove

@return

true in case of success, false in case of error.

@access public
@since 4.6.004 (2009-04-23)


15896
15897
15898
15899
15900
15901
15902
15903
15904
15905
15906
15907
15908
15909
15910
15911
15912
15913
15914
15915
15916
15917
15918
15919
15920
15921
15922
15923
15924
15925
15926
15927
15928
15929
15930
15931
15932
15933
15934
15935
15936
15937
15938
15939
15940
15941
15942
15943
15944
15945
15946
15947
15948
15949
15950
15951
15952
15953
15954
15955
15956
15957
15958
15959
15960
15961
15962
15963
15964
15965
15966
15967
15968
15969
15970
15971
15972
15973
15974
15975
15976
15977
15978
15979
15980
15981
15982
15983
15984
15985
15986
15987
15988
15989
15990
15991
15992
15993
15994
15995
15996
15997
15998
15999
16000
16001
16002
16003
16004
16005
16006
16007
16008
16009
16010
16011
16012
16013
16014
16015
16016
16017
16018
16019
16020
16021
16022
16023
16024
16025
16026
# File 'lib/rbpdf.rb', line 15896

def deletePage(page)
  if page > @numpages
    return false
  end
  # delete current page
  @pages[page] = nil
  @pagedim[page] = nil
  @pagelen[page] = nil
  @intmrk[page] = nil
  if @footerpos[page]
    @footerpos[page] = nil
  end
  if @footerlen[page]
    @footerlen[page] = nil
  end
  if @transfmrk[page]
    @transfmrk[page] = nil
  end
  if @page_annots[page]
    @page_annots[page] = nil
  end
  if @newpagegroup[page]
    @newpagegroup[page] = nil
  end
  if @pageopen[page]
    @pageopen[page] = nil
  end
  # update remaining pages
  page.upto(@numpages - 1) do |i|
    j = i + 1
    # shift pages
    @pages[i] = @pages[j]
    @pagedim[i] = @pagedim[j]
    @pagelen[i] = @pagelen[j]
    @intmrk[i] = @intmrk[j]
    if @footerpos[j]
      @footerpos[i] = @footerpos[j]
    elsif @footerpos[i]
      @footerpos[i] = nil
    end
    if @footerlen[j]
      @footerlen[i] = @footerlen[j]
    elsif @footerlen[i]
      @footerlen[i] = nil
    end
    if @transfmrk[j]
      @transfmrk[i] = @transfmrk[j]
    elsif @transfmrk[i]
      @transfmrk[i] = nil
    end
    if @page_annots[j]
      @page_annots[i] = page_annots[j]
    elsif @page_annots[i]
      @page_annots[i] = nil
    end
    if @newpagegroup[j]
      @newpagegroup[i] = @newpagegroup[j]
    elsif @newpagegroup[i]
      @newpagegroup[i] = nil
    end
    if @pageopen[j]
      @pageopen[i] = @pageopen[j]
    elsif @pageopen[i]
      @pageopen[i] = nil
    end
  end
  # remove last page
  @pages[@numpages] = nil
  @pagedim[@numpages] = nil
  @pagelen[@numpages] = nil
  @intmrk[@numpages] = nil
  if @footerpos[@numpages]
    @footerpos[@numpages] = nil
  end
  if @footerlen[@numpages]
    @footerlen[@numpages] = nil
  end
  if @transfmrk[@numpages]
    @transfmrk[@numpages] = nil
  end
  if @page_annots[@numpages]
    @page_annots[@numpages] = nil
  end
  if @newpagegroup[@numpages]
    @newpagegroup[@numpages] = nil
  end
  if @pageopen[@numpages]
    @pageopen[@numpages] = nil
  end
  @numpages -= 1
  @page = @numpages
  # adjust outlines
  tmpoutlines = @outlines
  tmpoutlines.each_with_index do |outline, key|
    if outline[:p] > page
      @outlines[key][:p] = outline[:p] - 1
    elsif outline[:p] == page
      @outlines[key] = nil
    end
  end
  # adjust links
  tmplinks = @links
  tmplinks.each_with_index do |link, key|
    next if link.nil?
    if link[0] > page
      @links[key][0] = link[0] - 1
    elsif link[0] == page
      @links[key] = nil
    end
  end

  #### PDF javascript code does not implement, yet. ###
  # adjust javascript
  #tmpjavascript = @javascript
  #jpage = page
  #tmpjavascript =~ /this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/
  #pagenum = $3.to_i + 1
  #if pagenum >= jpage
  #  newpage = pagenum - 1
  #elsif pagenum == jpage
  #  newpage = 1
  #else
  #  newpage = pagenum
  #end
  #newpage -= 1
  #@javascript = "this.addField(\'" + $1 + "\',\'" + $2 + "\'," + newpage + ""

  # return to last page
  lastPage(true)
  return true
end

#destroy(destroyall = false, preserve_objcopy = false) ⇒ Object

Unset all class variables except the following critical variables: internal_encoding, state, bufferlen, buffer and diskcache.

@param boolean :destroyall

if true destroys all class variables, otherwise preserves critical variables.

@param boolean :preserve_objcopy

if true preserves the objcopy variable

@access public


5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
# File 'lib/rbpdf.rb', line 5706

def destroy(destroyall=false, preserve_objcopy=false)
  if destroyall and @diskcache and !preserve_objcopy and !empty_string(@buffer.path)
    # remove buffer file from cache
    File.delete(@buffer.path)
  end
  self.instance_variables.each { |val|
    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'))
      if (!preserve_objcopy or (val.to_s != '@objcopy')) and !val.nil?
        eval("#{val} = nil")
      end
    end
  }
end

#Ellipse(x0, y0, rx, ry = '', angle = 0, astart = 0, afinish = 360, style = '', line_style = nil, fill_color = nil, nc = 2) ⇒ Object Also known as: ellipse

Draws an ellipse. An ellipse is formed from n Bezier curves.

@param float :x0

Abscissa of center point.

@param float :y0

Ordinate of center point.

@param float :rx

Horizontal radius.

@param float :ry

Vertical radius (if ry = 0 then is a circle, see Circle Circle). Default value: 0.

@param float :angle

Angle oriented (anti-clockwise). Default value: 0.

@param float :astart

Angle start of draw line. Default value: 0.

@param float :afinish

Angle finish of draw line. Default value: 360.

@param string :style

Style of rendering. See the getPathPaintOperator() function for more information.

@param array :line_style

Line style of ellipse. Array like for SetLineStyle SetLineStyle. Default value: default line style (empty array).

@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).

@param integer :nc

Number of curves used to draw a 90 degrees portion of ellipse.

@author

Nicola Asuni

@access public
@since 2.1.000 (2008-01-08)


9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
9207
9208
9209
9210
9211
# File 'lib/rbpdf.rb', line 9193

def Ellipse(x0, y0, rx, ry='', angle=0, astart=0, afinish=360, style='', line_style=nil, fill_color=nil, nc=2)
  style = '' if style.nil?
  if empty_string(ry) or (ry == 0)
    ry = rx
  end
  if (nil != style.index('F')) and fill_color
    SetFillColorArray(fill_color)
  end
  op = getPathPaintOperator(style)
  if op == 'f'
    line_style = nil
  end

  if line_style and !line_style.empty?
    SetLineStyle(line_style)
  end
  outellipticalarc(x0, y0, rx, ry, angle, astart, afinish, false, nc)
  out(op)
end

#empty_string(str) ⇒ Object

Determine whether a string is empty.

@param string :str

string to be checked

@return boolean

true if string is empty

@access public
@since 4.5.044 (2009-04-16)


16393
16394
16395
# File 'lib/rbpdf.rb', line 16393

def empty_string(str)
  return (str.nil? or (str.is_a?(String) and (str.length == 0)))
end

#endPage(tocpage = false) ⇒ Object Also known as: end_page

Terminate the current page

@param boolean :tocpage

if true set the tocpage state to false (end the page used to display Table Of Content).

@access public
@since 4.2.010 (2008-11-14)
@see

AddPage(), startPage(), addTOCPage(), endTOCPage()



1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
# File 'lib/rbpdf.rb', line 1747

def endPage(tocpage=false)
  # check if page is already closed
  if (@page == 0) or (@numpages > @page) or !@pageopen[@page]
    return
  end
  @in_footer = true
  # print page footer
  setFooter()
  # close page
  endpage()
  # mark page as closed
  @pageopen[@page] = false
  @in_footer = false
  if tocpage
    @tocpage = false
  end
end

#endTOCPageObject Also known as: end_toc_page

Terminate the current TOC (Table Of Content) page

@access public
@since 5.0.001 (2010-05-06)
@see

AddPage(), startPage(), endPage(), addTOCPage()



1699
1700
1701
# File 'lib/rbpdf.rb', line 1699

def endTOCPage()
  endPage(true)
end

#Error(msg, err = nil) ⇒ Object Also known as: error

This method is automatically called in case of fatal error; it simply outputs the message and halts the execution. An inherited class may override it to customize the error handling but should always halt the script, or the resulting document would probably be invalid.

  • 2004-06-11

    Nicola Asuni : changed bold tag with strong

@param string :msg

The error message

@param string :err

Exception object

@access public
@since 1.0

Raises:



1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
# File 'lib/rbpdf.rb', line 1530

def Error(msg, err = nil)
  if /^.+?:\d+(?::in `(.*)')?/ =~ caller(2).first
    method = $1
  end
  if err and err.class != RBPDFError
    logger.error "pdf: #{method}: #{err.message}"
    err.backtrace.each{|trace|
      logger.error trace
    }
  end
  raise RBPDFError, "RBPDF error: #{msg}"
end

This method is used to render the page footer. It is automatically called by AddPage() and could be overwritten in your own inherited class.

@access public


2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
# File 'lib/rbpdf.rb', line 2058

def Footer()
  cur_y = GetY()
  ormargins = getOriginalMargins()
  SetTextColor(0, 0, 0)
  # set style for cell border
  line_width = 0.85 / getScaleFactor()
  SetLineStyle({'width' => line_width, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => [0, 0, 0]})
  # print document barcode
  #barcode = getBarcode()
  #if !barcode.empty?
  #  Ln(line_width)
  #  barcode_width = ((getPageWidth() - ormargins['left'] - ormargins['right']) / 3.0).round
  #  write1DBarcode(barcode, 'C128B', GetX(), cur_y + line_width, barcode_width, ((getFooterMargin() / 3.0) - line_width), 0.3, '', '')
  #end
  w_page = (@l.nil? or @l['w_page'].nil?) ? '' : @l['w_page']
  if @pagegroups.empty?
    pagenumtxt = w_page + ' ' + getAliasNumPage() + ' / ' + getAliasNbPages()
  else
    pagenumtxt = w_page + ' ' + getPageNumGroupAlias() + ' / ' + getPageGroupAlias()
  end
  SetY(cur_y)
  # Print page number
  if getRTL()
    SetX(ormargins['right'])
    Cell(0, 0, pagenumtxt, 'T', 0, 'L')
  else
    SetX(ormargins['left'])
    Cell(0, 0, pagenumtxt, 'T', 0, 'R')
  end
end

#GetAbsXObject Also known as: get_abs_x

Returns the absolute X value of current position.

@return float
@access public
@since 1.2
@see

SetY(), GetX(), SetX()



5470
5471
5472
# File 'lib/rbpdf.rb', line 5470

def GetAbsX()
  return @x
end

#getAliasNbPagesObject Also known as: get_alias_nb_pages

Returns the string alias used for the total number of pages. If the current font is unicode type, the returned string is surrounded by additional curly braces.

@return string
@access public
@since 4.0.018 (2008-08-08)
@see

AliasNbPages(), PageNo(), Footer()



11386
11387
11388
11389
11390
11391
# File 'lib/rbpdf.rb', line 11386

def getAliasNbPages()
  if (@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont0')
    return '{' + @alias_nb_pages + '}'
  end
  return @alias_nb_pages
end

#getAliasNumPageObject Also known as: get_alias_num_page

Returns the string alias used for the page number. If the current font is unicode type, the returned string is surrounded by additional curly braces.

@return string
@access public
@since 4.5.000 (2009-01-02)
@see

AliasNbPages(), PageNo(), Footer()



11416
11417
11418
11419
11420
11421
# File 'lib/rbpdf.rb', line 11416

def getAliasNumPage()
  if (@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont0')
    return '{' + @alias_num_page + '}'
  end
  return @alias_num_page
end

#GetArrStringWidth(sa, fontname = '', fontstyle = '', fontsize = 0, getarray = false) ⇒ Object Also known as: get_arr_string_width

Returns the string length of an array of chars in user unit or an array of characters widths. A font must be selected.

@param string :sa

The array of chars whose total length is to be computed

@param string :fontname

Family font. It can be either a name defined by AddFont() or one of the standard families. It is also possible to pass an empty string, in that case, the current family is retained.

@param string :fontstyle

Font style. Possible values are (case insensitive):

  • empty string: regular

  • B: bold

  • I: italic

  • U: underline

  • D: line trough

  • O: overline

or any combination. The default value is regular.

@param float :fontsize

Font size in points. The default value is the current size.

@param boolean :getarray

if true returns an array of characters widths, if false returns the total length.

@return mixed int

total string length or array of characted widths

@author

Nicola Asuni

@access public
@since 2.4.000 (2008-03-06)


2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
# File 'lib/rbpdf.rb', line 2544

def GetArrStringWidth(sa, fontname='', fontstyle='', fontsize=0, getarray=false)
  # store current values
  if !empty_string(fontname)
    prev_FontFamily = @font_family
    prev_FontStyle = @font_style
    prev_FontSizePt = @font_size_pt
    SetFont(fontname, fontstyle, fontsize)
  end
  # convert UTF-8 array to Latin1 if required
  sa = UTF8ArrToLatin1(sa)
  w = 0 # total width
  wa = [] # array of characters widths
  sa.each do |char|
    # character width
    cw = GetCharWidth(char)
    wa.push cw
    w += cw
  end
  # restore previous values
  if !empty_string(fontname)
    SetFont(prev_FontFamily, prev_FontStyle, prev_FontSizePt)
  end
  if getarray
    return wa
  end
  return w
end

#getBreakMargin(pagenum = 0) ⇒ Object Also known as: get_break_margin

Returns the page break margin.

@param int :pagenum

page number (empty = current page)

@return int page

break margin.

@author

Nicola Asuni

[@access publi]c

@since 1.5.2
@see

getPageDimensions()



1238
1239
1240
1241
1242
1243
# File 'lib/rbpdf.rb', line 1238

def getBreakMargin(pagenum=0)
  if !pagenum.is_a? Integer or pagenum.zero?
    return @b_margin
  end
  return @pagedim[pagenum]['bm']
end

#GetBreakMargin(pagenum = 0) ⇒ Object



1246
1247
1248
1249
# File 'lib/rbpdf.rb', line 1246

def GetBreakMargin(pagenum=0)
  warn "[DEPRECATION] 'GetBreakMargin' is deprecated. Please use 'get_break_margin' instead."
  getBreakMargin(pagenum)
end

#getCellHeightRatioObject Also known as: get_cell_height_ratio

return the height of cell repect font height.

@access public
@since 4.0.012 (2008-07-24)


11662
11663
11664
# File 'lib/rbpdf.rb', line 11662

def getCellHeightRatio()
  return @cell_height_ratio
end

#GetCharWidth(char) ⇒ Object Also known as: get_char_width

Returns the length of the char in user unit for the current font.

@param int :char

The char code whose length is to be returned

@return int

char width

@author

Nicola Asuni

@access public
@since 2.4.000 (2008-03-06)


2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
# File 'lib/rbpdf.rb', line 2581

def GetCharWidth(char)
  if char == 173
    # SHY character will not be printed
    return 0
  end
  cw = @current_font['cw']
  if !cw[char].nil?
    w = cw[char]
  elsif !@current_font['dw'].nil?
    # default width
    w = @current_font['dw']
  elsif !cw[32].nil?
    # default width
    w = cw[32]
  else
    w = 600
  end
  return (w * @font_size / 1000.0)
end

#getFontAscent(font, style = '', size = 0) ⇒ Object Also known as: get_font_ascent

Return the font ascent value

@param string :font

font name

@param string :style

font style

@param float :size

The size (in points)

@return int

font ascent

@access public
@since 4.9.003 (2010-03-30)


2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
# File 'lib/rbpdf.rb', line 2976

def getFontAscent(font, style='', size=0)
  # Set font size in points
  sizek = size / @k
  fontdata = AddFont(font, style)
  font = getFontBuffer(fontdata['fontkey'])
  if font['desc'] and font['desc']['Ascent'] and (font['desc']['Ascent'] > 0)
    ascent = font['desc']['Ascent'] * sizek / 1000.0
  else
    ascent = 0.85 * sizek
  end
  return ascent
end

#getFontDescent(font, style = '', size = 0) ⇒ Object Also known as: get_font_descent

Return the font descent value

@param string :font

font name

@param string :style

font style

@param float :size

The size (in points)

@return int

font descent

@access public
@since 4.9.003 (2010-03-30)


2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
# File 'lib/rbpdf.rb', line 2953

def getFontDescent(font, style='', size=0)
  # Set font size in points
  sizek = size / @k
  fontdata = AddFont(font, style)
  font = getFontBuffer(fontdata['fontkey'])
  if font['desc'] and font['desc']['Descent'] and (font['desc']['Descent'] <= 0)
    descent = - font['desc']['Descent'] * sizek / 1000.0
  else
    descent = 0.15 * sizek
  end
  return descent
end

#getFontFamilyObject Also known as: get_font_family

Returns the current font family name.

@return string

current font family name

@access public
@since 4.3.008 (2008-12-05)


11963
11964
11965
# File 'lib/rbpdf.rb', line 11963

def getFontFamily()
  return @font_family
end

#getFontSizeObject Also known as: get_font_size

Returns the current font size.

@return

current font size

@access public
@since 3.2.000 (2008-06-23)


11941
11942
11943
# File 'lib/rbpdf.rb', line 11941

def getFontSize()
  return @font_size
end

#getFontSizePtObject Also known as: get_font_size_pt

Returns the current font size in points unit.

@return

current font size in points unit

@access public
@since 3.2.000 (2008-06-23)


11952
11953
11954
# File 'lib/rbpdf.rb', line 11952

def getFontSizePt()
  return @font_size_pt
end

#getFontStyleObject Also known as: get_font_style

Returns the current font style.

@return string

current font style

@access public
@since 4.3.008 (2008-12-05)


11974
11975
11976
# File 'lib/rbpdf.rb', line 11974

def getFontStyle()
  return @font_style
end

#getFontSubsettingObject Also known as: get_font_subsetting

Get Font Subsetting.

@return boolean
@access public


8505
8506
8507
# File 'lib/rbpdf.rb', line 8505

def getFontSubsetting()
  return @font_subsetting
end

#getFooterFont(font) ⇒ Object Also known as: get_footer_font

Get Footer font.

@return array
@access public
@since 4.0.012 (2008-07-24)


8559
8560
8561
# File 'lib/rbpdf.rb', line 8559

def getFooterFont(font)
  return @footer_font
end

#getFooterMarginObject Also known as: get_footer_margin

Returns footer margin in user units.

@return float
@since 4.0.012 (2008-07-24)
@access public


1947
1948
1949
# File 'lib/rbpdf.rb', line 1947

def getFooterMargin()
  return @footer_margin
end

#getFormDefaultPropObject Also known as: get_form_default_prop

Return the default properties for form fields.

@return array :prop

javascript field properties. Possible values are described on official Javascript for Acrobat API reference.

@access public
@author Nicola Asuni
@since 4.8.000 (2009-09-06)


10781
10782
10783
# File 'lib/rbpdf.rb', line 10781

def getFormDefaultProp()
  @default_form_prop
end

#getGroupPageNoObject Also known as: get_group_page_no

Return the current page in the group.

@return

current page in the group

@access public
@since 3.0.000 (2008-03-27)


11430
11431
11432
# File 'lib/rbpdf.rb', line 11430

def getGroupPageNo()
  return @pagegroups[@currpagegroup]
end

#getGroupPageNoFormattedObject Also known as: get_group_page_no_formatted

Returns the current group page number formatted as a string.

@access public
@since 4.3.003 (2008-11-18)
@see

PaneNo(), formatPageNumber()



11441
11442
11443
# File 'lib/rbpdf.rb', line 11441

def getGroupPageNoFormatted()
  return formatPageNumber(getGroupPageNo())
end

#getHeaderDataObject Also known as: get_header_data

Returns header data:

ret['logo'] = logo image
ret['logo_width'] = width of the image logo in user units
ret['title'] = header title
ret['string'] = header description string
@return hash
@access public
@since 4.0.012 (2008-07-24)


1888
1889
1890
1891
1892
1893
1894
1895
# File 'lib/rbpdf.rb', line 1888

def getHeaderData()
  ret = {}
  ret['logo'] = @header_logo
  ret['logo_width'] = @header_logo_width
  ret['title'] = @header_title
  ret['string'] = @header_string
  return ret
end

#getHeaderFontObject Also known as: get_header_font

Get header font.

@return array
@access public
@since 4.0.012 (2008-07-24)


8532
8533
8534
# File 'lib/rbpdf.rb', line 8532

def getHeaderFont()
  return @header_font
end

#getHeaderMarginObject Also known as: get_header_margin

Returns header margin in user units.

@return float
@since 4.0.012 (2008-07-24)
@access public


1920
1921
1922
# File 'lib/rbpdf.rb', line 1920

def getHeaderMargin()
  return @header_margin
end

#getHtmlAnchorPosition(anchor) ⇒ Object Also known as: get_html_anchor_position

Outputs HTML anchor position

@param string :anchor

html anchor id

@return array
Page, Y

of anchor

@access public


8659
8660
8661
# File 'lib/rbpdf.rb', line 8659

def getHtmlAnchorPosition(anchor)
  @html_anchors[anchor]
end

#getHTMLUnitToUnits(htmlval, refsize = 1, defaultunit = 'px', points = false) ⇒ Object Also known as: get_html_unit_to_units

convert HTML string containing value and unit of measure to user’s units or points.

@param string :htmlval

string containing values and unit

@param string :refsize

reference value in points

@param string :defaultunit

default unit (can be one of the following: %, em, ex, px, in, mm, pc, pt).

@param boolean :point

if true returns points, otherwise returns value in user’s units

@return float

value in user’s unit or point if :points=true

@access public
@since 4.4.004 (2008-12-10)


15170
15171
15172
15173
15174
15175
15176
15177
15178
15179
15180
15181
15182
15183
15184
15185
15186
15187
15188
15189
15190
15191
15192
15193
15194
15195
15196
15197
15198
15199
15200
15201
15202
15203
15204
15205
15206
15207
15208
15209
15210
15211
15212
15213
15214
15215
15216
15217
# File 'lib/rbpdf.rb', line 15170

def getHTMLUnitToUnits(htmlval, refsize=1, defaultunit='px', points=false)
  supportedunits = ['%', 'em', 'ex', 'px', 'in', 'cm', 'mm', 'pc', 'pt']
  retval = 0
  value = 0
  unit = 'px'
  k = @k
  if points
    k = 1
  end
  if supportedunits.include?(defaultunit)
    unit = defaultunit
  end
  if htmlval.is_a?(Numeric)
    value = htmlval.to_f
  else
    mnum = htmlval.scan(/[0-9\.\-\+]+/)
    unless mnum.empty?
      value = mnum[0].to_f
      munit = htmlval.scan(/[a-z%]+/)
      unless munit.empty?
        if supportedunits.include?(munit[0])
          unit = munit[0]
        end
      end
    end
  end
  case unit
  when '%' # percentage
    retval = (value * refsize) / 100.0
  when 'em' # relative-size
    retval = value * refsize
  when 'ex' # height of lower case 'x' (about half the font-size)
    retval = value * (refsize / 2.0)
  when 'in' # absolute-size
    retval = (value * @dpi) / k
  when 'cm' # centimeters
    retval = (value / 2.54 * @dpi) / k
  when 'mm' # millimeters
    retval = (value / 25.4 * @dpi) / k
  when 'pc' # one pica is 12 points
    retval = (value * 12) / k
  when 'pt' # points
    retval = value / k
  when 'px' # pixels
    retval = pixelsToUnits(value)
  end
  return retval
end

#getImageFileType(imgfile, iminfo = {}) ⇒ Object Also known as: get_image_file_type

Return the image type given the file name or array returned by getimagesize() function.

@param string :imgfile

image file name

@param hash :iminfo

array of image information returned by getimagesize() function.

@return string

image type

@access public
@since 4.8.017 (2009-11-27)


4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
# File 'lib/rbpdf.rb', line 4774

def getImageFileType(imgfile, iminfo={})
  if iminfo.is_a? Hash and iminfo['mime'] and !iminfo['mime'].empty?
    mime = iminfo['mime'].split('/')
    if (mime.length > 1) and (mime[0] == 'image') and !mime[1].empty?
      return mime[1].strip
    end
  end
  type = ''
  return type if imgfile.nil?

  fileinfo = File::extname(imgfile)
  type = fileinfo.sub(/^\./, '').downcase if fileinfo != ''
  if type == 'jpg'
    type = 'jpeg'
  end
  return type
end

#getImageRBXObject Also known as: get_image_rbx

Return the right-bottom (or left-bottom for RTL) corner X coordinate of last inserted image

@return float
@access public


1987
1988
1989
# File 'lib/rbpdf.rb', line 1987

def getImageRBX()
  return @img_rb_x
end

#getImageRBYObject Also known as: get_image_rby

Return the right-bottom (or left-bottom for RTL) corner Y coordinate of last inserted image

@return float
@access public


1997
1998
1999
# File 'lib/rbpdf.rb', line 1997

def getImageRBY()
  return @img_rb_y
end

#GetImageScaleObject



1126
1127
1128
1129
# File 'lib/rbpdf.rb', line 1126

def GetImageScale()
  warn "[DEPRECATION] 'GetImageScale' is deprecated. Please use 'get_image_scale' instead."
  getImageScale()
end

#getImageScaleObject Also known as: get_image_scale

Returns the adjusting factor to convert pixels to user units.

@return float

adjusting factor to convert pixels to user units.

@author

Nicola Asuni

@access public
@since 1.5.2


1121
1122
1123
# File 'lib/rbpdf.rb', line 1121

def getImageScale()
  return @img_scale;
end

#getLastHObject Also known as: get_last_h

Get the last cell height.

@return

last cell height

@access public
@since 4.0.017 (2008-08-05)


1092
1093
1094
# File 'lib/rbpdf.rb', line 1092

def getLastH()
  return @lasth
end

#GetLineWidthObject Also known as: get_line_width

Returns the current the line width.

@return int

Line width

@access public
@since 2.1.000 (2008-01-07)
@see

Line(), SetLineWidth()



8907
8908
8909
# File 'lib/rbpdf.rb', line 8907

def GetLineWidth()
  return @line_width
end

#getMarginsObject Also known as: get_margins

Returns an array containing current margins:

* ret['left'] = left  margin
* ret['right'] = right margin
* ret['top'] = top margin
* ret['bottom'] = bottom margin
* ret['header'] = header margin
* ret['footer'] = footer margin
* ret['cell'] = cell margin
@return array

containing all margins measures

@access public
@since 3.2.000 (2008-06-23)


11907
11908
11909
11910
11911
11912
11913
11914
11915
11916
11917
11918
# File 'lib/rbpdf.rb', line 11907

def getMargins()
  ret = {
      'left' => @l_margin,
      'right' => @r_margin,
      'top' => @t_margin,
      'bottom' => @b_margin,
      'header' => @header_margin,
      'footer' => @footer_margin,
      'cell' => @c_margin,
  }
  return ret
end

#GetNumChars(s) ⇒ Object Also known as: get_num_chars

Returns the numbero of characters in a string.

@param string :s

The input string.

@return int

number of characters

@access public
@since 2.0.0001 (2008-01-07)


2609
2610
2611
2612
2613
2614
# File 'lib/rbpdf.rb', line 2609

def GetNumChars(s)
  if (@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont0')
    return UTF8StringToArray(s).length
  end
  return s.length
end

#getNumLines(txt, w = 0, reseth = false, autopadding = true, cellMargin = '', lineWidth = '') ⇒ Object Also known as: get_num_lines

This method return the estimated number of lines for print a simple text string in Multicell() method.

@param string :txt

String for calculating his height

@param float :w

Width of cells. If 0, they extend up to the right margin of the page.

@param boolean :reseth

if true reset the last cell height (default false).

@param boolean :autopadding

if true, uses internal padding and automatically adjust it to account for line width (default true).

@param float :cellMargin

Internal cell margin, if empty or <= 0, extended up to current pdf cell margin (default ”).

@param float :lineWidth

Line width, if empty or <= 0, extended up to current pdf line width (default ”).

@return float

Return the minimal height needed for multicell method for printing the :txt param.

@author

Alexander Escalona Fernendez, Nicola Asuni

@access public
@since 4.5.011


4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
# File 'lib/rbpdf.rb', line 4174

def getNumLines(txt, w=0, reseth=false, autopadding=true, cellMargin='', lineWidth='')
  if empty_string(w) or (w <= 0)
    if @rtl
      w = @x - @l_margin
    else
      w = @w - @r_margin - @x
    end
  end
  if empty_string(cellMargin) or (cellMargin <= 0)
    cellMargin = @c_margin
  end
  if empty_string(lineWidth) or (lineWidth <= 0)
    lineWidth = @line_width
  end
  if autopadding
    # adjust internal padding
    if cellMargin < (lineWidth / 2.0)
      cellMargin = lineWidth / 2.0
    end
  end
  wmax = w - (2 * cellMargin)
  if reseth
    @lasth = @font_size * @cell_height_ratio
  end
  lines = 1
  sum = 0
  chars = UTF8StringToArray(txt)
  chars = utf8Bidi(chars, txt, rtl_text_dir)
  charsWidth = GetArrStringWidth(chars, '', '', 0, true)
  if @rtl
    charsWidth.reverse!
    chars.reverse!
  end
  length = chars.length
  lastSeparator = -1

  i = 0
  while i < length
    charWidth = charsWidth[i]
    if unichr(chars[i]) =~ /\s/
      lastSeparator = i
    end
    if (sum + charWidth >= wmax) or (chars[i] == 10) # 10 = "\n" = new line
      lines += 1
      if lastSeparator != -1
        i = lastSeparator
        lastSeparator = -1
        sum = 0
      else
        sum = charWidth
      end
    else
      sum += charWidth
    end
    i += 1
  end
  return lines
end

#getNumPagesObject Also known as: get_num_pages

Get the total number of insered pages.

@return int

number of pages

@access public
@since 2.1.000 (2008-01-07)
@see

setPage(), getPage(), lastPage()



1675
1676
1677
# File 'lib/rbpdf.rb', line 1675

def getNumPages()
  return @numpages
end

#getOriginalMarginsObject Also known as: get_original_margins

Returns an array containing original margins:

ret['left'] = left  margin
ret['right'] = right margin
@return array

containing all margins measures

@access public
@since 4.0.012 (2008-07-24)


11929
11930
11931
11932
# File 'lib/rbpdf.rb', line 11929

def getOriginalMargins()
  ret = { 'left' => @original_l_margin, 'right' => @original_r_margin }
  return ret
end

#getPageObject Also known as: get_page

Get current document page number.

@return int

page number

@access public
@since 2.1.000 (2008-01-07)
@see

setPage(), lastPage(), getNumPages()



1663
1664
1665
# File 'lib/rbpdf.rb', line 1663

def getPage()
  return @page
end

#getPageDimensions(pagenum = 0) ⇒ Object Also known as: get_page_dimensions

Returns an array of page dimensions:

@pagedim[@page]['w'] = page width in points
@pagedim[@page]['h'] = height in points
@pagedim[@page]['wk'] = page width in user units
@pagedim[@page]['hk'] = page height in user units
@pagedim[@page]['tm'] = top margin
@pagedim[@page]['bm'] = bottom margin
@pagedim[@page]['lm'] = left margin
@pagedim[@page]['rm'] = right margin
@pagedim[@page]['pb'] = auto page break
@pagedim[@page]['or'] = page orientation
@pagedim[@page]['olm'] = original left margin
@pagedim[@page]['orm'] = original right margin
@pagedim[@page]['Rotate'] = The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90.
@pagedim[@page]['PZ'] = The page's preferred zoom (magnification) factor.
@pagedim[@page]['trans'] : the style and duration of the visual transition to use when moving from another page to the given page during a presentation
  @pagedim[@page]['trans']['Dur'] = The page's display duration (also called its advance timing): the maximum length of time, in seconds, that the page shall be displayed during presentations before the viewer application shall automatically advance to the next page.
  @pagedim[@page]['trans']['S'] = transition style : Split, Blinds, Box, Wipe, Dissolve, Glitter, R, Fly, Push, Cover, Uncover, Fade
  @pagedim[@page]['trans']['D'] = The duration of the transition effect, in seconds.
  @pagedim[@page]['trans']['Dm'] = (Split and Blinds transition styles only) The dimension in which the specified transition effect shall occur: H = Horizontal, V = Vertical. Default value: H.
  @pagedim[@page]['trans']['M'] = (Split, Box and Fly transition styles only) The direction of motion for the specified transition effect: I = Inward from the edges of the page, O = Outward from the center of the pageDefault value: I.
  @pagedim[@page]['trans']['Di'] = (Wipe, Glitter, Fly, Cover, Uncover and Push transition styles only) The direction in which the specified transition effect shall moves, expressed in degrees counterclockwise starting from a left-to-right direction. If the value is a number, it shall be one of: 0 = Left to right, 90 = Bottom to top (Wipe only), 180 = Right to left (Wipe only), 270 = Top to bottom, 315 = Top-left to bottom-right (Glitter only). If the value is a name, it shall be None, which is relevant only for the Fly transition when the value of SS is not 1.0. Default value: 0.
  @pagedim[@page]['trans']['SS'] = (Fly transition style only) The starting or ending scale at which the changes shall be drawn. If M specifies an inward transition, the scale of the changes drawn shall progress from SS to 1.0 over the course of the transition. If M specifies an outward transition, the scale of the changes drawn shall progress from 1.0 to SS over the course of the transition. Default: 1.0.
  @pagedim[@page]['trans']['B'] = (Fly transition style only) If true, the area that shall be flown in is rectangular and opaque. Default: false.
@pagedim[@page]['MediaBox'] : the boundaries of the physical medium on which the page shall be displayed or printed
  @pagedim[@page]['MediaBox']['llx'] = lower-left x coordinate in points
  @pagedim[@page]['MediaBox']['lly'] = lower-left y coordinate in points
  @pagedim[@page]['MediaBox']['urx'] = upper-right x coordinate in points
  @pagedim[@page]['MediaBox']['ury'] = upper-right y coordinate in points
@pagedim[@page]['CropBox'] : the visible region of default user space
  @pagedim[@page]['CropBox']['llx'] = lower-left x coordinate in points
  @pagedim[@page]['CropBox']['lly'] = lower-left y coordinate in points
  @pagedim[@page]['CropBox']['urx'] = upper-right x coordinate in points
  @pagedim[@page]['CropBox']['ury'] = upper-right y coordinate in points
@pagedim[@page]['BleedBox'] : the region to which the contents of the page shall be clipped when output in a production environment
  @pagedim[@page]['BleedBox']['llx'] = lower-left x coordinate in points
  @pagedim[@page]['BleedBox']['lly'] = lower-left y coordinate in points
  @pagedim[@page]['BleedBox']['urx'] = upper-right x coordinate in points
  @pagedim[@page]['BleedBox']['ury'] = upper-right y coordinate in points
@pagedim[@page]['TrimBox'] : the intended dimensions of the finished page after trimming
  @pagedim[@page]['TrimBox']['llx'] = lower-left x coordinate in points
  @pagedim[@page]['TrimBox']['lly'] = lower-left y coordinate in points
  @pagedim[@page]['TrimBox']['urx'] = upper-right x coordinate in points
  @pagedim[@page]['TrimBox']['ury'] = upper-right y coordinate in points
@pagedim[@page]['ArtBox'] : the extent of the page's meaningful content
  @pagedim[@page]['ArtBox']['llx'] = lower-left x coordinate in points
  @pagedim[@page]['ArtBox']['lly'] = lower-left y coordinate in points
  @pagedim[@page]['ArtBox']['urx'] = upper-right x coordinate in points
  @pagedim[@page]['ArtBox']['ury'] = upper-right y coordinate in points
@param int :pagenum

page number (empty = current page)

@return

array of page dimensions.

@author

Nicola Asuni

@access public
@since 4.5.027 (2009-03-16)


1187
1188
1189
1190
1191
1192
# File 'lib/rbpdf.rb', line 1187

def getPageDimensions(pagenum=0)
  if !pagenum.is_a? Integer or pagenum.zero?
    pagenum = @page
  end
  return @pagedim[pagenum]
end

#getPageGroupAliasObject Also known as: get_page_group_alias

Return the alias of the current page group If the current font is unicode type, the returned string is surrounded by additional curly braces. (will be replaced by the total number of pages in this group).

@return

alias of the current page group

@access public
@since 3.0.000 (2008-03-27)


11454
11455
11456
11457
11458
11459
# File 'lib/rbpdf.rb', line 11454

def getPageGroupAlias()
  if (@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont1')
    return '{' + @currpagegroup + '}'
  end
  return @currpagegroup
end

#GetPageHeightObject



1224
1225
1226
1227
# File 'lib/rbpdf.rb', line 1224

def GetPageHeight()
  warn "[DEPRECATION] 'GetPageHeight' is deprecated. Please use 'get_page_height' instead."
  getPageHeight()
end

#getPageHeightObject Also known as: get_page_height

Returns the page height in units.

@return int

page height.

@author

Nicola Asuni

@access public
@since 1.5.2


1219
1220
1221
# File 'lib/rbpdf.rb', line 1219

def getPageHeight()
  return @h;
end

#getPageNumGroupAliasObject Also known as: get_page_num_group_alias

Return the alias for the page number on the current page group If the current font is unicode type, the returned string is surrounded by additional curly braces. (will be replaced by the total number of pages in this group).

@return

alias of the current page group

@access public
@since 4.5.000 (2009-01-02)


11470
11471
11472
11473
11474
11475
# File 'lib/rbpdf.rb', line 11470

def getPageNumGroupAlias()
  if (@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont0')
    return '{' + @currpagegroup.gsub('{nb', '{pnb') +'}'
  end
  return @currpagegroup.gsub('{nb', '{pnb')
end

#getPageSizeFromFormat(format) ⇒ Object Also known as: get_page_size_from_format

Get page dimensions from fromat name.

@param mixed :format

The format name. It can be:

  • 4A0,2A0,A0,A1,A2,A3,A4 (default),A5,A6,A7,A8,A9,A10

  • B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10

  • C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10

  • RA0,RA1,RA2,RA3,RA4

  • SRA0,SRA1,SRA2,SRA3,SRA4

  • LETTER,LEGAL,EXECUTIVE,FOLIO

@return array

containing page width and height in points

@access public
@since 5.0.010 (2010-05-17)


614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
# File 'lib/rbpdf.rb', line 614

def getPageSizeFromFormat(format)
  # Page formats (45 standard ISO paper formats and 4 american common formats).
  # Paper cordinates are calculated in this way: (inches * 72) where (1 inch = 2.54 cm)
  case format.upcase
  when '4A0'; pf = [4767.87,6740.79]
  when '2A0'; pf = [3370.39,4767.87]
  when 'A0'; pf = [2383.94,3370.39]
  when 'A1'; pf = [1683.78,2383.94]
  when 'A2'; pf = [1190.55,1683.78]
  when 'A3'; pf = [841.89,1190.55]
  when 'A4'; pf = [595.28,841.89]
  when 'A5'; pf = [419.53,595.28]
  when 'A6'; pf = [297.64,419.53]
  when 'A7'; pf = [209.76,297.64]
  when 'A8'; pf = [147.40,209.76]
  when 'A9'; pf = [104.88,147.40]
  when 'A10'; pf = [73.70,104.88]
  when 'B0'; pf = [2834.65,4008.19]
  when 'B1'; pf = [2004.09,2834.65]
  when 'B2'; pf = [1417.32,2004.09]
  when 'B3'; pf = [1000.63,1417.32]
  when 'B4'; pf = [708.66,1000.63]
  when 'B5'; pf = [498.90,708.66]
  when 'B6'; pf = [354.33,498.90]
  when 'B7'; pf = [249.45,354.33]
  when 'B8'; pf = [175.75,249.45]
  when 'B9'; pf = [124.72,175.75]
  when 'B10'; pf = [87.87,124.72]
  when 'C0'; pf = [2599.37,3676.54]
  when 'C1'; pf = [1836.85,2599.37]
  when 'C2'; pf = [1298.27,1836.85]
  when 'C3'; pf = [918.43,1298.27]
  when 'C4'; pf = [649.13,918.43]
  when 'C5'; pf = [459.21,649.13]
  when 'C6'; pf = [323.15,459.21]
  when 'C7'; pf = [229.61,323.15]
  when 'C8'; pf = [161.57,229.61]
  when 'C9'; pf = [113.39,161.57]
  when 'C10'; pf = [79.37,113.39]
  when 'RA0'; pf = [2437.80,3458.27]
  when 'RA1'; pf = [1729.13,2437.80]
  when 'RA2'; pf = [1218.90,1729.13]
  when 'RA3'; pf = [864.57,1218.90]
  when 'RA4'; pf = [609.45,864.57]
  when 'SRA0'; pf = [2551.18,3628.35]
  when 'SRA1'; pf = [1814.17,2551.18]
  when 'SRA2'; pf = [1275.59,1814.17]
  when 'SRA3'; pf = [907.09,1275.59]
  when 'SRA4'; pf = [637.80,907.09]
  when 'LETTER'; pf = [612.00,792.00]
  when 'LEGAL'; pf = [612.00,1008.00]
  when 'EXECUTIVE'; pf = [521.86,756.00]
  when 'FOLIO'; pf = [612.00,936.00]
  else
    pf = [595.28,841.89] # DEFAULT A4
  end
  return pf
end

#GetPageWidthObject



1207
1208
1209
1210
# File 'lib/rbpdf.rb', line 1207

def GetPageWidth()
  warn "[DEPRECATION] 'GetPageWidth' is deprecated. Please use 'get_page_width' instead."
  getPageWidth()
end

#getPageWidthObject Also known as: get_page_width

Returns the page width in units.

@return int

page width.

@author

Nicola Asuni

@access public
@since 1.5.2


1202
1203
1204
# File 'lib/rbpdf.rb', line 1202

def getPageWidth()
  return @w;
end

#getPDFDataObject Also known as: get_pdf_data

Returns the PDF data.

@access public


8588
8589
8590
8591
8592
8593
# File 'lib/rbpdf.rb', line 8588

def getPDFData()
  if (@state < 3)
    Close();
  end
  return @buffer;
end

#GetPDFDataObject



8596
8597
8598
8599
# File 'lib/rbpdf.rb', line 8596

def GetPDFData()
  warn "[DEPRECATION] 'GetPDFData' is deprecated. Please use 'get_pdf_data' instead."
  getPDFData()
end

#getRTLObject Also known as: get_rtl

Return the RTL status

@return boolean
@access public
@since 4.0.012 (2008-07-24)


1022
1023
1024
# File 'lib/rbpdf.rb', line 1022

def getRTL()
  return @rtl
end

#getScaleFactorObject Also known as: get_scale_factor

Returns the scale factor (number of points in user unit).

@return int

scale factor.

@author

Nicola Asuni

@access public
@since 1.5.2


1258
1259
1260
# File 'lib/rbpdf.rb', line 1258

def getScaleFactor()
  return @k;
end

#GetScaleFactorObject



1263
1264
1265
1266
# File 'lib/rbpdf.rb', line 1263

def GetScaleFactor()
  warn "[DEPRECATION] 'GetScaleFactor' is deprecated. Please use 'get_scale_factor' instead."
  getScaleFactor()
end

#getStringHeight(w, txt, reseth = false, autopadding = true, cellMargin = '', lineWidth = '') ⇒ Object Also known as: get_string_height

This method return the estimated needed height for print a simple text string in Multicell() method. Generally, if you want to know the exact height for a block of content you can use the following technique:

# store current object
pdf.start_transaction()
# store starting values
start_y = pdf.get_y()
start_page = pdf.get_page()
# call your printing functions with your parameters
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
pdf.multi_cell(w=0, h=0, txt, border=1, align='L', fill=0, ln=1, x='', y='', reseth=true, stretch=0, ishtml=false, autopadding=true, maxh=0)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# get the new Y
end_y = pdf.get_y()
end_page = pdf.get_page()
# calculate height
height = 0
if end_page == start_page
  height = end_y - start_y
else
  start_page.upto(end_page) do |page|
    pdf.set_page(page)
    if page == start_page
      # first page
      height = @h - start_y - @b_margin
    elsif page == end_page
      # last page
      height = end_y - @t_margin
    else
      height = @h - @t_margin - @b_margin
    end
  end
end
# restore previous object
pdf = pdf.rollbackTransaction()
@param float :w

Width of cells. If 0, they extend up to the right margin of the page.

@param string :txt

String for calculating his height

@param boolean :reseth

if true reset the last cell height (default false).

@param boolean :autopadding

if true, uses internal padding and automatically adjust it to account for line width (default true).

@param float :cellMargin

Internal cell margin, if empty or <= 0, extended up to current pdf cell margin (default ”).

@param float :lineWidth

Line width, if empty or <= 0, extended up to current pdf line width (default ”).

@return float

Return the minimal height needed for multicell method for printing the :txt param.

@author

Nicola Asuni, Alexander Escalona Fern<E1>ndez

@access public


4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
# File 'lib/rbpdf.rb', line 4281

def getStringHeight(w, txt, reseth=false, autopadding=true, cellMargin='', lineWidth='')
  lines = getNumLines(txt, w, reseth, autopadding, cellMargin, lineWidth)
  height = lines * (@font_size * @cell_height_ratio)
  if autopadding
    if empty_string(cellMargin) or (cellMargin <= 0)
      cellMargin = @c_margin
    end
    if empty_string(lineWidth) or (lineWidth <= 0)
      lineWidth = @line_width
    end
    # adjust internal padding
    if cellMargin < (lineWidth / 2.0)
      cellMargin = lineWidth / 2.0
    end
    # add top and bottom space if needed
    if (@lasth - @font_size) < lineWidth
      height += lineWidth
    end
    # add top and bottom padding
    height += 2 * cellMargin
  end
  return height
end

#GetStringWidth(s, fontname = '', fontstyle = '', fontsize = 0, getarray = false) ⇒ Object Also known as: get_string_width

Returns the length of a string in user unit. A font must be selected.

@param string :s

The string whose length is to be computed

@param string :fontname

Family font. It can be either a name defined by AddFont() or one of the standard families. It is also possible to pass an empty string, in that case, the current family is retained.

@param string :fontstyle

Font style. Possible values are (case insensitive):

  • empty string: regular

  • B: bold

  • I: italic

  • U: underline

  • D: line trough

  • O: overline

or any combination. The default value is regular.

@param float :fontsize

Font size in points. The default value is the current size.

@param boolean :getarray

if true returns an array of characters widths, if false returns the total length.

@return mixed int

total string length or array of characted widths

@author

Nicola Asuni

@access public
@since 1.2


2519
2520
2521
# File 'lib/rbpdf.rb', line 2519

def GetStringWidth(s, fontname='', fontstyle='', fontsize=0, getarray=false)
  return GetArrStringWidth(utf8Bidi(UTF8StringToArray(s), s, rtl_text_dir), fontname, fontstyle, fontsize, getarray)
end

#GetXObject Also known as: get_x

Returns the relative X value of current position. The value is relative to the left border for LTR languages and to the right border for RTL languages.

@return float
@access public
@since 1.2
@see

SetX(), GetY(), SetY()



5454
5455
5456
5457
5458
5459
5460
# File 'lib/rbpdf.rb', line 5454

def GetX()
  if @rtl
    return @w - @x
  else
    return @x
  end
end

#GetYObject Also known as: get_y

Returns the ordinate of the current position.

@return float
@access public
@since 1.0
@see

SetY(), GetX(), SetX()



5482
5483
5484
# File 'lib/rbpdf.rb', line 5482

def GetY()
  return @y;
end

#HeaderObject Also known as: header

This method is used to render the page header. It is automatically called by AddPage() and could be overwritten in your own inherited class.

@access public


2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
# File 'lib/rbpdf.rb', line 2007

def Header()
  ormargins = getOriginalMargins()
  headerfont = getHeaderFont()
  headerdata = getHeaderData()
  if headerdata['logo'] and (headerdata['logo'] != @@k_blank_image)
    result_img = Image(@@k_path_images + headerdata['logo'], '', '', headerdata['logo_width'])
    if result_img != false
      imgy = getImageRBY()
    else
      Write(@lasth, File.basename(headerdata['logo']), '', false, '', false, 0, false)
      imgy = GetY()
    end
  else
    imgy = GetY()
  end
  cell_height = ((getCellHeightRatio() * headerfont[2]) / getScaleFactor()).round(2)

  # set starting margin for text data cell
  if getRTL()
    header_x = ormargins['right'] + (headerdata['logo_width'] * 1.1)
  else
    header_x = ormargins['left'] + (headerdata['logo_width'] * 1.1)
  end
  SetTextColor(0, 0, 0)
  # header title
  SetFont(headerfont[0], 'B', headerfont[2] + 1)
  SetX(header_x)
  Cell(0, cell_height, headerdata['title'], 0, 1, '', 0, '', 0)
  # header string
  SetFont(headerfont[0], headerfont[1], headerfont[2])
  SetX(header_x)
  MultiCell(0, cell_height, headerdata['string'], 0, '', 0, 1, '', '', true, 0, false)

  # print an ending header line
  SetLineStyle({'width' => 0.85 / getScaleFactor(), 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => [0, 0, 0]})
  SetY((2.835 / getScaleFactor()) + (imgy > GetY() ? imgy : GetY()))

  if getRTL()
    SetX(ormargins['right'])
  else
    SetX(ormargins['left'])
  end
  Cell(0, 0, '', 'T', 0, 'C')
end

#Image(file, x = '', y = '', w = 0, h = 0, type = '', link = nil, align = '', resize = false, dpi = 300, palign = '', ismask = false, imgmask = false, border = 0, fitbox = false, hidden = false, fitonpage = false) ⇒ Object Also known as: image

Puts an image in the page. The upper-left corner must be given. The dimensions can be specified in different ways:

  • explicit width and height (expressed in user unit)

  • one explicit dimension, the other being calculated automatically in order to keep the original proportions

  • no explicit dimension, in which case the image is put at 72 dpi

Supported formats are PNG images whitout RMagick/MiniMagick library and JPEG and GIF and WebP images supported by RMagick/MiniMagick. For JPEG, all flavors are allowed:

  • gray scales

  • true colors (24 bits)

  • CMYK (32 bits)

For PNG, are allowed:

  • gray scales on at most 8 bits (256 levels)

  • indexed colors

  • true colors (24 bits)

If a transparent color is defined, it will be taken into account (but will be only interpreted by Acrobat 4 and above). The format can be specified explicitly or inferred from the file extension. It is possible to put a link on the image.

  • Remark: if an image is used several times, only one copy will be embedded in the file.

@param string :file

Name of the file containing the image.

@param float :x

Abscissa of the upper-left corner.

@param float :y

Ordinate of the upper-left corner.

@param float :w

Width of the image in the page. If not specified or equal to zero, it is automatically calculated.

@param float :h

Height of the image in the page. If not specified or equal to zero, it is automatically calculated.

@param string :type

Image format. Possible values are (case insensitive): JPG, JPEG, PNG, GIF, WebP. If not specified, the type is inferred from the file extension.

@param mixed :link

URL or identifier returned by AddLink().

@param string :align

Indicates the alignment of the pointer next to image insertion relative to image height. The value can be:

  • T: top-right for LTR or top-left for RTL

  • M: middle-right for LTR or middle-left for RTL

  • B: bottom-right for LTR or bottom-left for RTL

  • N: next line

@param mixed :resize

If true resize (reduce) the image to fit :w and :h (requires RMagick/MiniMagick library); if false do not resize; if 2 force resize in all cases (upscaling and downscaling).

@param int :dpi

dot-per-inch resolution used on resize

@param string :palign

Allows to center or align the image on the current line. Possible values are:

  • L : left align

  • C : center

  • R : right align

  • ” : empty string : left for LTR or right for RTL

@param boolean :ismask

true if this image is a mask, false otherwise

@param mixed :imgmask

image object returned by this function or false

@param mixed :border

Indicates if borders must be drawn around the image. The value can be either a number:

  • 0: no border (default)

  • 1: frame

or a string containing some or all of the following characters (in any order):

  • L: left

  • T: top

  • R: right

  • B: bottom

@param boolean :fitbox

If true scale image dimensions proportionally to fit within the (:w, :h) box.

@param boolean :hidden

if true do not display the image.

@param boolean :fitonpage

if true the image is resized to not exceed page dimensions.

@return

image information

@access public
@since 1.1


4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
# File 'lib/rbpdf.rb', line 4852

def Image(file, x='', y='', w=0, h=0, type='', link=nil, align='', resize=false, dpi=300, palign='', ismask=false, imgmask=false, border=0, fitbox=false, hidden=false, fitonpage=false)
  w = 0 if w == ''
  h = 0 if h == ''

  x = @x if x == ''
  y = @y if y == ''

  # set bottomcoordinates
  @img_rb_y = y + h
  Error('Image filename is empty.') if file.nil? or file.length == 0
  unless File.exist?(file)
    Error('Image file is not found. : ' + file)
  end

  # get image dimensions
  imsize = getimagesize(file)
  if imsize.nil? or imsize == false
    # encode spaces on filename
    file = file.gsub(' ', '%20')
    imsize = getimagesize(file)

    if imsize.nil?
      Error("Can't get image dimension. : " + file)
    elsif imsize == false
      if (w > 0) and (h > 0)
        pw = getHTMLUnitToUnits(w, 0, @pdfunit, true) * @img_scale * @k
        ph = getHTMLUnitToUnits(h, 0, @pdfunit, true) * @img_scale * @k
        imsize = [pw, ph]
      else
        Error('Unable to get image width and height: ' + file)
      end
    end
  end
  # get original image width and height in pixels
  pixw = imsize[0]
  pixh = imsize[1]

  # calculate image width and height on document
  if (w <= 0) and (h <= 0)
    # convert image size to document unit
    w = pixelsToUnits(pixw)
    h = pixelsToUnits(pixh)
  elsif w <= 0
    w = h * pixw / pixh
  elsif h <= 0
    h = w * pixh / pixw
  elsif fitbox and (w > 0) and (h > 0)
    # scale image dimensions proportionally to fit within the (:w, :h) box
    if ((w * pixh) / (h * pixw)) < 1
      h = w * pixh / pixw
    else
      w = h * pixw / pixh
    end
  end

  # resize image to be contained on a single page          # fix at page break case.
  if fitonpage
    ratio_wh = w / h
    if (@t_margin + h) > @page_break_trigger
      h = @page_break_trigger - @t_margin
      w = h * ratio_wh
    end
    if !@rtl and ((x + w) > (@w - @r_margin))
      w = @w - @r_margin - x
      h = w / ratio_wh
    elsif @rtl and ((x - w) < @l_margin)
      w = x - @l_margin
      h = w / ratio_wh
    end
  end

  # Check whether we need a new page first as this does not fit
  prev_x = @x
  if checkPageBreak(h, y)
    y = @y
    y += @c_margin if !empty_string(@thead) and !@in_thead  ### fix ###
    if @rtl
      x += prev_x - @x
    else
      x += @x - prev_x
    end
  end
  # resize image to be contained on a single page
  if fitonpage
    ratio_wh = w / h
    if (y + h) > @page_break_trigger
      h = @page_break_trigger - y
      w = h * ratio_wh
    end
    if !@rtl and ((x + w) > (@w - @r_margin))
      w = @w - @r_margin - x
      h = w / ratio_wh
    elsif @rtl and ((x - w) < @l_margin)
      w = x - @l_margin
      h = w / ratio_wh
    end
  end
  # calculate new minimum dimensions in pixels
  neww = (w * @k * dpi / @dpi).round
  newh = (h * @k * dpi / @dpi).round
  # check if resize is necessary (resize is used only to reduce the image)
  newsize = neww * newh
  pixsize = pixw * pixh
  if resize == 2
    resize = true
  elsif newsize >= pixsize
    resize = false
  end

  # check if image has been already added on document
  newimage = true
  if @imagekeys.include?(file)
    newimage = false;
    # get existing image data
    info = getImageBuffer(file)
    # check if the newer image is larger
    oldsize = info['w'] * info['h']
    if ((oldsize < newsize) and resize) or ((oldsize < pixsize) and !resize)
      newimage = true
    end
  end
  if newimage
    #First use of image, get info
    if (type == '')
      type = getImageFileType(file, imsize)
    else
      type = type.downcase
      type = 'jpeg' if type == 'jpg'
    end

    info = false
    if !resize
      case type
      when 'jpeg'
        info=parsejpeg(file)
      when 'png'
        info=parsepng(file)
      when 'webp'
        tmpFile = imageToPNG(file, false)
        if tmpFile != false
          info=parsepng(tmpFile.path)
          tmpFile.close(true)
        end
      when 'gif'
        tmpFile = imageToPNG(file, false)
        if tmpFile != false
          info=parsepng(tmpFile.path)
          tmpFile.close(true)
        end
      else
        #Allow for additional formats
        mtd='parse' + type;
        unless self.respond_to?(mtd, true)
          Error('Unsupported image type: ' + type);
        end
        info=send(mtd, file);
      end

      if info == 'pngalpha' and ismask == false and (Object.const_defined?(:MiniMagick) or Object.const_defined?(:Magick))
        info = ImagePngAlpha(file, x, y, w, h, 'PNG', link, align, resize, dpi, palign)
        if false != info
          return true
        end
      end
    end
    if !info
      if Object.const_defined?(:MiniMagick)
        # MiniMagick library

        ### T.B.D ### TCPDF 5.0.000 ###
        # if type == 'SVG'
        # else
          img = MiniMagick::Image.open(file)
        # end
        if resize
          img.resize("#{neww}x#{newh}")
        end
        img.format 'jpeg'
        tmpname = Tempfile.new(File::basename(file), @@k_path_cache)
        tmpname.binmode
        tmpname.print img.to_blob
      elsif Object.const_defined?(:Magick)
        # RMagick library

        ### T.B.D ### TCPDF 5.0.000 ###
        # if type == 'SVG'
        # else
          img = Magick::ImageList.new(file)
        # end
        if resize
          img.resize(neww,newh)
        end
        img.format = 'JPEG'
        tmpname = Tempfile.new(File::basename(file), @@k_path_cache)
        tmpname.binmode
        jpeg_quality = @jpeg_quality
        tmpname.print img.to_blob { |image| image.quality = jpeg_quality }
      else
        return false
      end
      tmpname.fsync
      info = parsejpeg(tmpname.path)
      tmpname.close(true)
    end

    if info == false
      # If false, we cannot process image
      return false
    end
    if ismask
      # force grayscale
      info['cs'] = 'DeviceGray'
    end
    info['i'] = @numimages
    if !@imagekeys.include?(file)
      info['i'] += 1
    end
    if imgmask != false
      info['masked'] = imgmask
    end
    # add image to document
    setImageBuffer(file, info)
  end

  # set alignment
  @img_rb_y = y + h
  # set alignment
  if @rtl
    if palign == 'L'
      ximg = @l_margin
    elsif palign == 'C'
      ximg = (@w + @l_margin - @r_margin - w) / 2.0
    elsif palign == 'R'
      ximg = @w - @r_margin - w
    else
      ximg = x - w
    end
    @img_rb_x = ximg
  else
    if palign == 'L'
      ximg = @l_margin
    elsif palign == 'C'
      ximg = (@w + @l_margin - @r_margin - w) / 2.0
    elsif palign == 'R'
      ximg = @w - @r_margin - w
    else
      ximg = x
    end
    @img_rb_x = ximg + w
  end
  if ismask or hidden
    # image is not displayed
    return info['i']
  end
  xkimg = ximg * @k
  out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q', w * @k, h * @k, xkimg, (@h - (y + h)) * @k, info['i']))

  if border != 0
    bx = x
    by = y
    @x = ximg
    if @rtl
      @x += w
    end
    @y = y
    Cell(w, h, '', border, 0, '', 0, '', 0)
    @x = bx
    @y = by
  end

  if link and !link.empty?
    Link(ximg, y, w, h, link)
  end

  # set pointer to align the successive text/objects
  case align
  when 'T'
    @y = y
    @x = @img_rb_x
  when 'M'
    @y = y + (h/2.0).round
    @x = @img_rb_x
  when 'B'
    @y = @img_rb_y
    @x = @img_rb_x
  when 'N'
    SetY(@img_rb_y)
  end
  @endlinex = @img_rb_x
  return info['i']
end

#IncludeJS(script) ⇒ Object

--- JAVASCRIPT ------------------------------------------------------

Adds a javascript

@param string :script

Javascript code

@access public
@author Johannes G???ntert, Nicola Asuni
@since 2.1.002 (2008-02-12)


10437
10438
10439
# File 'lib/rbpdf.rb', line 10437

def IncludeJS(script)
  @javascript << script
end

#intToRoman(number) ⇒ Object Also known as: int_to_roman

Returns the Roman representation of an integer number

@param int :number

to convert

@return string

roman representation of the specified number

@access public
@since 4.4.004 (2008-12-10)


15227
15228
15229
15230
15231
15232
15233
15234
15235
15236
15237
15238
15239
15240
15241
15242
15243
15244
15245
15246
15247
15248
15249
15250
15251
15252
15253
15254
15255
15256
15257
15258
15259
15260
15261
15262
15263
15264
15265
15266
15267
15268
15269
15270
15271
15272
15273
15274
15275
15276
15277
15278
15279
15280
15281
15282
# File 'lib/rbpdf.rb', line 15227

def intToRoman(number)
  roman = ''
  while number >= 1000
    roman << 'M'
    number -= 1000
  end
  while number >= 900
    roman << 'CM'
    number -= 900
  end
  while number >= 500
    roman << 'D'
    number -= 500
  end
  while number >= 400
    roman << 'CD'
    number -= 400
  end
  while number >= 100
    roman << 'C'
    number -= 100
  end
  while number >= 90
    roman << 'XC'
    number -= 90
  end
  while number >= 50
    roman << 'L'
    number -= 50
  end
  while number >= 40
    roman << 'XL'
    number -= 40
  end
  while number >= 10
    roman << 'X'
    number -= 10
  end
  while number >= 9
    roman << 'IX'
    number -= 9
  end
  while number >= 5
    roman << 'V'
    number -= 5
  end
  while number >= 4
    roman << 'IV'
    number -= 4
  end
  while number >= 1
    roman << 'I'
    number -= 1
  end
  return roman
end

#isRTLTextDirObject Also known as: is_rtl_text_dir

Return the current temporary RTL status

@return boolean

true: RTL, false: LTR

@access public
@since 4.8.014 (2009-11-04)


1051
1052
1053
1054
1055
1056
1057
# File 'lib/rbpdf.rb', line 1051

def isRTLTextDir()
  if @tmprtl != false
    return @tmprtl == 'R'
  else
    return @rtl
  end
end

#lastPage(resetmargins = false) ⇒ Object Also known as: last_page

Reset pointer to the last document page.

@param boolean :resetmargins

if true reset left, right, top margins and Y position.

@access public
@since 2.0.000 (2008-01-04)
@see

setPage(), getPage(), getNumPages()



1651
1652
1653
# File 'lib/rbpdf.rb', line 1651

def lastPage(resetmargins=false)
  setPage(getNumPages(), resetmargins)
end

#Line(x1, y1, x2, y2, style = nil) ⇒ Object Also known as: line

Draws a line between two points.

@param float :x1

Abscissa of first point

@param float :y1

Ordinate of first point

@param float :x2

Abscissa of second point

@param float :y2]

Ordinate of second point

@param hash :style

Line style. Array like for SetLineStyle SetLineStyle. Default value: default line style (empty array).

@access public
@since 1.0
@see

SetLineWidth(), SetDrawColor(), SetLineStyle()



9077
9078
9079
9080
9081
9082
9083
9084
# File 'lib/rbpdf.rb', line 9077

def Line(x1, y1, x2, y2, style=nil)
  if style.is_a? Hash
    SetLineStyle(style)
  end
  outPoint(x1, y1)
  outLine(x2, y2)
  out('S')
end

Puts a link on a rectangular area of the page. Text or image links are generally put via Cell(), Write() or Image(), but this method can be useful for instance to define a clickable area inside an image.

@param float :x

Abscissa of the upper-left corner of the rectangle

@param float :y

Ordinate of the upper-left corner of the rectangle

@param float :w

Width of the rectangle

@param float :h

Height of the rectangle

@param mixed :link

URL or identifier returned by AddLink()

@param int :spaces

number of spaces on the text to link

@access public
@since 1.5
@see

AddLink(), Annotation(), Cell(), Write(), Image()



3049
3050
3051
# File 'lib/rbpdf.rb', line 3049

def Link(x, y, w, h, link, spaces=0)
  Annotation(x, y, w, h, link, {'Subtype'=>'Link'}, spaces)
end

#ListBox(name, w, h, values, prop = {}, opt = {}, x = '', y = '', js = false) ⇒ Object Also known as: list_box

Creates a List-box field

@param string :name

field name

@param int :w

width

@param int :h

height

@param array :values

array containing the list of values.

@param array :prop

javascript field properties. Possible values are described on official Javascript for Acrobat API reference.

@param array :opt

annotation parameters. Possible values are described on official PDF32000_2008 reference.

@param float :x

Abscissa of the upper-left corner of the rectangle

@param float :y

Ordinate of the upper-left corner of the rectangle

@param boolean :js

if true put the field using JavaScript (requires Acrobat Writer to be rendered).

@access public
@author Nicola Asuni
@since 4.8.000 (2009-09-07)


10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996
10997
10998
10999
11000
11001
11002
11003
11004
11005
11006
11007
11008
11009
11010
11011
11012
11013
11014
11015
11016
11017
11018
11019
11020
11021
11022
11023
11024
11025
11026
11027
11028
11029
11030
11031
11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
11045
11046
11047
11048
11049
11050
11051
11052
11053
11054
11055
# File 'lib/rbpdf.rb', line 10986

def ListBox(name, w, h, values, prop = {}, opt = {}, x = '', y = '', js = false)
  x = @x if x == ''
  y = @y if y == ''

  if js
    addfield('listbox', name, x, y, w, h, prop)
    s = ''
    values.each {|v|
      if v.is_a?(Array)
        s << "['#{v[0]}','#{v[1]}'],"
      else
        s << "'#{v}',"
      end
    }
    @javascript << "f#{name}.setItems([#{s[0...-1]}]);\n"
    return
  end
  # get default style
  prop = getFormDefaultProp.merge prop
  # get annotation data
  popt = getAnnotOptFromJSProp(prop)
  # set additional default values
  font = @font_family
  fontkey = @fontkeys.index font
  unless @annotation_fonts.include? fontkey
    @annotation_fonts[font] = fontkey
  end
  s = ''
  values.each {|v|
    if v.is_a?(Array)
      s << "#{v[1]}\n"
    else
      s << "#{v}\n"
    end
  }

  fontstyle = sprintf('/F%d %.2f Tf %s', fontkey + 1, @font_size_pt, @text_color)
  popt['da'] = fontstyle
  popt['ap'] = {}
  # set Appearances
  popt['ap']['n'] = "/Tx BMC q #{fontstyle} "
  gvars = getGraphicVars()
  @h = h
  @w = w
  @t_margin = 0
  @c_margin = 0.2

  @tmp_buffer = ''
  multi_cell(w, h, s, 0, '', 0, 0, 0.2, 0, true, 0, false, true, 0)
  popt['ap']['n'] << @tmp_buffer
  popt['ap']['n'] << 'Q EMC'
  @tmp_buffer = nil

  # restore previous values
  setGraphicVars(gvars, true)

  # merge options
  opt = popt.merge opt
  # set remaining annotation data
  opt['Subtype'] = 'Widget'
  opt['ft'] = 'Ch'
  opt['t'] = name
  opt['opt'] = values
  Annotation(x, y, w, h, name, opt, 0)
  if @rtl
    @x -= w
  else
    @x += w
  end
end

#Ln(h = '', cell = false) ⇒ Object Also known as: ln

Performs a line break. The current abscissa goes back to the left margin and the ordinate increases by the amount passed in parameter.

@param float :h

The height of the break. By default, the value equals the height of the last printed cell.

@param boolean :cell

if true add a c_margin to the x coordinate

@access public
@since 1.0
@see

Cell()



5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
# File 'lib/rbpdf.rb', line 5422

def Ln(h='', cell=false)
  if (@num_columns > 0) and (@y == @columns[@current_column]['y']) and @columns[@current_column]['x'] and (@x == @columns[@current_column]['x'])
    # revove vertical space from the top of the column
    return
  end
  if cell
    cellmargin = @c_margin
  else
    cellmargin = 0
  end
  if @rtl
    @x = @w - @r_margin - cellmargin
  else
    @x = @l_margin + cellmargin
  end
  if h.is_a?(String)
    @y += @lasth
  else
    @y += h
  end
  @newline = true
end

#loggerObject



117
118
119
120
121
122
123
124
125
126
# File 'lib/rbpdf.rb', line 117

def logger
  if defined? Rails.logger
    Rails.logger
  else
    # This particular error will occur when the test suite is run from outside a Rails environment.
    # We use the standard Ruby stdout logger in that case.
    require 'logger'
    return Logger.new(STDOUT)
  end
end

#movePage(frompage, topage) ⇒ Object Also known as: move_page

Move a page to a previous position.

@param int :frompage

number of the source page

@param int :topage

number of the destination page (must be less than :frompage)

@return

true in case of success, false in case of error.

@access public
@since 4.5.000 (2009-01-02)


15756
15757
15758
15759
15760
15761
15762
15763
15764
15765
15766
15767
15768
15769
15770
15771
15772
15773
15774
15775
15776
15777
15778
15779
15780
15781
15782
15783
15784
15785
15786
15787
15788
15789
15790
15791
15792
15793
15794
15795
15796
15797
15798
15799
15800
15801
15802
15803
15804
15805
15806
15807
15808
15809
15810
15811
15812
15813
15814
15815
15816
15817
15818
15819
15820
15821
15822
15823
15824
15825
15826
15827
15828
15829
15830
15831
15832
15833
15834
15835
15836
15837
15838
15839
15840
15841
15842
15843
15844
15845
15846
15847
15848
15849
15850
15851
15852
15853
15854
15855
15856
15857
15858
15859
15860
15861
15862
15863
15864
15865
15866
15867
15868
15869
15870
15871
15872
15873
15874
15875
15876
15877
15878
15879
15880
15881
15882
15883
15884
15885
15886
# File 'lib/rbpdf.rb', line 15756

def movePage(frompage, topage)
  if (frompage > @numpages) or (frompage <= topage)
    return false
  end
  if frompage == @page
    # close the page before moving it
    endPage()
  end
  # move all page-related states
  tmppage = @pages[frompage]
  tmppagedim = @pagedim[frompage]
  tmppagelen = @pagelen[frompage]
  tmpintmrk = @intmrk[frompage]
  if @footerpos[frompage]
    tmpfooterpos = @footerpos[frompage]
  end
  if @footerlen[frompage]
    tmpfooterlen = @footerlen[frompage]
  end
  if @transfmrk[frompage]
    tmptransfmrk = @transfmrk[frompage]
  end
  if @page_annots[frompage]
    tmpannots = @page_annots[frompage]
  end
  if @newpagegroup[frompage]
    tmpnewpagegroup = @newpagegroup[frompage]
  end
  frompage.downto(topage + 1) do |i|
    j = i - 1
    # shift pages down
    @pages[i] = @pages[j]
    @pagedim[i] = @pagedim[j]
    @pagelen[i] = @pagelen[j]
    @intmrk[i] = @intmrk[j]
    if @footerpos[j]
      @footerpos[i] = @footerpos[j]
    elsif footerpos[i]
      @footerpos[i] = nil
    end
    if @footerlen[j]
      @footerlen[i] = @footerlen[j]
    elsif @footerlen[i]
      @footerlen[i] = nil
    end
    if @transfmrk[j]
      @transfmrk[i] = @transfmrk[j]
    elsif @transfmrk[i]
      @transfmrk[i] = nil
    end
    if @page_annots[j]
      @page_annots[i] = @page_annots[j]
    elsif @page_annots[i]
      @page_annots[i] = nil
    end
    if @newpagegroup[j]
      @newpagegroup[i] = @newpagegroup[j]
    elsif @newpagegroup[i]
      @newpagegroup[i] = nil
    end
  end
  @pages[topage] = tmppage
  @pagedim[topage] = tmppagedim
  @pagelen[topage] = tmppagelen
  @intmrk[topage] = tmpintmrk
  if tmpfooterpos
    @footerpos[topage] = tmpfooterpos
  elsif @footerpos[topage]
    @footerpos[topage] = nil
  end
  if tmpfooterlen
    @footerlen[topage] = tmpfooterlen
  elsif @footerlen[topage]
    @footerlen[topage] = nil
  end
  if tmptransfmrk
    @transfmrk[topage] = tmptransfmrk
  elsif @transfmrk[topage]
    @transfmrk[topage] = nil
  end
  if tmpannots
    @page_annots[topage] = tmpannots
  elsif @page_annots[topage]
    @page_annots[topage] = nil
  end
  if tmpnewpagegroup
    @newpagegroup[topage] = tmpnewpagegroup
  elsif @newpagegroup[topage]
    @newpagegroup[topage] = nil
  end
  # adjust outlines
  tmpoutlines = @outlines
  tmpoutlines.each_with_index do |outline, key|
    if (outline[:p] >= topage) and (outline[:p] < frompage)
      @outlines[key][:p] = outline[:p] + 1
    elsif outline[:p] == frompage
      @outlines[key][:p] = topage
    end
  end
  # adjust links
  tmplinks = @links
  tmplinks.each_with_index do |link, key|
    next if link.nil?
    if (link[0] >= topage) and (link[0] < frompage)
      @links[key][0] = link[0] + 1
    elsif link[0] == frompage
      @links[key][0] = topage
    end
  end
  ### T.B.D ### TCPDF 5.0.001 ###
  # adjust javascript
  #tmpjavascript = @javascript
  #global jfrompage, jtopage
  #jfrompage = frompage
  #jtopage = topage
  #tmpjavascript =~ /this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/
  #pagenum = $3.to_i + 1
  #if (pagenum >= jtopage) && (pagenum < jfrompage)
  #  newpage = pagenum + 1
  #elsif pagenum == jfrompage
  #  newpage = jtopage
  #else
  #  newpage = pagenum
  #end
  #newpage -= 1
  #@javascript = "this.addField(\'" + $1 + "\',\'" + $2 + "\'," + newpage + ""

  # return to last page
  lastPage(true)
  return true
end

#MultiCell(w, h, txt, border = 0, align = 'J', fill = 0, ln = 1, x = '', y = '', reseth = true, stretch = 0, ishtml = false, autopadding = true, maxh = 0) ⇒ Object Also known as: multi_cell

This method allows printing text with line breaks. They can be automatic (as soon as the text reaches the right border of the cell) or explicit (via the n character). As many cells as necessary are output, one below the other. Text can be aligned, centered or justified. The cell block can be framed and the background painted.

@param float :w

Width of cells. If 0, they extend up to the right margin of the page.

@param float :h

Cell minimum height. The cell extends automatically if needed.

@param string :txt

String to print

@param mixed :border

Indicates if borders must be drawn around the cell block. The value can be either a number:

  • 0: no border (default)

  • 1: frame

or a string containing some or all of the following characters (in any order):

  • L: left

  • T: top

  • R: right

  • B: bottom

@param string :align

Allows to center or align the text. Possible values are:

  • L or empty string: left align

  • C: center

  • R: right align

  • J: justification (default value when :ishtml=false)

@param int :fill

Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.

@param int :ln

Indicates where the current position should go after the call. Possible values are:

  • 0: to the right

  • 1: to the beginning of the next line [DEFAULT]

  • 2: below

@param float :x

x position in user units

@param float :y

y position in user units

@param boolean :reseth

if true reset the last cell height (default true).

@param int :stretch

stretch carachter mode:

  • 0 = disabled

  • 1 = horizontal scaling only if necessary

  • 2 = forced horizontal scaling

  • 3 = character spacing only if necessary

  • 4 = forced character spacing

@param boolean :ishtml

set to true if :txt is HTML content (default = false).

@param boolean :autopadding

if true, uses internal padding and automatically adjust it to account for line width.

@param float :maxh

maximum height. It should be >= :h and less then remaining space to the bottom of the page, or 0 for disable this feature. This feature works only when :ishtml=false.

@return int

Rerurn the number of cells or 1 for html mode.

@access public
@since 1.3
@see

SetFont(), SetDrawColor(), SetFillColor(), SetTextColor(), SetLineWidth(), Cell(), Write(), SetAutoPageBreak()



3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
# File 'lib/rbpdf.rb', line 3871

def MultiCell(w, h, txt, border=0, align='J', fill=0, ln=1, x='', y='', reseth=true, stretch=0, ishtml=false, autopadding=true, maxh=0)

  @x ||= 0

  w = 0 unless w.is_a?(Numeric)
  h = 0 unless h.is_a?(Numeric)

  if empty_string(@lasth) or reseth
    # set row height
    @lasth = @font_size * @cell_height_ratio
  end

  if !empty_string(y)
    SetY(y)
  else
    y = GetY()
  end
  resth = 0
  if !@in_footer and (y + h > @page_break_trigger)
    # spit cell in two pages
    newh = @page_break_trigger - y
    resth = h - newh # cell to be printed on the next page
    h = newh
  end
  # get current page number
  startpage = @page

  if !empty_string(x)
    SetX(x)
  else
    x = GetX()
  end

  if empty_string(w) or (w <= 0)
    if @rtl
      w = @x - @l_margin
    else
      w = @w - @r_margin - @x
    end
  end

  # store original margin values
  l_margin = @l_margin
  r_margin = @r_margin

  if @rtl
    SetRightMargin(@w - @x)
    SetLeftMargin(@x - w)
  else
    SetLeftMargin(@x)
    SetRightMargin(@w - @x - w)
  end

  starty = @y
  if autopadding
    # Adjust internal padding
    if @c_margin < (@line_width / 2.0)
      @c_margin = @line_width / 2.0
    end
    # Add top space if needed
    if (@lasth - @font_size) < @line_width
      @y += @line_width / 2.0
    end
    # add top padding
    @y += @c_margin
  end

  if ishtml
    # ******* Write HTML text
    writeHTML(txt, true, false, reseth, true, align)
    nl = 1
  else
    # ******* Write text
    nl = Write(@lasth, txt, '', 0, align, true, stretch, false, true, maxh)
  end

  if autopadding
    # add bottom padding
    @y += @c_margin
    # Add bottom space if needed
    if (@lasth - @font_size) < @line_width
      @y += @line_width / 2.0
    end
  end

  # Get end-of-text Y position
  currentY = @y
  # get latest page number
  end_page = @page
  if resth > 0
    skip = end_page - startpage
    tmpresth = resth
    while tmpresth > 0
      if skip <= 0
        # add a page (or trig AcceptPageBreak() for multicolumn mode)
        checkPageBreak(@page_break_trigger + 1)
      end
      tmpresth -= (@h - @t_margin - @b_margin)
      skip -= 1
    end
    currentY = @y
    end_page = @page
  end

  # check if a new page has been created
  if end_page > startpage
    # design borders around HTML cells.
    for page in startpage..end_page
      setPage(page)
      if page == startpage
        # first page
        @y = starty # put cursor at the beginning of cell on the first page
        h = @h - starty - @b_margin
        cborder = getBorderMode(border, position='start')
      elsif page == end_page
        # last page
        @y = @t_margin # put cursor at the beginning of last page
        h = currentY - @t_margin
        if resth > h
          h = resth
        end
        cborder = getBorderMode(border, position='end')
      else
        @y = @t_margin # put cursor at the beginning of the current page
        h = @h - @t_margin - @b_margin
        resth -= h
        cborder = getBorderMode(border, position='middle')
      end
      nx = x
      # account for margin changes
      if page > startpage
        if @rtl and (@pagedim[page]['orm'] != @pagedim[startpage]['orm'])
          nx = x + (@pagedim[page]['orm'] - @pagedim[startpage]['orm'])
        elsif !@rtl and (@pagedim[page]['olm'] != @pagedim[startpage]['olm'])
          nx = x + (@pagedim[page]['olm'] - @pagedim[startpage]['olm'])
        end
      end
      SetX(nx)

      prevLastH = @lasth
      ccode = getCellCode(w, h, '', cborder, 1, '', fill, '', 0, false)
      @lasth = prevLastH

      if (cborder != 0) or (fill == 1)
        pagebuff = getPageBuffer(@page)
        pstart = pagebuff[0, @intmrk[@page]]
        pend = pagebuff[@intmrk[@page]..-1]
        setPageBuffer(@page, pstart + ccode + "\n" + pend)
        @intmrk[@page] += (ccode + "\n").length
      end
    end
  else
    h = [h, currentY - y].max
    # put cursor at the beginning of text
    SetY(y)
    SetX(x)

    prevLastH = @lasth
    # design a cell around the text
    ccode = getCellCode(w, h, '', border, 1, '', fill, '', 0, true)
    @lasth = prevLastH

    if @tmp_buffer
      @tmp_buffer = "#{ccode}\n#{@tmp_buffer}"
    elsif (border != 0) or (fill == 1)
      if !@transfmrk[@page].nil?
        pagemark = @transfmrk[@page]
        @transfmrk[@page] += (ccode + "\n").length
      elsif @in_footer
        pagemark = @footerpos[@page]
        @footerpos[@page] += (ccode + "\n").length
      else
        pagemark = @intmrk[@page]
        @intmrk[@page] += (ccode + "\n").length
      end
      pagebuff = getPageBuffer(@page)
      pstart = pagebuff[0, pagemark]
      pend = pagebuff[pagemark..-1].to_s
      setPageBuffer(@page, pstart + ccode + "\n" + pend)
    end
  end

  # Get end-of-cell Y position
  currentY = GetY()

  # restore original margin values
  SetLeftMargin(l_margin)
  SetRightMargin(r_margin)

  if ln > 0
    # Go to the beginning of the next line
    SetY(currentY)
    if ln == 2
      SetX(x + w)
    end
  else
    # go left or right by case
    setPage(startpage)
    @y = y
    SetX(x + w)
  end

  setContentMark()
  return nl
rescue => err
  Error('MultiCell Error.', err)
end

#objclone(object) ⇒ Object

Creates a copy of a class object

@param object :object

class object to be cloned

@return

cloned object

@access public
@since 4.5.029 (2009-03-19)


16371
16372
16373
16374
16375
16376
16377
16378
16379
16380
16381
# File 'lib/rbpdf.rb', line 16371

def objclone(object)
  if @diskcache
    newobj = object.dup
    newobj.cache_file_length = object.cache_file_length.dup
    newobj.prev_pages = object.prev_pages.dup
    newobj.pages = object.pages.dup
    return newobj
  else
    return Marshal.load(Marshal.dump(object))
  end
end

#OpenObject

This method begins the generation of the PDF document. It is not necessary to call it explicitly because AddPage() does it automatically.

  • Note: no page is created by this method

@access public
@since 1.0
@see

AddPage(), Close()



1551
1552
1553
1554
# File 'lib/rbpdf.rb', line 1551

def Open()
  #Begin document
  @state = 1
end

#Output(name = '', dest = '') ⇒ Object Also known as: output

Send the document to a given destination: string, local file or browser. In the last case, the plug-in may be used (if present) or a download (“Save as” dialog box) may be forced. The method first calls Close() if necessary to terminate the document.

@param string :name

The name of the file when saved. Note that special characters are removed and blanks characters are replaced with the underscore character.

@param string :dest

Destination where to send the document. It can take one of the following values:

  • I: send the file inline to the browser (default). The plug-in is used if available. The name given by name is used when one selects the “Save as” option on the link generating the PDF.

  • D: send to the browser and force a file download with the name given by name.

  • F: save to a local server file with the name given by name.

  • S: return the document as a string. name is ignored.

  • FI: equivalent to F + I option

  • FD: equivalent to F + D option

@access public
@since 1.0
@see

Close()



5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
# File 'lib/rbpdf.rb', line 5580

def Output(name='', dest='')
  #Output PDF to some destination
  #Finish document if necessary

  lastPage()

  if (@state < 3)
    Close();
  end
  #Normalize parameters
  # Boolean no longer supported
  # if (dest.is_a?(Boolean))
  #   dest = dest ? 'D' : 'F';
  # end
  dest = dest.upcase
  if (dest=='')
    if (name=='')
      name='doc.pdf';
      dest='I';
    else
      dest='F';
    end
  end
  case (dest)
  when 'I'
      # This is PHP specific code
      ##Send to standard output
      # if (ob_get_contents())
      #   Error('Some data has already been output, can\'t send PDF file');
      # end
      # if (php_sapi_name()!='cli')
      #   #We send to a browser
      #   header('Content-Type: application/pdf');
      #   if (headers_sent())
      #     Error('Some data has already been output to browser, can\'t send PDF file');
      #   end
      #   header('Content-Length: ' + @buffer.length);
      #   header('Content-disposition: inline; filename="' + name + '"');
      # end
    return getBuffer
  when 'D'
      # PHP specific
      #Download file
      # if (ob_get_contents())
      #   Error('Some data has already been output, can\'t send PDF file');
      # end
      # if (!_SERVER['HTTP_USER_AGENT'].nil? && SERVER['HTTP_USER_AGENT'].include?('MSIE'))
      #   header('Content-Type: application/force-download');
      # else
      #   header('Content-Type: application/octet-stream');
      # end
      # if (headers_sent())
      #   Error('Some data has already been output to browser, can\'t send PDF file');
      # end
      # header('Content-Length: '+ @buffer.length);
      # header('Content-disposition: attachment; filename="' + name + '"');
    return getBuffer
  when 'F', 'FI', 'FD'
    # Save PDF to a local file
    if @diskcache
      FileUtils.copy(@buffer.path, name)
    else
      open(name,'wb') do |f|
        f.write(@buffer)
      end
    end
    if dest == 'FI'
    # This is PHP specific code
    #  # send headers to browser
    #  header('Content-Type: application/pdf')
    #  header('Cache-Control: public, must-revalidate, max-age=0') # HTTP/1.1
    #  header('Pragma: public')
    #  header('Expires: Sat, 26 Jul 1997 05:00:00 GMT') # Date in the past
    #  header('Last-Modified: ' + gmdate('D, d M Y H:i:s') + ' GMT')
    #  header('Content-Length: ' + filesize(name))
    #  header('Content-Disposition: inline; filename="' + File.basename(name) + '";')
      # send document to the browser
      data = ''
      open(name) do |f| data<< f.read ;end
      return data
    elsif dest == 'FD'
    # This is PHP specific code
    #  # send headers to browser
    #  if ob_get_contents()
    #    Error('Some data has already been output, can\'t send PDF file')
    #  end
    #  header('Content-Description: File Transfer')
    #  if headers_sent())
    #    Error('Some data has already been output to browser, can\'t send PDF file')
    #  end
    #  header('Cache-Control: public, must-revalidate, max-age=0') # HTTP/1.1
    #  header('Pragma: public')
    #  header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); # Date in the past
    #  header('Last-Modified: ' + gmdate('D, d M Y H:i:s') + ' GMT')
    #  # force download dialog
    #  header('Content-Type: application/force-download')
    #  header('Content-Type: application/octet-stream', false)
    #  header('Content-Type: application/download', false)
    #  header('Content-Type: application/pdf', false)
    #  # use the Content-Disposition header to supply a recommended filename
    #  header('Content-Disposition: attachment; filename="' + File.basename(name) + '";')
    #  header('Content-Transfer-Encoding: binary')
    #  header('Content-Length: ' + filesize(name))
      # send document to the browser
      data = ''
      open(name) do |f| data<< f.read ;end
      return data
    end
  when 'S'
    # Returns PDF as a string
    return getBuffer
  else
    Error('Incorrect output destination: ' + dest);
  end
  return '';
ensure
  destroy(true)
end

#PageNoObject Also known as: page_no

Returns the current page number.

@return int

page number

@access public
@since 1.0
@see

alias_nb_pages()



2226
2227
2228
2229
# File 'lib/rbpdf.rb', line 2226

def PageNo()
  #Get current page number
  return @page;
end

#PageNoFormattedObject Also known as: page_no_formatted

Returns the current page number formatted as a string.

@access public
@since 4.2.005 (2008-11-06)
@see

PaneNo(), formatPageNumber()



11509
11510
11511
# File 'lib/rbpdf.rb', line 11509

def PageNoFormatted()
  return formatPageNumber(PageNo())
end

#PieSector(xc, yc, r, a, b, style = 'FD', cw = true, o = 90) ⇒ Object Also known as: pie_sector

Draw the sector of a circle. It can be used for instance to render pie charts.

@param float :xc

abscissa of the center.

@param float :yc

ordinate of the center.

@param float :r

radius.

@param float :a

start angle (in degrees).

@param float :b

end angle (in degrees).

@param string :style

Style of rendering. See the getPathPaintOperator() function for more information.

@param float :cw

indicates whether to go clockwise (default: true).

@param float :o

origin of angles (0 for 3 o’clock, 90 for noon, 180 for 9 o’clock, 270 for 6 o’clock). Default: 90.

@author

Maxime Delorme, Nicola Asuni

@since 3.1.000 (2008-06-09)
@access public


11753
11754
11755
# File 'lib/rbpdf.rb', line 11753

def PieSector(xc, yc, r, a, b, style='FD', cw=true, o=90)
  PieSectorXY(xc, yc, r, r, a, b, style, cw, o)
end

#PieSectorXY(xc, yc, rx, ry, a, b, style = 'FD', cw = false, o = 0, nc = 2) ⇒ Object Also known as: pie_sector_xy

Draw the sector of an ellipse. It can be used for instance to render pie charts.

@param float :xc

abscissa of the center.

@param float :yc

ordinate of the center.

@param float :rx

the x-axis radius.

@param float :ry

the y-axis radius.

@param float :a

start angle (in degrees).

@param float :b

end angle (in degrees).

@param string :style

Style of rendering. See the getPathPaintOperator() function for more information.

@param float :cw

indicates whether to go clockwise.

@param float :o

origin of angles (0 for 3 o’clock, 90 for noon, 180 for 9 o’clock, 270 for 6 o’clock).

@param integer :nc

Number of curves used to draw a 90 degrees portion of arc.

@author

Maxime Delorme, Nicola Asuni

@since 3.1.000 (2008-06-09)
@access public


11775
11776
11777
11778
11779
11780
11781
11782
11783
11784
11785
11786
11787
11788
11789
11790
11791
11792
11793
11794
# File 'lib/rbpdf.rb', line 11775

def PieSectorXY(xc, yc, rx, ry, a, b, style='FD', cw=false, o=0, nc=2)
  if @rtl
    xc = @w - xc
  end
  op = getPathPaintOperator(style)
  ### not use ###
  #if op == 'f'
  #  line_style = nil
  #end
  if cw
    d = b
    b = 360 - a + o
    a = 360 - d + o
  else
    b += o
    a += o
  end
  outellipticalarc(xc, yc, rx, ry, 0, a, b, true, nc)
  out(op)
end

#pixelsToUnits(px) ⇒ Object Also known as: pixels_to_units

Converts pixels to Units.

@param int

:px pixels

@return float

millimeters

@access public
@see

setImageScale(), getImageScale()



8741
8742
8743
# File 'lib/rbpdf.rb', line 8741

def pixelsToUnits(px)
  return (px.to_f / (@img_scale * @k))
end

#Polygon(p, style = '', line_style = nil, fill_color = nil, closed = true) ⇒ Object Also known as: polygon

Draws a polygon.

@param array :p

Points 0 to (np - 1). Array with values (x0, y0, x1, y1,…, x(np-1), y(np - 1))

@param string :style

Style of rendering. See the getPathPaintOperator() function for more information.

@param array :line_style

Line style of polygon. Array with keys among the following:

  • all: Line style of all lines. Array like for SetLineStyle SetLineStyle.

  • 0 to (:np - 1): Line style of each line. Array like for SetLineStyle SetLineStyle.

If a key is not present or is null, not draws the line. Default value is default line style (empty array).

@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).

@param boolean :closed

if true the polygon is closes, otherwise will remain open

@access public
@since 2.1.000 (2008-01-08)


9367
9368
9369
9370
9371
9372
9373
9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
9436
9437
9438
9439
# File 'lib/rbpdf.rb', line 9367

def Polygon(p, style='', line_style=nil, fill_color=nil, closed=true)
  style = '' if style.nil?
  nc = p.length # number of coordinates
  np = nc / 2 # number of points
  if closed
    # close polygon by adding the first 2 points at the end (one line)
    0.upto(3) do |i|
      p[nc + i] = p[i]
    end
    # copy style for the last added line
    if line_style
      if line_style.is_a? Array and line_style[0]
        line_style[np] = line_style[0]
      elsif line_style.is_a? Hash and line_style['all']
        line_style[np] = line_style['all']
      end
    end
    nc += 4
  end
  if (nil != style.index('F')) and fill_color
    SetFillColorArray(fill_color)
  end
  op = getPathPaintOperator(style)
  if op == 'f'
    line_style = []
  end
  draw = true
  if line_style
    if line_style.is_a? Hash and line_style['all']
      SetLineStyle(line_style['all'])
    else
      draw = false
      if op == 'B'
        # draw fill
        op = 'f'
        outPoint(p[0], p[1])
        2.step(nc - 1, 2) do |i|
          outLine(p[i], p[i + 1])
        end
        out(op)
      end
      # draw outline
      outPoint(p[0], p[1])
      2.step(nc - 1, 2) do |i|
        line_num = i / 2 - 1
        if line_style[line_num]
          if line_style[line_num] != 0
            if line_style[line_num].is_a? Hash
              out('S')
              SetLineStyle(line_style[line_num])
              outPoint(p[i - 2], p[i - 1])
              outLine(p[i], p[i + 1])
              out('S')
              outPoint(p[i], p[i + 1])
            else
              outLine(p[i], p[i + 1])
            end
          end
        else
          outLine(p[i], p[i + 1])
        end
      end
      out(op)
    end
  end
  if draw
    outPoint(p[0], p[1])
    2.step(nc - 1, 2) do |i|
      outLine(p[i], p[i + 1])
    end
    out(op)
  end
end

#PolyLine(p, style = '', line_style = nil, fill_color = nil) ⇒ Object Also known as: poly_line

Draws a polygonal line

@param array :p

Points 0 to (:np - 1). Array with values (x0, y0, x1, y1,…, x(np-1), y(np - 1))

@param string :style

Style of rendering. See the getPathPaintOperator() function for more information.

@param array :line_style

Line style of polygon. Array with keys among the following:

  • all: Line style of all lines. Array like for SetLineStyle SetLineStyle.

  • 0 to (:np - 1): Line style of each line. Array like for SetLineStyle SetLineStyle.

If a key is not present or is null, not draws the line. Default value is default line style (empty array).

[@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). [@param boolean :closed if true the polygon is closes, otherwise will remain open

@access public
@since 4.8.003 (2009-09-15)


9348
9349
9350
# File 'lib/rbpdf.rb', line 9348

def PolyLine(p, style='', line_style=nil, fill_color=nil)
  Polygon(p, style, line_style, fill_color, false)
end

#putjavascriptObject

Create a javascript PDF string.

@access protected
@author Johannes G???ntert, Nicola Asuni
@since 2.1.002 (2008-02-12)


10462
10463
10464
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493
10494
10495
10496
10497
10498
10499
10500
10501
10502
# File 'lib/rbpdf.rb', line 10462

def putjavascript()
  return if @javascript.empty? && @js_objects.empty?

  if @javascript.index 'this.addField'
    # @setUserRights() unless @ur

    # the following two lines are used to avoid form fields duplication after saving
    # The addField method only works on Acrobat Writer, unless the document is signed with Adobe private key (UR3)
    jsa = sprintf("ftcpdfdocsaved=this.addField('%s','%s',%d,[%.2f,%.2f,%.2f,%.2f]);", 'tcpdfdocsaved', 'text', 0, 0, 1, 0, 1)
    jsb = "getField('tcpdfdocsaved').value='saved';"
    @javascript = "#{jsa}\n#{@javascript}\n#{jsb}"
  end
  @n_js = newobj()
  out = ' << /Names ['
  unless @javascript.empty?
    out << " (EmbeddedJS) #{@n + 1} 0 R"
  end
  unless @js_objects.empty?
    @js_objects.each{|key, val|
      out << " (JS#{key}) #{key} 0 R" if val['onload']
    }
  end
  out << ' ] >> endobj'
  out(out)
  # default Javascript object
  unless @javascript.empty?
    newobj()
    out = '<< /S /JavaScript'
    out << " /JS #{textstring(@javascript)}"
    out << ' >> endobj'
    out(out)
  end
  # additional Javascript objects
  unless @js_objects.empty?
    @js_objects.each {|key, val|
      @offsets[key] = @bufferlen
      out = "#{key} 0 obj\n << /S /JavaScript /JS #{textstring(val['js'])} >> endobj"
      out(out)
    }
  end
end

#RadioButton(name, w, prop = {}, opt = {}, onvalue = 'On', checked = false, x = '', y = '', js = false) ⇒ Object Also known as: radio_button

Creates a RadioButton field

@param string :name

field name

@param int :w

width

@param array :prop

javascript field properties. Possible values are described on official Javascript for Acrobat API reference.

@param array :opt

annotation parameters. Possible values are described on official PDF32000_2008 reference.

@param string :onvalue

value to be returned if selected.

@param boolean :checked

define the initial state.

@param float :x

Abscissa of the upper-left corner of the rectangle

@param float :y

Ordinate of the upper-left corner of the rectangle

@param boolean :js

if true put the field using JavaScript (requires Acrobat Writer to be rendered).

@access public
@author Nicola Asuni
@since 4.8.000 (2009-09-07)


10909
10910
10911
10912
10913
10914
10915
10916
10917
10918
10919
10920
10921
10922
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935
10936
10937
10938
10939
10940
10941
10942
10943
10944
10945
10946
10947
10948
10949
10950
10951
10952
10953
10954
10955
10956
10957
10958
10959
10960
10961
10962
10963
10964
10965
10966
10967
10968
# File 'lib/rbpdf.rb', line 10909

def RadioButton(name, w, prop = {}, opt = {}, onvalue = 'On', checked = false, x = '', y = '', js = false)
  x = @x if x == ''
  y = @y if y == ''

  if js
    addfield('radiobutton', name, x, y, w, w, prop)
    return
  end

  onvalue = 'On' if empty_string(onvalue)
  defval = checked ? onvalue : 'Off'
  # set data for parent group
  @radiobutton_groups[@page] ||= {}
  unless @radiobutton_groups[@page][name]
    @radiobutton_groups[@page][name] = []
    @annot_obj_id += 1
    @radio_groups << @annot_obj_id
  end
  # save object ID to be added on Kids entry on parent object
  @radiobutton_groups[@page][name] << {'kid' => @annot_obj_id + 1, 'def' => defval}
  # get default style
  prop = getFormDefaultProp.merge prop
  prop['NoToggleToOff'] = 'true'
  prop['Radio'] = 'true'
  prop['borderStyle'] = 'inset'
  # get annotation data
  popt = getAnnotOptFromJSProp(prop)
  # set additional default values
  font = 'zapfdingbats'
  AddFont(font)
  fontkey = @fontkeys.index font
  unless @annotation_fonts.include? fontkey
    @annotation_fonts[font] = fontkey
  end
  fontstyle = sprintf('/F%d %.2f Tf', fontkey + 1, @font_size_pt)
  popt['da'] = "#{fontstyle} #{@text_color}"
  popt['ap'] = {}
  popt['ap']['n'] = {}
  popt['ap']['n'][onvalue] = "q #{@text_color} BT #{fontstyle} 0 0 Td (n) Tj ET Q"
  popt['ap']['n']['Off'] = "q #{@text_color} BT #{fontstyle} 0 0 Td (o) Tj ET Q"
  popt['mk'] ||= {}
  popt['mk']['ca'] = '(l)'
  # merge options
  opt = popt.merge opt
  # set remaining annotation data
  opt['Subtype'] = 'Widget'
  opt['ft'] = 'Btn'
  if checked
    opt['v'] = ["/#{onvalue}"]
    opt['as'] = onvalue
  else
    opt['as'] = 'Off'
  end
  Annotation(x, y, w, w, name, opt, 0)
  if @rtl
    @x -= w
  else
    @x += w
  end
end

#Rect(x, y, w, h, style = '', border_style = {}, fill_color = {}) ⇒ Object Also known as: rect

Draws a rectangle.

@param float :x

Abscissa of upper-left corner (or upper-right corner for RTL language).

@param float :y

Ordinate of upper-left corner (or upper-right corner for RTL language).

@param float :w

Width.

@param float :h

Height.

@param string :style

Style of rendering. See the getPathPaintOperator() function for more information.

  • all: Line style of all borders. Array like for SetLineStyle SetLineStyle.

  • L, T, R, B or combinations: Line style of left, top, right or bottom border. Array like for SetLineStyle SetLineStyle.

If a key is not present or is null, not draws the border. Default value: default line style (empty array).

@param array :border_style

Border style of rectangle. Array like for SetLineStyle SetLineStyle. Default value: default line style (empty array).

@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).

@access public
@since 1.0
@see

SetLineStyle()



9104
9105
9106
9107
9108
9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
9138
9139
# File 'lib/rbpdf.rb', line 9104

def Rect(x, y, w, h, style='', border_style={}, fill_color={})
  if style.index('F') != nil and !fill_color.empty?
    SetFillColorArray(fill_color)
  end
  op = getPathPaintOperator(style)
  if !border_style or !border_style['all'].nil?
    if !border_style['all'].nil? and border_style['all']
      SetLineStyle(border_style['all'])
      border_style = {}
    end
  end
  outRect(x, y, w, h, op)

  if border_style
    border_style2 = {}
    border_style.each { |line, value|
      length = line.length
      0.upto(length - 1) do |i|
        border_style2[line[i]] = value
      end
    }
    border_style = border_style2
    if !border_style['L'].nil? and border_style['L']
      Line(x, y, x, y + h, border_style['L'])
    end
    if !border_style['T'].nil? and border_style['T']
      Line(x, y, x + w, y, border_style['T'])
    end
    if !border_style['R'].nil? and border_style['R']
      Line(x + w, y, x + w, y + h, border_style['R'])
    end
    if !border_style['B'].nil? and border_style['B']
      Line(x, y + h, x + w, y + h, border_style['B'])
    end
  end
end

#RegularPolygon(x0, y0, r, ns, angle = 0, draw_circle = false, style = '', line_style = nil, fill_color = nil, circle_style = '', circle_outLine_style = nil, circle_fill_color = nil) ⇒ Object Also known as: regular_polygon

Draws a regular polygon.

@param float :x0

Abscissa of center point.

@param float :y0

Ordinate of center point.

@param float :r

Radius of inscribed circle.

@param integer :ns

Number of sides.

@param float :angle

Angle oriented (anti-clockwise). Default value: 0.

@param boolean :draw_circle

Draw inscribed circle or not. Default value: false.

@param string :style

Style of rendering. See the getPathPaintOperator() function for more information.

@param array :line_style

Line style of polygon sides. Array with keys among the following:

  • all: Line style of all sides. Array like for SetLineStyle SetLineStyle.

  • 0 to (:ns - 1): Line style of each side. Array like for SetLineStyle SetLineStyle.

If a key is not present or is null, not draws the side. Default value is default line style (empty array).

@param array :fill_color

Fill color. Format: array(red, green, blue). Default value: default color (empty array).

@param string :circle_style

Style of rendering of inscribed circle (if draws). Possible values are:

  • D or empty string: Draw (default).

  • F: Fill.

  • DF or FD: Draw and fill.

  • CNZ: Clipping mode (using the even-odd rule to determine which regions lie inside the clipping path).

  • CEO: Clipping mode (using the nonzero winding number rule to determine which regions lie inside the clipping path).

@param array :circle_outLine_style

Line style of inscribed circle (if draws). Array like for SetLineStyle SetLineStyle. Default value: default line style (empty array).

@param array :circle_fill_color

Fill color of inscribed circle (if draws). Format: array(red, green, blue). Default value: default color (empty array).

@access public
@since 2.1.000 (2008-01-08)


9469
9470
9471
9472
9473
9474
9475
9476
9477
9478
9479
9480
9481
9482
9483
9484
9485
# File 'lib/rbpdf.rb', line 9469

def RegularPolygon(x0, y0, r, ns, angle=0, draw_circle=false, style='', line_style=nil, fill_color=nil, circle_style='', circle_outLine_style=nil, circle_fill_color=nil)
  draw_circle = false if draw_circle == 0
  if 3 > ns
    ns = 3
  end
  if draw_circle
    Circle(x0, y0, r, 0, 360, circle_style, circle_outLine_style, circle_fill_color)
  end
  p = []
  0.upto(ns - 1) do |i|
    a = angle + i * 360 / ns
    a_rad = a * ::Math::PI / 180 # deg2rad
    p.push x0 + (r * ::Math.sin(a_rad))
    p.push y0 + (r * ::Math.cos(a_rad))
  end
  Polygon(p, style, line_style, fill_color)
end

#removeSHY(txt = '') ⇒ Object Also known as: remove_shy

Removes SHY characters from text. Unicode Data:

* Name : SOFT HYPHEN, commonly abbreviated as SHY
* HTML Entity (decimal): &#173;
* HTML Entity (hex): &#xad;
* HTML Entity (named): &shy;
* How to type in Microsoft Windows: [Alt +00AD] or [Alt 0173]
* UTF-8 (hex): 0xC2 0xAD (c2ad)
* UTF-8 character: chr(194).chr(173)
@param string :txt

input string

@return string

without SHY characters.

@access public
@since (4.5.019) 2009-02-28


3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
# File 'lib/rbpdf.rb', line 3337

def removeSHY(txt='')
  txt = txt.dup
  txt.force_encoding('ASCII-8BIT') if txt.respond_to?(:force_encoding)
  txt.gsub!(/([\xc2]{1}[\xad]{1})/, '')
  if !@is_unicode
    txt.gsub!(/([\xad]{1})/, '')
    return txt
  end
  txt.force_encoding('UTF-8') if txt.respond_to?(:force_encoding)
  return txt
end

#revstrpos(haystack, needle, offset = 0) ⇒ Object

Find position of last occurrence of a substring in a string

@param string :haystack

The string to search in.

@param string :needle

substring to search.

@param int :offset

May be specified to begin searching an arbitrary number of characters into the string.

@return

Returns the position where the needle exists. Returns FALSE if the needle was not found.

@access public
@since 4.8.038 (2010-03-13)


16406
16407
16408
16409
16410
16411
16412
# File 'lib/rbpdf.rb', line 16406

def revstrpos(haystack, needle, offset = 0)
  length = haystack.length
  offset = (offset > 0) ? (length - offset) : offset.abs
  pos = haystack.reverse.index(needle.reverse, offset)

  return (pos.nil? ? nil : length - pos - needle.length)
end

#rollbackTransaction(this_self = false) ⇒ Object Also known as: rollback_transaction

This method allows to undo the latest transaction by returning the latest saved RBPDF object with startTransaction().

@param boolean :this_self

if true restores current class object to previous state without the need of reassignment via the returned value.

@return

RBPDF object.

@access public
@since 4.5.029 (2009-03-19)


16338
16339
16340
16341
16342
16343
16344
16345
16346
16347
16348
16349
16350
16351
16352
16353
16354
16355
16356
16357
16358
16359
16360
16361
# File 'lib/rbpdf.rb', line 16338

def rollbackTransaction(this_self=false)
  if @objcopy
    if @objcopy.diskcache
      # truncate files to previous values
      @objcopy.cache_file_length.each { |file, length|
        File.truncate(file, length) if File.exist?(file)
      }
      @pages.each_with_index do |file, i|
        if @prev_pages[i] and File.exist?(@prev_pages[i].path)
          File.delete(file.path)
        end
      end
    end
    destroy(true, true)
    if this_self
      objvars = @objcopy.instance_variables
      objvars.each {|key|
        eval("#{key} = @objcopy.instance_variable_get(key)") if key.to_s != '@objcopy'
      }
    end
    return @objcopy
  end
  return self
end

#Rotate(angle, x = "", y = "") ⇒ Object Also known as: rotate

Rotate object.

@param float :angle

angle in degrees for counter-clockwise rotation

@param int :x

abscissa of the rotation center. Default is current x position

@param int :y

ordinate of the rotation center. Default is current y position

@access public
@since 2.1.000 (2008-01-07)
@see

StartTransform(), StopTransform()



8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
# File 'lib/rbpdf.rb', line 8834

def Rotate(angle, x="", y="")
  if (x == '')
    x = @x
  end

  if (y == '')
    y = @y
  end

  y = (@h - y) * @k
  x *= @k

  # calculate elements of transformation matrix
  tm = []
  tm[0] = ::Math::cos(angle * ::Math::PI / 180) # deg2rad
  tm[1] = ::Math::sin(angle * ::Math::PI / 180) # deg2rad
  tm[2] = -tm[1]
  tm[3] = tm[0]
  tm[4] = x + tm[1] * y - tm[0] * x
  tm[5] = y - tm[0] * y - tm[1] * x

  # generate the transformation matrix
  Transform(tm)
end

#RoundedRect(x, y, w, h, r, round_corner = '1111', style = '', border_style = nil, fill_color = nil) ⇒ Object Also known as: rounded_rect

Draws a rounded rectangle.

@param float :x

Abscissa of upper-left corner.

@param float :y

Ordinate of upper-left corner.

@param float :w

Width.

@param float :h

Height.

@param float :r

the radius of the circle used to round off the corners of the rectangle.

@param string :round_corner

Draws rounded corner or not. String with a 0 (not rounded i-corner) or 1 (rounded i-corner) in i-position. Positions are, in order and begin to 0: top left, top right, bottom right and bottom left. Default value: all rounded corner (“1111”).

@param string :style

Style of rendering. See the getPathPaintOperator() function for more information.

@param array :border_style

Border style of rectangle. Array like for SetLineStyle SetLineStyle. Default value: default line style (empty array).

@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).

@access public
@since 2.1.000 (2008-01-08)


9561
9562
9563
# File 'lib/rbpdf.rb', line 9561

def RoundedRect(x, y, w, h, r, round_corner='1111', style='', border_style=nil, fill_color=nil)
  RoundedRectXY(x, y, w, h, r, r, round_corner, style, border_style, fill_color)
end

#RoundedRectXY(x, y, w, h, rx, ry, round_corner = '1111', style = '', border_style = nil, fill_color = nil) ⇒ Object Also known as: rounded_rect_xy

Draws a rounded rectangle.

@param float :x

Abscissa of upper-left corner.

@param float :y

Ordinate of upper-left corner.

@param float :w

Width.

@param float :h

Height.

@param float :rx

the x-axis radius of the ellipse used to round off the corners of the rectangle.

@param float :ry

the y-axis radius of the ellipse used to round off the corners of the rectangle.

@param string :round_corner

Draws rounded corner or not. String with a 0 (not rounded i-corner) or 1 (rounded i-corner) in i-position. Positions are, in order and begin to 0: top left, top right, bottom right and bottom left. Default value: all rounded corner (“1111”).

@param string :style

Style of rendering. See the getPathPaintOperator() function for more information.

@param array :border_style

Border style of rectangle. Array like for SetLineStyle SetLineStyle. Default value: default line style (empty array).

@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).

@access public
@since 4.9.019 (2010-04-22)


9581
9582
9583
9584
9585
9586
9587
9588
9589
9590
9591
9592
9593
9594
9595
9596
9597
9598
9599
9600
9601
9602
9603
9604
9605
9606
9607
9608
9609
9610
9611
9612
9613
9614
9615
9616
9617
9618
9619
9620
9621
9622
9623
9624
9625
9626
9627
9628
9629
9630
9631
9632
9633
9634
9635
# File 'lib/rbpdf.rb', line 9581

def RoundedRectXY(x, y, w, h, rx, ry, round_corner='1111', style='', border_style=nil, fill_color=nil)
  style = '' if style.nil?
  if (round_corner == '0000') or ((rx == ry) and (rx == 0))
    # Not rounded
    Rect(x, y, w, h, style, border_style, fill_color)
    return
  end
  # Rounded
  if (nil != style.index('F')) and fill_color
    SetFillColorArray(fill_color)
  end
  op = getPathPaintOperator(style)
  if op == 'f'
    border_style = []
  end
  if border_style
    SetLineStyle(border_style)
  end
  myArc = 4 / 3.0 * (::Math.sqrt(2) - 1)
  outPoint(x + rx, y)
  xc = x + w - rx
  yc = y + ry
  outLine(xc, y)
  if round_corner[0,1] == '1'
    outCurve(xc + (rx * myArc), yc - ry, xc + rx, yc - (ry * myArc), xc + rx, yc)
  else
    outLine(x + w, y)
  end
  xc = x + w - rx
  yc = y + h - ry
  outLine(x + w, yc)
  if round_corner[1,1] == '1'
    outCurve(xc + rx, yc + (ry * myArc), xc + (rx * myArc), yc + ry, xc, yc + ry)
  else
    outLine(x + w, y + h)
  end
  xc = x + rx
  yc = y + h - ry
  outLine(xc, y + h)
  if round_corner[2,1] == '1'
    outCurve(xc - (rx * myArc), yc + ry, xc - rx, yc + (ry * myArc), xc - rx, yc)
  else
    outLine(x, y + h)
  end
  xc = x + rx
  yc = y + ry
  outLine(x, yc)
  if round_corner[3,1] == '1'
    outCurve(xc - rx, yc - (ry * myArc), xc - (rx * myArc), yc - ry, xc, yc - ry)
  else
    outLine(x, y)
    outLine(x + rx, y)
  end
  out(op)
end

#setAlpha(alpha, bm = 'Normal') ⇒ Object Also known as: set_alpha

Set alpha for stroking (CA) and non-stroking (ca) operations.

@param float :alpha

real value from 0 (transparent) to 1 (opaque)

@param string :bm

blend mode, one of the following: Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity

@access public
@since 3.0.000 (2008-03-27)


11626
11627
11628
11629
# File 'lib/rbpdf.rb', line 11626

def setAlpha(alpha, bm='Normal')
  gs = addExtGState({'ca' => alpha, 'CA' => alpha, 'BM' => '/' + bm, 'AIS' => 'false'})
  setExtGState(gs)
end

#SetAuthor(author) ⇒ Object Also known as: set_author

Defines the author of the document.

@param string :author

The name of the author.

@access public
@since 1.2
@see

SetCreator(), SetKeywords(), SetSubject(), SetTitle()



1490
1491
1492
1493
# File 'lib/rbpdf.rb', line 1490

def SetAuthor(author)
  #Author of document
  @author = author
end

#SetAutoPageBreak(auto, margin = 0) ⇒ Object Also known as: set_auto_page_break

Enables or disables the automatic page breaking mode. When enabling, the second parameter is the distance from the bottom of the page that defines the triggering limit. By default, the mode is on and the margin is 2 cm.

@param boolean :auto

Boolean indicating if mode should be on or off.

@param float :margin

Distance from the bottom of the page.

@access public
@since 1.0
@see

Cell(), MultiCell(), AcceptPageBreak()



1361
1362
1363
1364
1365
1366
# File 'lib/rbpdf.rb', line 1361

def SetAutoPageBreak(auto, margin=0)
  #Set auto page break mode and triggering margin
  @auto_page_break = auto
  @b_margin = margin
  @page_break_trigger = @h - margin
end

#SetBooklet(booklet = true, inner = -1,, outer = -1)) ⇒ Object Also known as: set_booklet

Set the booklet mode for double-sided pages.

@param boolean :booklet

true set the booklet mode on, fals eotherwise.

@param float :inner

Inner page margin.

@param float :outer

Outer page margin.

@access public
@since 4.2.000 (2008-10-29)


15113
15114
15115
15116
15117
15118
15119
15120
15121
# File 'lib/rbpdf.rb', line 15113

def SetBooklet(booklet=true, inner=-1, outer=-1)
  @booklet = booklet
  if inner >= 0
    @l_margin = inner
  end
  if outer >= 0
    @r_margin = outer
  end
end

#setCellHeightRatio(h) ⇒ Object Also known as: set_cell_height_ratio

Set the height of cell repect font height.

@param int :h

cell proportion respect font height (typical value = 1.25).

@access public
@since 3.0.014 (2008-06-04)


11652
11653
11654
# File 'lib/rbpdf.rb', line 11652

def setCellHeightRatio(h)
  @cell_height_ratio = h
end

#SetCellPadding(pad) ⇒ Object Also known as: set_cell_padding

Set the internal Cell padding.

@param float :pad

internal padding.

@access public
@since 2.1.000 (2008-01-09)
@see

Cell(), SetLeftMargin(), SetTopMargin(), SetAutoPageBreak(), SetMargins()



1348
1349
1350
# File 'lib/rbpdf.rb', line 1348

def SetCellPadding(pad)
  @c_margin = pad
end

#SetCompression(compress) ⇒ Object Also known as: set_compression

Activates or deactivates page compression. When activated, the internal representation of each page is compressed, which leads to a compression ratio of about 2 for the resulting document. Compression is on by default.

  • Note: the Zlib extension is required for this feature. If not present, compression will be turned off.

@param boolean :compress

Boolean indicating if compression must be enabled.

@access public
@since 1.4


1447
1448
1449
1450
1451
1452
1453
1454
# File 'lib/rbpdf.rb', line 1447

def SetCompression(compress)
  #Set page compression
  if Object.const_defined?(:Zlib)
    @compress = compress
  else
    @compress = false
  end
end

#SetCreator(creator) ⇒ Object Also known as: set_creator

Defines the creator of the document. This is typically the name of the application that generates the PDF.

@param string :creator

The name of the creator.

@access public
@since 1.2
@see

SetAuthor(), SetKeywords(), SetSubject(), SetTitle()



1516
1517
1518
1519
# File 'lib/rbpdf.rb', line 1516

def SetCreator(creator)
  #Creator of document
  @creator = creator
end

#SetDefaultMonospacedFont(font) ⇒ Object Also known as: set_default_monospaced_font

Defines the default monospaced font.

@param string :font

Font name.

@access public
@since 4.5.025


2996
2997
2998
# File 'lib/rbpdf.rb', line 2996

def SetDefaultMonospacedFont(font)
  @default_monospaced_font = font
end

#SetDisplayMode(zoom, layout = 'SinglePage', mode = 'UseNone') ⇒ Object Also known as: set_display_mode

Defines the way the document is to be displayed by the viewer.

@param mixed :zoom

The zoom to use. It can be one of the following string values or a number indicating the zooming factor to use.

  • fullpage: displays the entire page on screen

  • fullwidth: uses maximum width of window

  • real: uses real size (equivalent to 100% zoom)

  • default: uses viewer default mode

@param string :layout

The page layout. Possible values are:

  • SinglePage Display one page at a time

  • OneColumn Display the pages in one column

  • TwoColumnLeft Display the pages in two columns, with odd-numbered pages on the left

  • TwoColumnRight Display the pages in two columns, with odd-numbered pages on the right

  • TwoPageLeft (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the left

  • TwoPageRight (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the right

@param string :mode

A name object specifying how the document should be displayed when opened:

  • UseNone Neither document outline nor thumbnail images visible

  • UseOutlines Document outline visible

  • UseThumbs Thumbnail images visible

  • FullScreen Full-screen mode, with no menu bar, window controls, or any other window visible

  • UseOC (PDF 1.5) Optional content group panel visible

  • UseAttachments (PDF 1.6) Attachments panel visible

@access public
@since 1.2


1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
# File 'lib/rbpdf.rb', line 1396

def SetDisplayMode(zoom, layout='SinglePage', mode='UseNone')
  #Set display mode in viewer
  if (zoom == 'fullpage' or zoom == 'fullwidth' or zoom == 'real' or zoom == 'default' or zoom.is_a?(Numeric))
    @zoom_mode = zoom
  else
    Error('Incorrect zoom display mode: ' + zoom)
  end

  case layout
  when 'default', 'single', 'SinglePage'
    @layout_mode = 'SinglePage'
  when 'continuous', 'OneColumn'
    @layout_mode = 'OneColumn'
  when 'two', 'TwoColumnLeft'
    @layout_mode = 'TwoColumnLeft'
  when 'TwoColumnRight'
    @layout_mode = 'TwoColumnRight'
  when 'TwoPageLeft'
    @layout_mode = 'TwoPageLeft'
  when 'TwoPageRight'
    @layout_mode = 'TwoPageRight'
  else
    @layout_mode = 'SinglePage'
  end

  case mode
  when 'UseNone'
    @page_mode = 'UseNone'
  when 'UseOutlines'
    @page_mode = 'UseOutlines'
  when 'UseThumbs'
    @page_mode = 'UseThumbs'
  when 'FullScreen'
    @page_mode = 'FullScreen'
  when 'UseOC'
    @page_mode = 'UseOC'
  when ''
    @page_mode = 'UseAttachments'
  else
    @page_mode = 'UseNone'
  end
end

#SetDrawColor(col1 = 0, col2 = -1,, col3 = -1,, col4 = -1)) ⇒ Object Also known as: set_draw_color

Defines the color used for all drawing operations (lines, rectangles and cell borders). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.

@param int :col1

Gray level for single color, or Red color for RGB, or Cyan color for CMYK. Value between 0 and 255

@param int :col2

Green color for RGB, or Magenta color for CMYK. Value between 0 and 255

@param int :col3

Blue color for RGB, or Yellow color for CMYK. Value between 0 and 255

@param int :col4

Key (Black) color for CMYK. Value between 0 and 255

@access public
@since 1.3
@see

SetFillColor(), SetTextColor(), Line(), Rect(), Cell(), MultiCell()



2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
# File 'lib/rbpdf.rb', line 2285

def SetDrawColor(col1=0, col2=-1, col3=-1, col4=-1)
  # set default values
  unless col1.is_a?(Numeric)
    col1 = 0
  end
  unless col2.is_a?(Numeric)
    col2 = 0
  end
  unless col3.is_a?(Numeric)
    col3 = 0
  end
  unless col4.is_a?(Numeric)
    col4 = 0
  end
  #Set color for all stroking operations
  if (col2 == -1) and (col3 == -1) and (col4 == -1)
    # Grey scale
    @draw_color = sprintf('%.3f G', col1 / 255.0)
    @strokecolor['G'] = col1
  elsif col4 == -1
    # RGB
    @draw_color = sprintf('%.3f %.3f %.3f RG', col1 / 255.0, col2 / 255.0, col3 / 255.0)
    @strokecolor['R'] = col1
    @strokecolor['G'] = col2
    @strokecolor['B'] = col3
  else
    # CMYK
    @draw_color = sprintf('%.3f %.3f %.3f %.3f K', col1 / 100.0, col2 / 100.0, col3 / 100.0, col4 / 100.0)
    @strokecolor['C'] = col1
    @strokecolor['M'] = col2
    @strokecolor['Y'] = col3
    @strokecolor['K'] = col4
  end
  if (@page>0)
    out(@draw_color + ' ')
  end
end

#SetDrawColorArray(color) ⇒ Object Also known as: set_draw_color_array

Defines the color used for all drawing operations (lines, rectangles and cell borders). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.

@param array or ordered hash :color

array(or ordered hash) of colors

@access public
@since 3.1.000 (2008-6-11)
@see

SetDrawColor()



2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
# File 'lib/rbpdf.rb', line 2261

def SetDrawColorArray(color)
  if !color.nil?
    color = color.values if color.is_a? Hash
    r = !color[0].nil? ? color[0] : -1
    g = !color[1].nil? ? color[1] : -1
    b = !color[2].nil? ? color[2] : -1
    k = !color[3].nil? ? color[3] : -1
    if r >= 0
      SetDrawColor(r, g, b, k)
    end
  end
end

#SetFillColor(col1 = 0, col2 = -1,, col3 = -1,, col4 = -1)) ⇒ Object Also known as: set_fill_color

Defines the color used for all filling operations (filled rectangles and cell backgrounds). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.

@param int :col1

Gray level for single color, or Red color for RGB, or Cyan color for CMYK. Value between 0 and 255

@param int :col2

Green color for RGB, or Magenta color for CMYK. Value between 0 and 255

@param int :col3

Blue color for RGB, or Yellow color for CMYK. Value between 0 and 255

@param int :col4

Key (Black) color for CMYK. Value between 0 and 255

@access public
@since 1.3
@see

SetDrawColor(), SetTextColor(), Rect(), Cell(), MultiCell()



2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
# File 'lib/rbpdf.rb', line 2357

def SetFillColor(col1=0, col2=-1, col3=-1, col4=-1)
  # set default values
  unless col1.is_a?(Numeric)
    col1 = 0
  end
  unless col2.is_a?(Numeric)
    col2 = -1
  end
  unless col3.is_a?(Numeric)
    col3 = -1
  end
  unless col4.is_a?(Numeric)
    col4 = -1
  end

  # Set color for all filling operations
  if (col2 == -1) and (col3 == -1) and (col4 == -1)
    # Grey scale
    @fill_color = sprintf('%.3f g', col1 / 255.0)
    @bgcolor['G'] = col1
  elsif col4 == -1
    # RGB
    @fill_color = sprintf('%.3f %.3f %.3f rg', col1 / 255.0, col2 / 255.0, col3 / 255.0)
    @bgcolor['R'] = col1
    @bgcolor['G'] = col2
    @bgcolor['B'] = col3
  else
    # CMYK
    @fill_color = sprintf('%.3f %.3f %.3f %.3f k', col1 / 100.0, col2 / 100.0, col3 / 100.0, col4 / 100.0)
    @bgcolor['C'] = col1
    @bgcolor['M'] = col2
    @bgcolor['Y'] = col3
    @bgcolor['K'] = col4
  end

  @color_flag = (@fill_color != @text_color)
  if @page > 0
    out(@fill_color)
  end
end

#SetFillColorArray(color) ⇒ Object Also known as: set_fill_color_array

Defines the color used for all filling operations (filled rectangles and cell backgrounds). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.

@param array or ordered hash :color

array(or ordered hash) of colors

@access public
@since 3.1.000 (2008-6-11)
@see

SetFillColor()



2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
# File 'lib/rbpdf.rb', line 2333

def SetFillColorArray(color)
  if !color.nil?
    color = color.values if color.is_a? Hash
    r = !color[0].nil? ? color[0] : -1
    g = !color[1].nil? ? color[1] : -1
    b = !color[2].nil? ? color[2] : -1
    k = !color[3].nil? ? color[3] : -1
    if r >= 0
      SetFillColor(r, g, b, k)
    end
  end
end

#SetFont(family, style = '', size = 0, fontfile = '', subset = nil) ⇒ Object Also known as: set_font

Sets the font used to print character strings. The font can be either a standard one or a font added via the AddFont() method. Standard fonts use Windows encoding cp1252 (Western Europe). The method can be called before the first page is created and the font is retained from page to page. If you just wish to change the current font size, it is simpler to call SetFontSize().

  • Note: for the standard fonts, the font metric files must be accessible. There are three possibilities for this:

    • They are in the current directory (the one where the running script lies)

    • They are in one of the directories defined by the include_path parameter

    • They are in the directory defined by the FPDF_FONTPATH constant

@param string :family

Family font. It can be either a name defined by AddFont() or one of the standard Type1 families (case insensitive):

  • times (Times-Roman)

  • timesb (Times-Bold)

  • timesi (Times-Italic)

  • timesbi (Times-BoldItalic)

  • helvetica (Helvetica)

  • helveticab (Helvetica-Bold)

  • helveticai (Helvetica-Oblique)

  • helveticabi (Helvetica-BoldOblique)

  • courier (Courier)

  • courierb (Courier-Bold)

  • courieri (Courier-Oblique)

  • courierbi (Courier-BoldOblique)

  • symbol (Symbol)

  • zapfdingbats (ZapfDingbats)

It is also possible to pass an empty string. In that case, the current family is retained.

@param string :style

Font style. Possible values are (case insensitive):

  • empty string: regular

  • B: bold

  • I: italic

  • U: underline

  • D: line trough

  • O: overline

or any combination. The default value is regular. Bold and italic styles do not apply to Symbol and ZapfDingbats basic fonts or other fonts when not defined.

@param float :size

Font size in points. The default value is the current size. If no size has been specified since the beginning of the document, the value taken is 12

@param string :fontfile

The font definition file. By default, the name is built from the family and style, in lower case with no spaces.

@param boolean :subset

if true embedd only a subset of the font (stores only the information related to the used characters); this option is valid only for TrueTypeUnicode fonts. If you want to enable users to change the document, set this parameter to false. If you subset the font, the person who receives your PDF would need to have your same font in order to make changes to your PDF. The file size of the PDF would also be smaller because you are embedding only part of a font.

@author Nicola Asuni
@access public
@since 1.0
@see

AddFont(), SetFontSize()



2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
# File 'lib/rbpdf.rb', line 2903

def SetFont(family, style='', size=0, fontfile='', subset=nil)
  # Select a font; size given in points
  if size == 0
    size = @font_size_pt
  end
  # try to add font (if not already added)
  fontdata =  AddFont(family, style, fontfile, subset)
  @font_family = fontdata['family']
  @font_style = fontdata['style']
  @current_font = getFontBuffer(fontdata['fontkey'])
  SetFontSize(size)
end

#SetFontSize(size) ⇒ Object Also known as: set_font_size

Defines the size of the current font.

@param float :size

The size (in points)

@access public
@since 1.0
@see

SetFont()



2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
# File 'lib/rbpdf.rb', line 2924

def SetFontSize(size)
  #Set font size in points
  @font_size_pt = size;
  @font_size = size.to_f / @k;
  if !@current_font['desc'].nil? and !@current_font['desc']['Ascent'].nil? and (@current_font['desc']['Ascent'] > 0)
    @font_ascent = @current_font['desc']['Ascent'] * @font_size / 1000.0
  else
    @font_ascent = 0.85 * @font_size
  end
  if !@current_font['desc'].nil? and !@current_font['desc']['Descent'].nil? and (@current_font['desc']['Descent'] <= 0)
    @font_descent = - @current_font['desc']['Descent'] * @font_size / 1000.0
  else
    @font_descent = 0.15 * @font_size
  end
  if (@page > 0) and !@current_font['i'].nil?
    out(sprintf('BT /F%d %.2f Tf ET ', @current_font['i'], @font_size_pt));
  end
end

#setFontSubsetting(subset) ⇒ Object Also known as: set_font_subsetting

Set Font Subsetting.

@param boolean :subset

subset of the font default setting.

@access public


8495
8496
8497
# File 'lib/rbpdf.rb', line 8495

def setFontSubsetting(subset)
  @font_subsetting = (subset == true ? true : false)
end

#setFooterFont(font) ⇒ Object Also known as: set_footer_font

Set footer font.

@param array :font

font

@access public
@since 1.1


8543
8544
8545
# File 'lib/rbpdf.rb', line 8543

def setFooterFont(font)
  @footer_font = font;
end

#SetFooterFont(font) ⇒ Object



8548
8549
8550
8551
# File 'lib/rbpdf.rb', line 8548

def SetFooterFont(font)
  warn "[DEPRECATION] 'SetFooterFont' is deprecated. Please use 'set_footer_font' instead."
  setFooterFont(font)
end

#setFooterMargin(fm = 10) ⇒ Object Also known as: set_footer_margin

Set footer margin. (minimum distance between footer and bottom page margin)

@param int :fm

distance in millimeters

@access public


1931
1932
1933
# File 'lib/rbpdf.rb', line 1931

def setFooterMargin(fm=10)
  @footer_margin = fm;
end

#SetFooterMargin(fm = 10) ⇒ Object



1936
1937
1938
1939
# File 'lib/rbpdf.rb', line 1936

def SetFooterMargin(fm=10)
  warn "[DEPRECATION] 'SetFooterMargin' is deprecated. Please use 'set_footer_margin' instead."
  setFooterMargin(fm)
end

#setFormDefaultProp(prop = []) ⇒ Object Also known as: set_form_default_prop

Set default properties for form fields.

@param array :prop

javascript field properties. Possible values are described on official Javascript for Acrobat API reference.

@access public
@author Nicola Asuni
@since 4.8.000 (2009-09-06)


10769
10770
10771
# File 'lib/rbpdf.rb', line 10769

def setFormDefaultProp(prop = [])
  @default_form_prop = prop
end

#setHeaderData(ln = "", lw = 0, ht = "", hs = "") ⇒ Object Also known as: set_header_data

Set header data.

@param string :ln

header image logo

@param string :lw

header image logo width in mm

@param string :ht

string to print as title on document header

@param string :hs

string to print on document header

@access public


1865
1866
1867
1868
1869
1870
# File 'lib/rbpdf.rb', line 1865

def setHeaderData(ln="", lw=0, ht="", hs="")
  @header_logo = ln || ""
  @header_logo_width = lw || 0
  @header_title = ht || ""
  @header_string = hs || ""
end

#SetHeaderData(ln = "", lw = 0, ht = "", hs = "") ⇒ Object



1873
1874
1875
1876
# File 'lib/rbpdf.rb', line 1873

def SetHeaderData(ln="", lw=0, ht="", hs="")
  warn "[DEPRECATION] 'SetHeaderData' is deprecated. Please use 'set_header_data' instead."
  setHeaderData(ln, lw, ht, hs)
end

#setHeaderFont(font) ⇒ Object Also known as: set_header_font

Set header font.

@param array :font

font

@access public
@since 1.1


8516
8517
8518
# File 'lib/rbpdf.rb', line 8516

def setHeaderFont(font)
  @header_font = font;
end

#SetHeaderFont(font) ⇒ Object



8521
8522
8523
8524
# File 'lib/rbpdf.rb', line 8521

def SetHeaderFont(font)
  warn "[DEPRECATION] 'SetHeaderFont' is deprecated. Please use 'set_header_font' instead."
  setHeaderFont(font)
end

#setHeaderMargin(hm = 10) ⇒ Object Also known as: set_header_margin

Set header margin. (minimum distance between header and top page margin)

@param int :hm

distance in user units

@access public


1904
1905
1906
# File 'lib/rbpdf.rb', line 1904

def setHeaderMargin(hm=10)
  @header_margin = hm;
end

#SetHeaderMargin(hm = 10) ⇒ Object



1909
1910
1911
1912
# File 'lib/rbpdf.rb', line 1909

def SetHeaderMargin(hm=10)
  warn "[DEPRECATION] 'SetHeaderMargin' is deprecated. Please use 'set_header_margin' instead."
  setHeaderMargin(hm)
end

#setHtmlVSpace(tagvs) ⇒ Object Also known as: set_html_v_space

Set the vertical spaces for HTML tags. The array must have the following structure (example):

:tagvs = {'h1' => [{'h' => '', 'n' => 2}, {'h' => 1.3, 'n' => 1}]}

The first array level contains the tag names, the second level contains 0 for opening tags or 1 for closing tags, the third level contains the vertical space unit (h) and the number spaces to add (n). If the h parameter is not specified, default values are used.

@param array :tagvs

array of tags and relative vertical spaces.

@access public
@since 4.2.001 (2008-10-30)


15155
15156
15157
# File 'lib/rbpdf.rb', line 15155

def setHtmlVSpace(tagvs)
  @tagvspaces = tagvs
end

#setImageScale(scale) ⇒ Object Also known as: set_image_scale

Set the adjusting factor to convert pixels to user units.

@param float :scale

adjusting factor to convert pixels to user units.

@author

Nicola Asuni

@access public
@since 1.5.2


1104
1105
1106
# File 'lib/rbpdf.rb', line 1104

def setImageScale(scale)
  @img_scale = scale;
end

#SetImageScale(scale) ⇒ Object



1109
1110
1111
1112
# File 'lib/rbpdf.rb', line 1109

def SetImageScale(scale)
  warn "[DEPRECATION] 'SetImageScale' is deprecated. Please use 'set_image_scale' instead."
  setImageScale(scale)
end

#setJPEGQuality(quality) ⇒ Object Also known as: set_jpeg_quality

Set the default JPEG compression quality (1-100)

@param int :quality

JPEG quality, integer between 1 and 100

@access public
@since 3.0.000 (2008-03-27)


11638
11639
11640
11641
11642
11643
# File 'lib/rbpdf.rb', line 11638

def setJPEGQuality(quality)
  if (quality < 1) or (quality > 100)
    quality = 75
  end
  @jpeg_quality = quality
end

#SetKeywords(keywords) ⇒ Object Also known as: set_keywords

Associates keywords with the document, generally in the form ‘keyword1 keyword2 …’.

@param string :keywords

The list of keywords.

@access public
@since 1.2
@see

SetAuthor(), SetCreator(), SetSubject(), SetTitle()



1503
1504
1505
1506
# File 'lib/rbpdf.rb', line 1503

def SetKeywords(keywords)
  #Keywords of document
  @keywords = keywords
end

#setLanguageArray(language) ⇒ Object Also known as: set_language_array

Set language array.

@param array :language
@since 1.1


8569
8570
8571
8572
8573
8574
8575
8576
# File 'lib/rbpdf.rb', line 8569

def setLanguageArray(language)
  @l = language;
  if @l['a_meta_dir']
    @rtl = (@l['a_meta_dir'] == 'rtl') ? true : false
  else
    @rtl = false
  end
end

#SetLanguageArray(language) ⇒ Object



8579
8580
8581
8582
# File 'lib/rbpdf.rb', line 8579

def SetLanguageArray(language)
  warn "[DEPRECATION] 'SetLanguageArray' is deprecated. Please use 'set_language_array' instead."
  setLanguageArray(language)
end

#setLastH(h) ⇒ Object Also known as: set_last_h

Set the last cell height.

@param float :h

cell height.

@author

Nicola Asuni

@access public
@since 1.53.0.TC034


1081
1082
1083
# File 'lib/rbpdf.rb', line 1081

def setLastH(h)
  @lasth = h
end

#SetLeftMargin(margin) ⇒ Object Also known as: set_left_margin

Defines the left margin. The method can be called before creating the first page. If the current abscissa gets out of page, it is brought back to the margin.

@param float :margin

The margin.

@access public
@since 1.4
@see

SetTopMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins()



1301
1302
1303
1304
1305
1306
1307
# File 'lib/rbpdf.rb', line 1301

def SetLeftMargin(margin)
  #Set left margin
  @l_margin = margin
  if (@page > 0) and (@x < margin)
    @x = margin
  end
end

#SetLineStyle(style) ⇒ Object Also known as: set_line_style

Set line style.

@param hash :style

Line style. Array with keys among the following:

  • width (float): Width of the line in user units.

  • cap (string): Type of cap to put on the line. Possible values are: butt, round, square. The difference between “square” and “butt” is that “square” projects a flat end past the end of the line.

  • join (string): Type of join. Possible values are: miter, round, bevel.

  • dash (mixed): Dash pattern. Is 0 (without dash) or string with series of length values, which are the lengths of the on and off dashes. For example: “2” represents 2 on, 2 off, 2 on, 2 off, …; “2,1” is 2 on, 1 off, 2 on, 1 off, …

  • phase (integer): Modifier on the dash pattern which is used to shift the point at which the pattern starts.

  • color (array): Draw color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K).

@access public
@since 2.1.000 (2008-01-08)


8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
8949
8950
8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
# File 'lib/rbpdf.rb', line 8925

def SetLineStyle(style)
  unless style.is_a? Hash
    return
  end
  if !style['width'].nil?
    width = style['width']
    width_prev = @line_width
    SetLineWidth(width)
    @line_width = width_prev
  end
  if !style['cap'].nil?
    cap = style['cap']
    ca = {'butt' => 0, 'round'=> 1, 'square' => 2}
    if !ca[cap].nil?
      @linestyle_cap = ca[cap].to_s + ' J'
      out(@linestyle_cap)
    end
  end
  if !style['join'].nil?
    join = style['join']
    ja = {'miter' => 0, 'round' => 1, 'bevel' => 2}
    if !ja[join].nil?
      @linestyle_join = ja[join].to_s + ' j'
      out(@linestyle_join);
    end
  end
  if !style['dash'].nil?
    dash = style['dash']
    dash_string = ''
    if dash != 0 and dash != ''
      if dash.is_a?(String) && dash =~ /^.+,/
        tab = dash.split(',')
      else
        tab = [dash]
      end
      dash_string = ''
      tab.each_with_index { |v, i|
        if i != 0
          dash_string << ' '
        end
        dash_string << sprintf("%.2f", v.to_f)
      }
    end
    phase = 0
    @linestyle_dash = sprintf("[%s] %.2f d", dash_string, phase)
    out(@linestyle_dash)
  end
  if !style['color'].nil?
    color = style['color']
    SetDrawColorArray(color)
  end
end

#SetLineWidth(width) ⇒ Object Also known as: set_line_width

Defines the line width. By default, the value equals 0.2 mm. The method can be called before the first page is created and the value is retained from page to page.

@param float :width

The width.

@access public
@since 1.0
@see

Line(), Rect(), Cell(), MultiCell()



8890
8891
8892
8893
8894
8895
8896
8897
# File 'lib/rbpdf.rb', line 8890

def SetLineWidth(width)
  #Set line width
  @line_width = width;
  @linestyle_width = sprintf('%.2f w', width * @k)
  if (@page>0)
    out(@linestyle_width)
  end
end

Defines the page and position a link points to

@param int :link

The link identifier returned by AddLink()

@param float :y

Ordinate of target position; -1 indicates the current position. The default value is 0 (top of page)

@param int :page

Number of target page; -1 indicates the current page. This is the default value

@since 1.5
@see

AddLink()



3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
# File 'lib/rbpdf.rb', line 3024

def SetLink(link, y=0, page=-1)
  #Set destination of internal link
  if (y==-1)
    y=@y;
  end
  if (page==-1)
    page=@page;
  end
  @links[link] = [page, y]
end

#SetMargins(left, top, right = -1,, keepmargins = false) ⇒ Object Also known as: set_margins

Defines the left, top and right margins.

@param float :left

Left margin.

@param float :top

Top margin.

@param float :right

Right margin. Default value is the left one.

@param boolean :keepmargins

if true overwrites the default page margins

@access public
@since 1.0
@see

SetLeftMargin(), SetTopMargin(), SetRightMargin(), SetAutoPageBreak()



1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
# File 'lib/rbpdf.rb', line 1278

def SetMargins(left, top, right=-1, keepmargins=false)
  #Set left, top and right margins
  @l_margin = left
  @t_margin = top
  if (right == -1)
    right = left
  end
  @r_margin = right
  if keepmargins
    # overwrite original values
    @original_l_margin = @l_margin
    @original_r_margin = @r_margin
  end
end

#setPage(pnum, resetmargins = false) ⇒ Object Also known as: set_page

Move pointer at the specified document page and update page dimensions.

@param int :pnum

page number (1 … numpages)

@param boolean :resetmargins

if true reset left, right, top margins and Y position.

@access public
@since 2.1.000 (2008-01-07)
@see

getPage(), lastPage(), getNumPages()



1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
# File 'lib/rbpdf.rb', line 1603

def setPage(pnum, resetmargins=false)
  if pnum == @page
    return
  end
  if (pnum > 0) and (pnum <= @numpages)
    @state = 2
    # save current graphic settings
    # gvars = getGraphicVars()
    oldpage = @page
    @page = pnum
    @w_pt = @pagedim[@page]['w']
    @h_pt = @pagedim[@page]['h']
    @w = @pagedim[@page]['wk']
    @h = @pagedim[@page]['hk']
    @t_margin = @pagedim[@page]['tm']
    @b_margin = @pagedim[@page]['bm']
    @original_l_margin = @pagedim[@page]['olm']
    @original_r_margin = @pagedim[@page]['orm']
    @auto_page_break = @pagedim[@page]['pb']
    @cur_orientation = @pagedim[@page]['or']
    SetAutoPageBreak(@auto_page_break, @b_margin)
    # restore graphic settings
    # setGraphicVars(gvars)
    if resetmargins
      @l_margin = @pagedim[@page]['olm']
      @r_margin = @pagedim[@page]['orm']
      SetY(@t_margin)
    else
      # account for booklet mode
      if @pagedim[@page]['olm'] != @pagedim[oldpage]['olm']
        deltam = @pagedim[@page]['olm'] - @pagedim[@page]['orm']
        @l_margin += deltam
        @r_margin -= deltam
      end
    end
  else
    Error('Wrong page number on setPage() function.')
  end
end

#setPageBoxes(page, type, llx, lly, urx, ury, points = false) ⇒ Object Also known as: set_page_boxes

Set page boundaries.

@param int :page

page number

@param string :type

valid values are:

  • ‘MediaBox’ : the boundaries of the physical medium on which the page shall be displayed or printed

  • ‘CropBox’ : the visible region of default user space

  • ‘BleedBox’ : the region to which the contents of the page shall be clipped when output in a production environment

  • ‘TrimBox’ : the intended dimensions of the finished page after trimming

  • ‘ArtBox’ : the page’s meaningful content (including potential white space).

@param float :llx

lower-left x coordinate in user units

@param float :lly

lower-left y coordinate in user units

@param float :urx

upper-right x coordinate in user units

@param float :ury

upper-right y coordinate in user units

@param boolean :points

if true uses user units as unit of measure, if false uses PDF points

@access public
@since 5.0.010 (2010-05-17)


858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
# File 'lib/rbpdf.rb', line 858

def setPageBoxes(page, type, llx, lly, urx, ury, points=false)
  pageboxes = ['MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox']
  unless pageboxes.include?(type)
    return
  end
  if @pagedim[page].nil?
    # initialize array
    @pagedim[page] = {}
  end

  points ? k = 1 : k = @k
  @pagedim[page][type] = {}
  @pagedim[page][type]['llx'] = llx * k
  @pagedim[page][type]['lly'] = lly * k
  @pagedim[page][type]['urx'] = urx * k
  @pagedim[page][type]['ury'] = ury * k
end

#setPageMarkObject Also known as: set_page_mark

Set start-writing mark on current page stream used to put borders and fills. Borders and fills are always created after content and inserted on the position marked by this method. This function must be called after calling Image() function for a background image. Background images must be always inserted before calling Multicell() or WriteHTMLCell() or WriteHTML() functions.

@access public
@since 4.0.016 (2008-07-30)


1832
1833
1834
1835
# File 'lib/rbpdf.rb', line 1832

def setPageMark()
  @intmrk[@page] = @pagelen[@page]
  setContentMark()
end

#setPageOrientation(orientation, autopagebreak = '', bottommargin = '') ⇒ Object Also known as: set_page_orientation

Set page orientation.

@param string :orientation

page orientation. Possible values are (case insensitive):

  • P or PORTRAIT (default)

  • L or LANDSCAPE

@param boolean :autopagebreak

Boolean indicating if auto-page-break mode should be on or off.

@param float :bottommargin

bottom margin of the page.

@access public
@since 3.0.015 (2008-06-06)


910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
# File 'lib/rbpdf.rb', line 910

def setPageOrientation(orientation, autopagebreak='', bottommargin='')
  if @pagedim[@page].nil? or @pagedim[@page]['MediaBox'].nil?
    # the boundaries of the physical medium on which the page shall be displayed or printed
    setPageBoxes(@page, 'MediaBox', 0, 0, @fw_pt, @fh_pt, true)
  end
  if @pagedim[@page]['CropBox'].nil?
    # the visible region of default user space
    setPageBoxes(@page, 'CropBox', @pagedim[@page]['MediaBox']['llx'], @pagedim[@page]['MediaBox']['lly'], @pagedim[@page]['MediaBox']['urx'], @pagedim[@page]['MediaBox']['ury'], true)
  end
  if @pagedim[@page]['BleedBox'].nil?
    # the region to which the contents of the page shall be clipped when output in a production environment
    setPageBoxes(@page, 'BleedBox', @pagedim[@page]['CropBox']['llx'], @pagedim[@page]['CropBox']['lly'], @pagedim[@page]['CropBox']['urx'], @pagedim[@page]['CropBox']['ury'], true)
  end
  if @pagedim[@page]['TrimBox'].nil?
    # the intended dimensions of the finished page after trimming
    setPageBoxes(@page, 'TrimBox', @pagedim[@page]['CropBox']['llx'], @pagedim[@page]['CropBox']['lly'], @pagedim[@page]['CropBox']['urx'], @pagedim[@page]['CropBox']['ury'], true)
  end
  if @pagedim[@page]['ArtBox'].nil?
    # the page's meaningful content (including potential white space)
    setPageBoxes(@page, 'ArtBox', @pagedim[@page]['CropBox']['llx'], @pagedim[@page]['CropBox']['lly'], @pagedim[@page]['CropBox']['urx'], @pagedim[@page]['CropBox']['ury'], true)
  end
  if @pagedim[@page]['Rotate'].nil?
    # The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90.
    @pagedim[@page]['Rotate'] = 0
  end
  if @pagedim[@page]['PZ'].nil?
    # The page's preferred zoom (magnification) factor
    @pagedim[@page]['PZ'] = 1
  end
  if @fw_pt > @fh_pt
    # landscape
    default_orientation = 'L'
  else
    # portrait
    default_orientation = 'P'
  end
  valid_orientations = ['P', 'L']
  if orientation.empty?
    orientation = default_orientation
  else
    orientation = orientation[0, 1].upcase
  end
  if valid_orientations.include?(orientation) and (orientation != default_orientation)
    @cur_orientation = orientation
    @w_pt = @fh_pt
    @h_pt = @fw_pt
  else
    @cur_orientation = default_orientation
    @w_pt = @fw_pt
    @h_pt = @fh_pt
  end
  if ((@pagedim[@page]['MediaBox']['urx'] - @h_pt).abs < @feps) and ((@pagedim[@page]['MediaBox']['ury'] - @w_pt).abs < @feps)
    # swap X and Y coordinates (change page orientatio
    swapPageBoxCoordinates(@page)
  end
  @w = @w_pt / @k
  @h = @h_pt / @k
  if empty_string(autopagebreak)
    unless @auto_page_break.nil?
      autopagebreak = @auto_page_break
    else
      autopagebreak = true
    end
  end
  if empty_string(bottommargin)
    unless @b_margin.nil?
      bottommargin = @b_margin
    else
      # default value = 2 cm
      bottommargin = 2 * 28.35 / @k
    end
  end
  SetAutoPageBreak(autopagebreak, bottommargin)
  # store page dimensions
  @pagedim[@page]['w'] = @w_pt
  @pagedim[@page]['h'] = @h_pt
  @pagedim[@page]['wk'] = @w
  @pagedim[@page]['hk'] = @h
  @pagedim[@page]['tm'] = @t_margin
  @pagedim[@page]['bm'] = bottommargin
  @pagedim[@page]['lm'] = @l_margin
  @pagedim[@page]['rm'] = @r_margin
  @pagedim[@page]['pb'] = autopagebreak
  @pagedim[@page]['or'] = @cur_orientation
  @pagedim[@page]['olm'] = @original_l_margin
  @pagedim[@page]['orm'] = @original_r_margin
  @pagedim[@page]
end

#setPageUnit(unit) ⇒ Object Also known as: set_page_unit

Set the units of measure for the document.

@param string :unit

User measure unit. Possible values are:

  • pt: point

  • mm: millimeter (default)

  • cm: centimeter

  • in: inch

A point equals 1/72 of inch, that is to say about 0.35 mm (an inch being 2.54 cm). This is a very common unit in typography; font sizes are expressed in that unit.

@access public
@since 3.0.015 (2008-06-06)


582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
# File 'lib/rbpdf.rb', line 582

def setPageUnit(unit)
  unit = unit.downcase
  # Set scale factor
  case unit
  when 'px', 'pt'; @k=1.0     # points
  when 'mm'; @k = @dpi / 25.4 # millimeters
  when 'cm'; @k = @dpi / 2.54 # centimeters
  when 'in'; @k = @dpi        # inches
  # unsupported unit
  else Error("Incorrect unit: #{unit}")
  end
  @pdfunit = unit
  unless @cur_orientation.nil?
    setPageOrientation(@cur_orientation)
  end
end

#setPDFVersion(version = '1.7') ⇒ Object Also known as: set_pdf_version

Set the PDF version (check PDF reference for valid values). Default value is 1.t

@access public
@since 3.1.000 (2008-06-09)


11673
11674
11675
# File 'lib/rbpdf.rb', line 11673

def setPDFVersion(version='1.7')
  @pdf_version = version
end

#setPrintFooter(val = true) ⇒ Object Also known as: set_print_footer

Set a flag to print page footer.

@param boolean :value

set to true to print the page footer (default), false otherwise.

@access public


1972
1973
1974
# File 'lib/rbpdf.rb', line 1972

def setPrintFooter(val=true)
  @print_footer = val;
end

#SetPrintFooter(val = true) ⇒ Object



1977
1978
1979
1980
# File 'lib/rbpdf.rb', line 1977

def SetPrintFooter(val=true)
  warn "[DEPRECATION] 'SetPrintFooter' is deprecated. Please use 'set_print_footer' instead."
  setPrintFooter(val)
end

#SetPrintHeader(val = true) ⇒ Object



1962
1963
1964
1965
# File 'lib/rbpdf.rb', line 1962

def SetPrintHeader(val=true)
  warn "[DEPRECATION] 'SetPrintHeader' is deprecated. Please use 'set_print_header' instead."
  setPrintHeader(val)
end

#setPrintHeader(val = true) ⇒ Object Also known as: set_print_header

Set a flag to print page header.

@param boolean :val

set to true to print the page header (default), false otherwise.

@access public


1957
1958
1959
# File 'lib/rbpdf.rb', line 1957

def setPrintHeader(val=true)
  @print_header = val;
end

#SetRightMargin(margin) ⇒ Object Also known as: set_right_margin

Defines the right margin. The method can be called before creating the first page.

@param float :margin

The margin.

@access public
@since 1.5
@see

SetLeftMargin(), SetTopMargin(), SetAutoPageBreak(), SetMargins()



1333
1334
1335
1336
1337
1338
# File 'lib/rbpdf.rb', line 1333

def SetRightMargin(margin)
  @r_margin = margin
  if (@page > 0) and (@x > (@w - margin))
    @x = @w - margin
  end
end

#setRTL(enable, resetx = true) ⇒ Object Also known as: set_rtl

Enable or disable Right-To-Left language mode

@param Boolean :enable

if true enable Right-To-Left language mode.

@param Boolean :resetx

if true reset the X position on direction change.

@access public
@since 2.0.000 (2008-01-03)


1007
1008
1009
1010
1011
1012
1013
# File 'lib/rbpdf.rb', line 1007

def setRTL(enable, resetx=true)
  enable = enable ? true : false
  resetx = resetx and (enable != @rtl)
  @rtl = enable
  @tmprtl = false
  Ln(0) if resetx
end

#SetSubject(subject) ⇒ Object Also known as: set_subject

Defines the subject of the document.

@param string :subject

The subject.

@access public
@since 1.2
@see

SetAuthor(), SetCreator(), SetKeywords(), SetTitle()



1477
1478
1479
1480
# File 'lib/rbpdf.rb', line 1477

def SetSubject(subject)
  #Subject of document
  @subject = subject
end

#setTempRTL(mode) ⇒ Object Also known as: set_temp_rtl

Force temporary RTL language direction

@param mixed :mode

can be false, ‘L’ for LTR or ‘R’ for RTL

@access public
@since 2.1.000 (2008-01-09)


1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
# File 'lib/rbpdf.rb', line 1033

def setTempRTL(mode)
  newmode = false
  case mode
  when 'ltr', 'LTR', 'L'
    newmode = 'L' if @rtl
  when 'rtl', 'RTL', 'R'
    newmode = 'R' if !@rtl
  end
  @tmprtl = newmode
end

#SetTextColor(col1 = 0, col2 = -1,, col3 = -1,, col4 = -1)) ⇒ Object Also known as: set_text_color

Defines the color used for text. It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.

@param int :col1

Gray level for single color, or Red color for RGB, or Cyan color for CMYK. Value between 0 and 255

@param int :col2

Green color for RGB, or Magenta color for CMYK. Value between 0 and 255

@param int :col3

Blue color for RGB, or Yellow color for CMYK. Value between 0 and 255

@param int :col4

Key (Black) color for CMYK. Value between 0 and 255

@access public
@since 1.3
@see

SetDrawColor(), SetFillColor(), Text(), Cell(), MultiCell()



2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
# File 'lib/rbpdf.rb', line 2447

def SetTextColor(col1=0, col2=-1, col3=-1, col4=-1)
  # set default values
  unless col1.is_a?(Numeric)
    col1 = 0
  end
  unless col2.is_a?(Numeric)
    col2 = -1
  end
  unless col3.is_a?(Numeric)
    col3 = -1
  end
  unless col4.is_a?(Numeric)
    col4 = -1
  end

  # Set color for text
  if (col2 == -1) and (col3 == -1) and (col4 == -1)
    # Grey scale
    @text_color = sprintf('%.3f g', col1 / 255.0)
    @fgcolor['G'] = col1
  elsif col4 == -1
    # RGB
    @text_color = sprintf('%.3f %.3f %.3f rg', col1 / 255.0, col2 / 255.0, col3 / 255.0)
    @fgcolor['R'] = col1
    @fgcolor['G'] = col2
    @fgcolor['B'] = col3
  else
    # CMYK
    @text_color = sprintf('%.3f %.3f %.3f %.3f k', col1 / 100.0, col2 / 100.0, col3 / 100.0, col4 / 100.0)
    @fgcolor['C'] = col1
    @fgcolor['M'] = col2
    @fgcolor['Y'] = col3
    @fgcolor['K'] = col4
  end
  @color_flag = (@fill_color != @text_color)
end

#SetTextColorArray(color) ⇒ Object Also known as: set_text_color_array

Defines the color used for text. It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.

@param array or ordered hash :color

array(or ordered hash) of colors

@access public
@since 3.1.000 (2008-6-11)
@see

SetFillColor()



2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
# File 'lib/rbpdf.rb', line 2423

def SetTextColorArray(color)
  unless color.nil?
    color = color.values if color.is_a? Hash
    r = !color[0].nil? ? color[0] : -1
    g = !color[1].nil? ? color[1] : -1
    b = !color[2].nil? ? color[2] : -1
    k = !color[3].nil? ? color[3] : -1
    if r >= 0
      SetTextColor(r, g, b, k)
    end
  end
end

#setTextRenderingMode(stroke = 0, fill = true, clip = false) ⇒ Object Also known as: set_text_rendering_mode

Set Text rendering mode.

@param int :stroke

outline size in user units (0 = disable).

@param boolean :fill

if true fills the text (default).

@param boolean :clip

if true activate clipping mode

@access public
@since 4.9.008 (2009-04-02)


16424
16425
16426
16427
16428
16429
16430
16431
16432
16433
16434
16435
16436
16437
16438
16439
16440
16441
16442
16443
16444
16445
16446
16447
16448
16449
16450
16451
16452
16453
16454
16455
16456
16457
16458
16459
16460
16461
16462
16463
16464
16465
16466
16467
16468
16469
16470
16471
# File 'lib/rbpdf.rb', line 16424

def setTextRenderingMode(stroke=0, fill=true, clip=false)
  # Ref.: PDF 32000-1:2008 - 9.3.6 Text Rendering Mode
  # convert text rendering parameters
  if stroke < 0
    stroke = 0
  end
  if fill == true
    if stroke > 0
      if clip == true
        # Fill, then stroke text and add to path for clipping
        textrendermode = 6
      else
        # Fill, then stroke text
        textrendermode = 2
      end
      textstrokewidth = stroke
    else
      if clip == true
        # Fill text and add to path for clipping
        textrendermode = 4
      else
        # Fill text
        textrendermode = 0
      end
    end
  else
    if stroke > 0
      if clip == true
        # Stroke text and add to path for clipping
        textrendermode = 5
      else
        # Stroke text
        textrendermode = 1
      end
      textstrokewidth = stroke
    else
      if clip == true
        # Add text to path for clipping
        textrendermode = 7
      else
        # Neither fill nor stroke text (invisible)
        textrendermode = 3
      end
    end
  end
  @textrendermode = textrendermode
  @textstrokewidth = stroke * @k
end

#SetTitle(title) ⇒ Object Also known as: set_title

Defines the title of the document.

@param string :title

The title.

[@access public$

@since 1.2
@see

SetAuthor(), SetCreator(), SetKeywords(), SetSubject()



1464
1465
1466
1467
# File 'lib/rbpdf.rb', line 1464

def SetTitle(title)
  #Title of document
  @title = title
end

#SetTopMargin(margin) ⇒ Object Also known as: set_top_margin

Defines the top margin. The method can be called before creating the first page.

@param float :margin

The margin.

@access public
@since 1.5
@see

SetLeftMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins()



1317
1318
1319
1320
1321
1322
1323
# File 'lib/rbpdf.rb', line 1317

def SetTopMargin(margin)
  #Set top margin
  @t_margin = margin
  if (@page > 0) and (@y < margin)
    @y = margin
  end
end

#setViewerPreferences(preferences) ⇒ Object Also known as: set_viewer_preferences

Set the viewer preferences dictionary controlling the way the document is to be presented on the screen or in print. (see Section 8.1 of PDF reference, “Viewer Preferences”).

  • HideToolbar boolean (Optional) A flag specifying whether to hide the viewer application’s tool bars when the document is active. Default value: false.

  • HideMenubar boolean (Optional) A flag specifying whether to hide the viewer application’s menu bar when the document is active. Default value: false.

  • HideWindowUI boolean (Optional) A flag specifying whether to hide user interface elements in the document’s window (such as scroll bars and navigation controls), leaving only the document’s contents displayed. Default value: false.

  • FitWindow boolean (Optional) A flag specifying whether to resize the document’s window to fit the size of the first displayed page. Default value: false.

  • CenterWindow boolean (Optional) A flag specifying whether to position the document’s window in the center of the screen. Default value: false.

  • DisplayDocTitle boolean (Optional; PDF 1.4) A flag specifying whether the window’s title bar should display the document title taken from the Title entry of the document information dictionary (see Section 10.2.1, “Document Information Dictionary”). If false, the title bar should instead display the name of the PDF file containing the document. Default value: false.

  • NonFullScreenPageMode name (Optional) The document’s page mode, specifying how to display the document on exiting full-screen mode:

    • UseNone Neither document outline nor thumbnail images visible

    • UseOutlines Document outline visible

    • UseThumbs Thumbnail images visible

    • UseOC Optional content group panel visible

    This entry is meaningful only if the value of the PageMode entry in the catalog dictionary (see Section 3.6.1, “Document Catalog”) is FullScreen; it is ignored otherwise. Default value: UseNone.

  • ViewArea name (Optional; PDF 1.4) The name of the page boundary representing the area of a page to be displayed when viewing the document on the screen. Valid values are (see Section 10.10.1, “Page Boundaries”).:

    • MediaBox

    • CropBox (default)

    • BleedBox

    • TrimBox

    • ArtBox

  • ViewClip name (Optional; PDF 1.4) The name of the page boundary to which the contents of a page are to be clipped when viewing the document on the screen. Valid values are (see Section 10.10.1, “Page Boundaries”).:

    • MediaBox

    • CropBox (default)

    • BleedBox

    • TrimBox

    • ArtBox

  • PrintArea name (Optional; PDF 1.4) The name of the page boundary representing the area of a page to be rendered when printing the document. Valid values are (see Section 10.10.1, “Page Boundaries”).:

    • MediaBox

    • CropBox (default)

    • BleedBox

    • TrimBox

    • ArtBox

  • PrintClip name (Optional; PDF 1.4) The name of the page boundary to which the contents of a page are to be clipped when printing the document. Valid values are (see Section 10.10.1, “Page Boundaries”).:

    • MediaBox

    • CropBox (default)

    • BleedBox

    • TrimBox

    • ArtBox

  • PrintScaling name (Optional; PDF 1.6) The page scaling option to be selected when a print dialog is displayed for this document. Valid values are:

    • None, which indicates that the print dialog should reflect no page scaling

    • AppDefault (default), which indicates that applications should use the current print scaling

  • Duplex name (Optional; PDF 1.7) The paper handling option to use when printing the file from the print dialog. The following values are valid:

    • Simplex - Print single-sided

    • DuplexFlipShortEdge - Duplex and flip on the short edge of the sheet

    • DuplexFlipLongEdge - Duplex and flip on the long edge of the sheet

    Default value: none

  • PickTrayByPDFSize boolean (Optional; PDF 1.7) A flag specifying whether the PDF page size is used to select the input paper tray. This setting influences only the preset values used to populate the print dialog presented by a PDF viewer application. If PickTrayByPDFSize is true, the check box in the print dialog associated with input paper tray is checked. Note: This setting has no effect on Mac OS systems, which do not provide the ability to pick the input tray by size.

  • PrintPageRange array (Optional; PDF 1.7) The page numbers used to initialize the print dialog box when the file is printed. The first page of the PDF file is denoted by 1. Each pair consists of the first and last pages in the sub-range. An odd number of integers causes this entry to be ignored. Negative numbers cause the entire array to be ignored. Default value: as defined by PDF viewer application

  • NumCopies integer (Optional; PDF 1.7) The number of copies to be printed when the print dialog is opened for this file. Supported values are the integers 2 through 5. Values outside this range are ignored. Default value: as defined by PDF viewer application, but typically 1

@param array :preferences

array of options.

@author

Nicola Asuni

@access public
@since 3.1.000 (2008-06-09)


11733
11734
11735
# File 'lib/rbpdf.rb', line 11733

def setViewerPreferences(preferences)
  @viewer_preferences = preferences
end

#setVisibility(v) ⇒ Object Also known as: set_visibility

Set the visibility of the successive elements. This can be useful, for instance, to put a background image or color that will show on screen but won’t print.

@param string :v

visibility mode. Legal values are: all, print, screen.

@access public
@since 3.0.000 (2008-03-27)


11537
11538
11539
11540
11541
11542
11543
11544
11545
11546
11547
11548
11549
11550
11551
11552
11553
11554
11555
11556
# File 'lib/rbpdf.rb', line 11537

def setVisibility(v)
  if @open_marked_content
    # close existing open marked-content
    out('EMC')
    @open_marked_content = false
  end
  case v
  when 'print'
    out('/OC /OC1 BDC')
    @open_marked_content = true
  when 'screen'
    out('/OC /OC2 BDC')
    @open_marked_content = true
  when 'all'
    out('')
  else
    Error('Incorrect visibility: ' + v)
  end
  @visibility = v
end

#SetX(x, rtloff = false) ⇒ Object Also known as: set_x

Defines the abscissa of the current position. If the passed value is negative, it is relative to the right of the page (or left if language is RTL).

@param float :x

The value of the abscissa.

@param boolean :rtloff

if true always uses the page top-left corner as origin of axis.

@access public
@since 1.2
@see

GetX(), GetY(), SetY(), SetXY()



5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
# File 'lib/rbpdf.rb', line 5496

def SetX(x, rtloff=false)
  #Set x position
  if !rtloff and @rtl
    if x >= 0
      @x = @w - x
    else
      @x = x.abs
    end
  else
    if x >= 0
      @x = x
    else
      @x = @w + x
    end
  end
end

#SetXY(x, y, rtloff = false) ⇒ Object Also known as: set_xy

Defines the abscissa and ordinate of the current position. If the passed values are negative, they are relative respectively to the right and bottom of the page.

@param float :x

The value of the abscissa.

@param float :y

The value of the ordinate.

@param boolean :rtloff

if true always uses the page top-left corner as origin of axis.

@access public
@since 1.2
@see

SetX(), SetY()



5557
5558
5559
5560
# File 'lib/rbpdf.rb', line 5557

def SetXY(x, y, rtloff=false)
  SetY(y, false, rtloff)
  SetX(x, rtloff)
end

#SetY(y, resetx = true, rtloff = false) ⇒ Object Also known as: set_y

Moves the current abscissa back to the left margin and sets the ordinate. If the passed value is negative, it is relative to the bottom of the page.

@param float :y

The value of the ordinate.

@param bool :resetx

if true (default) reset the X position.

@param boolean :rtloff

if true always uses the page top-left corner as origin of axis.

@access public
@since 1.0
@see

GetX(), GetY(), SetY(), SetXY()



5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
# File 'lib/rbpdf.rb', line 5524

def SetY(y, resetx=true, rtloff=false)
  if resetx
    # reset x
    if !rtloff and @rtl
      @x = @w - @r_margin
    else
      @x = @l_margin
    end
  end
  if (y>=0)
    @y = y;
  else
    @y=@h+y;
  end

  if @y < 0
    @y = 0
  end
  if @y > @h
    @y = @h
  end
end

#StarPolygon(x0, y0, r, nv, ng, angle = 0, draw_circle = false, style = '', line_style = nil, fill_color = nil, circle_style = '', circle_outLine_style = nil, circle_fill_color = nil) ⇒ Object Also known as: star_polygon

Draws a star polygon

@param float :x0

Abscissa of center point.

@param float :y0

Ordinate of center point.

@param float :r

Radius of inscribed circle.

@param integer :nv

Number of vertices.

@param integer :ng

Number of gap (if (:ng % :nv = 1) then is a regular polygon).

@param float :angle

Angle oriented (anti-clockwise). Default value: 0.

@param boolean :draw_circle

Draw inscribed circle or not. Default value is false.

@param string :style

Style of rendering. See the getPathPaintOperator() function for more information.

@param array :line_style

Line style of polygon sides. Array with keys among the following:

  • all: Line style of all sides. Array like for SetLineStyle SetLineStyle.

  • 0 to (n - 1): Line style of each side. Array like for SetLineStyle SetLineStyle.

If a key is not present or is null, not draws the side. Default value is default line style (empty array). [@param array :fill_color ]Fill color. Format: array(red, green, blue). Default value: default color (empty array).

@param string :circle_style

Style of rendering of inscribed circle (if draws). Possible values are:

  • D or empty string: Draw (default).

  • F: Fill.

  • DF or FD: Draw and fill.

  • CNZ: Clipping mode (using the even-odd rule to determine which regions lie inside the clipping path).

  • CEO: Clipping mode (using the nonzero winding number rule to determine which regions lie inside the clipping path).

@param array :circle_outLine_style

Line style of inscribed circle (if draws). Array like for SetLineStyle SetLineStyle. Default value: default line style (empty array).

@param array :circle_fill_color

Fill color of inscribed circle (if draws). Format: array(red, green, blue). Default value: default color (empty array).

@access public
@since 2.1.000 (2008-01-08)


9516
9517
9518
9519
9520
9521
9522
9523
9524
9525
9526
9527
9528
9529
9530
9531
9532
9533
9534
9535
9536
9537
9538
9539
9540
9541
9542
9543
9544
# File 'lib/rbpdf.rb', line 9516

def StarPolygon(x0, y0, r, nv, ng, angle=0, draw_circle=false, style='', line_style=nil, fill_color=nil, circle_style='', circle_outLine_style=nil, circle_fill_color=nil)
  draw_circle = false if draw_circle == 0
  if nv < 2
    nv = 2
  end
  if draw_circle
    Circle(x0, y0, r, 0, 360, circle_style, circle_outLine_style, circle_fill_color)
  end
  p2 = []
  visited = []
  0.upto(nv - 1) do |i|
    a = angle + i * 360 / nv
    a_rad = a * ::Math::PI / 180 # deg2rad
    p2.push x0 + r * ::Math.sin(a_rad)
    p2.push y0 + r * ::Math.cos(a_rad)
    visited.push false
  end
  p = []
  i = 0
  while true
    p.push p2[i * 2]
    p.push p2[i * 2 + 1]
    visited[i] = true
    i += ng
    i %= nv
    break if visited[i]
  end
  Polygon(p, style, line_style, fill_color)
end

#startPage(orientation = '', format = '', tocpage = false) ⇒ Object Also known as: start_page

Starts a new page to the document. The page must be closed using the endPage() function. The origin of the coordinate system is at the top-left corner and increasing ordinates go downwards.

@param string :orientation

page orientation. Possible values are (case insensitive):

  • P or PORTRAIT (default)

  • L or LANDSCAPE

@param mixed :format

The format used for pages. It can be either: A string indicating the page format:

  • 4A0,2A0,A0,A1,A2,A3,A4 (default),A5,A6,A7,A8,A9,A10

  • B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10

  • C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10

  • RA0,RA1,RA2,RA3,RA4

  • SRA0,SRA1,SRA2,SRA3,SRA4

  • LETTER,LEGAL,EXECUTIVE,FOLIO

An array containing page measures and advanced options: see setPageFormat()

@param boolean :tocpage

if true set the tocpage state to true (the added page will be used to display Table of Content).

@access public
@since 4.2.010 (2008-11-14)
@see

AddPage(), endPage(), addTOCPage(), endTOCPage()



1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
# File 'lib/rbpdf.rb', line 1787

def startPage(orientation='', format='', tocpage=false)
  if tocpage
    @tocpage = true
  end
  if @numpages > @page
    # this page has been already added
    setPage(@page + 1)
    SetY(@t_margin)
    return
  end
  # start a new page
  if @state == 0
    Open()
  end
  @numpages += 1
  swapMargins(@booklet)
  # save current graphic settings
  gvars = getGraphicVars()
  # start new page
  beginpage(orientation, format)
  # mark page as open
  @pageopen[@page] = true
  # restore graphic settings
  setGraphicVars(gvars)
  # mark this point
  setPageMark()
  # print page header
  setHeader()
  # restore graphic settings
  setGraphicVars(gvars)
  # mark this point
  setPageMark()
  # print table header (if any)
  setTableHeader()
end

#startPageGroup(page = 0) ⇒ Object Also known as: start_page_group

Create a new page group.

  • NOTE: call this function before calling AddPage()

@param int :page

starting group page (leave empty for next page).

@access public
@since 3.0.000 (2008-03-27)


11357
11358
11359
11360
11361
11362
# File 'lib/rbpdf.rb', line 11357

def startPageGroup(page=0)
  if !page.is_a? Integer or page.zero?
    page = @page + 1
  end
  @newpagegroup[page] = true
end

#startTransactionObject Also known as: start_transaction

Stores a copy of the current RBPDF object used for undo operation.

@access public
@since 4.5.029 (2009-03-19)


16298
16299
16300
16301
16302
16303
16304
16305
16306
16307
16308
# File 'lib/rbpdf.rb', line 16298

def startTransaction()
  if @objcopy
    # remove previous copy
    commitTransaction()
  end
  # record current page number and Y position
  @start_transaction_page = @page
  @start_transaction_y = @y
  # clone current object
  @objcopy = objclone(self)
end

#StartTransformObject Also known as: start_transform

Starts a 2D tranformation saving current graphic state. This function must be called before scaling, mirroring, translation, rotation and skewing. Use StartTransform() before, and StopTransform() after the transformations to restore the normal behavior.

@access public
@since 2.1.000 (2008-01-07)
@see

StartTransform(), StopTransform()



8799
8800
8801
8802
8803
8804
# File 'lib/rbpdf.rb', line 8799

def StartTransform
  out('q');
  @transfmrk[@page] = @pagelen[@page]
  @transfmatrix_key += 1
  @transfmatrix[@transfmatrix_key] = []
end

#StopTransformObject Also known as: stop_transform

Stops a 2D tranformation restoring previous graphic state. This function must be called after scaling, mirroring, translation, rotation and skewing. Use StartTransform() before, and StopTransform() after the transformations to restore the normal behavior.

@access public
@since 2.1.000 (2008-01-07)
@see

StartTransform(), StopTransform()



8815
8816
8817
8818
8819
8820
8821
8822
# File 'lib/rbpdf.rb', line 8815

def StopTransform
  out('Q');
  if @transfmatrix[@transfmatrix_key]
    @transfmatrix[@transfmatrix_key].pop
    @transfmatrix_key -= 1
  end
  @transfmrk[@page] = nil
end

#Text(x, y, txt, fstroke = false, fclip = false, ffill = true, border = 0, ln = 0, align = '', fill = 0, link = '', stretch = 0, ignore_min_height = false, calign = 'T', valign = 'M', rtloff = false) ⇒ Object Also known as: text

Prints a text cell at the specified position. The origin is on the left of the first charcter, on the baseline. This method allows to place a string precisely on the page.

@param float :x

Abscissa of the cell origin

@param float :y

Ordinate of the cell origin

@param string :txt

String to print

@param int :fstroke

outline size in user units (false = disable)

@param boolean :fclip

if true activate clipping mode (you must call StartTransform() before this function and StopTransform() to stop the clipping tranformation).

@param boolean :ffill

if true fills the text

@param mixed :border

Indicates if borders must be drawn around the cell. The value can be either a number:

  • 0: no border (default)

  • 1: frame

or a string containing some or all of the following characters (in any order):

  • L: left

  • T: top

  • R: right

  • B: bottom

@param int :ln

Indicates where the current position should go after the call. Possible values are:

  • 0: to the right (or left for RTL languages)

  • 1: to the beginning of the next line

  • 2: below

Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.

@param string :align

Allows to center or align the text. Possible values are:

  • L or empty string: left align (default value)

  • C: center

  • R: right align

  • J: justify

@param int :fill

Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.

@param mixed :link

URL or identifier returned by AddLink().

@param int :stretch

stretch carachter mode:

  • 0 = disabled

  • 1 = horizontal scaling only if necessary

  • 2 = forced horizontal scaling

  • 3 = character spacing only if necessary

  • 4 = forced character spacing

@param boolean :ignore_min_height

if true ignore automatic minimum height value.

@param string :calign

cell vertical alignment relative to the specified Y value. Possible values are:

  • T : cell top

  • A : font top

  • L : font baseline

  • D : font bottom

  • B : cell bottom

@param string :valign

text vertical alignment inside the cell. Possible values are:

  • T : top

  • C : center

  • B : bottom

@param boolean :rtloff

if true uses the page top-left corner as origin of axis for :x and :y initial position.

@access public
@since 1.0
@see

SetFont(), SetTextColor(), Cell(), MultiCell(), Write()



3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
# File 'lib/rbpdf.rb', line 3223

def Text(x, y, txt, fstroke=false, fclip=false, ffill=true, border=0, ln=0, align='', fill=0, link='', stretch=0, ignore_min_height=false, calign='T', valign='M', rtloff=false)
  fstroke = 0 if fstroke == false

  textrendermode = @textrendermode
  textstrokewidth = @textstrokewidth
  setTextRenderingMode(fstroke, ffill, fclip)
  SetXY(x, y, rtloff)
  Cell(0, 0, txt, border, ln, align, fill, link, stretch, ignore_min_height, calign, valign)
  # restore previous rendering mode
  @textrendermode = textrendermode
  @textstrokewidth = textstrokewidth
end

#TextField(name, w, h, prop = {}, opt = {}, x = '', y = '', js = false) ⇒ Object Also known as: text_field

Creates a text field

@param string :name

field name

@param float :w

Width of the rectangle

@param float :h

Height of the rectangle

@param array :prop

javascript field properties. Possible values are described on official Javascript for Acrobat API reference.

@param array :opt

annotation parameters. Possible values are described on official PDF32000_2008 reference.

@param float :x

Abscissa of the upper-left corner of the rectangle

@param float :y

Ordinate of the upper-left corner of the rectangle

@param boolean :js

if true put the field using JavaScript (requires Acrobat Writer to be rendered).

@access public
@author Nicola Asuni
@since 4.8.000 (2009-09-07)


10800
10801
10802
10803
10804
10805
10806
10807
10808
10809
10810
10811
10812
10813
10814
10815
10816
10817
10818
10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
10835
10836
10837
10838
10839
10840
10841
10842
10843
10844
10845
10846
10847
10848
10849
10850
10851
10852
10853
10854
10855
10856
10857
10858
10859
10860
10861
10862
10863
10864
10865
10866
10867
10868
10869
10870
10871
10872
10873
10874
10875
10876
10877
10878
10879
10880
10881
10882
10883
10884
10885
10886
10887
10888
10889
10890
10891
# File 'lib/rbpdf.rb', line 10800

def TextField(name, w, h, prop = {}, opt = {}, x = '', y = '', js = false)
  x = @x if x == ''
  y = @y if y == ''

  if js
    addfield('text', name, x, y, w, h, prop)
    return
  end
  # get default style
  prop = getFormDefaultProp.merge prop
  # get annotation data
  popt = getAnnotOptFromJSProp(prop)
  # set default appearance stream
  font = @font_family
  fontkey = @fontkeys.index font
  unless @annotation_fonts.include? fontkey
    @annotation_fonts[font] = fontkey
  end
  fontstyle = sprintf("/F%d %.2f Tf %s", fontkey + 1, @font_size_pt, @text_color)
  popt['da'] = fontstyle
  popt['ap'] = {}

  if opt['v'] && !empty_string(opt['v'])
    # set Appearances
    popt['ap']['n'] = "/Tx BMC q #{fontstyle} "
    gvars = getGraphicVars()
    @h = h
    @w = w
    @t_margin = 0
    @c_margin = 0.2

    @tmp_buffer = ''
    multi_cell(w, h, opt['v'], 0, '', 0, 0, 0.2, 0, true, 0, false, true, 0)
    popt['ap']['n'] << @tmp_buffer
    @tmp_buffer = nil
    popt['ap']['n'] << 'Q EMC'

    # restore previous values
    setGraphicVars(gvars, true)
  else
    popt['ap']['n'] = "q BT #{fontstyle} ET Q"
  end

  # merge options
  opt = popt.merge opt
  # remove some conflicting options
  opt.delete :bs
  # set remaining annotation data
  opt['Subtype'] = 'Widget'
  opt['ft'] = 'Tx'
  opt['t'] = name
  #
  # Additional annotation's parameters (check _putannotsobj() method):
  # opt['f']
  # opt['ap']
  # opt['as']
  # opt['bs']
  # opt['be']
  # opt['c']
  # opt['border']
  # opt['h']
  # opt['mk']
  # opt['mk']['r']
  # opt['mk']['bc']
  # opt['mk']['bg']
  # opt['mk']['ca']
  # opt['mk']['rc']
  # opt['mk']['ac']
  # opt['mk']['i']
  # opt['mk']['ri']
  # opt['mk']['ix']
  # opt['mk']['if']
  # opt['mk']['if']['sw']
  # opt['mk']['if']['s']
  # opt['mk']['if']['a']
  # opt['mk']['if']['fb']
  # opt['mk']['tp']
  # opt['tu']
  # opt['tm']
  # opt['ff']
  # opt['v']
  # opt['dv']
  # opt['a']
  # opt['aa']
  # opt['q']
  Annotation(x, y, w, h, name, opt, 0)
  if @rtl
    @x -= w
  else
    @x += w
  end
end

#unhtmlentities(string) ⇒ Object

Reverse function for htmlentities. Convert entities in UTF-8.

@param :text_to_convert

Text to convert.

@return string

converted

@access public


8754
8755
8756
8757
8758
8759
8760
# File 'lib/rbpdf.rb', line 8754

def unhtmlentities(string)
  if @@decoder.nil?
    CGI.unescapeHTML(string)
  else
    @@decoder.decode(string)
  end
end

#UniArrSubString(uniarr, start = 0, last = uniarr.length) ⇒ Object Also known as: uni_arr_sub_string

Extract a slice of the :uniarr array and return it as string.

@param string :uniarr

The input array of characters. (UTF-8)

@param int :start

the starting element of :strarr.

[@param int :las]t first element that will not be returned.

@return

Return part of a string (UTF-8)

@access public
@since 4.5.037 (2009-04-07)


4713
4714
4715
4716
4717
4718
4719
# File 'lib/rbpdf.rb', line 4713

def UniArrSubString(uniarr, start=0, last=uniarr.length)
  string = ''
  start.upto(last - 1) do |i|
    string << uniarr[i]
  end
  return string
end

#unichr(c) ⇒ Object

Returns the unicode caracter specified by UTF-8 value

@param int :c

UTF-8 value (UCS4)

@return

Returns the specified character. (UTF-8)

@author

Miguel Perez, Nicola Asuni

@access public
@since 2.3.000 (2008-03-05)


4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
# File 'lib/rbpdf.rb', line 4746

def unichr(c)
  if !@is_unicode
    return c.chr
  elsif c <= 0x7F
    # one byte
    return c.chr
  elsif c <= 0x7FF
    # two bytes
    return (0xC0 | c >> 6).chr + (0x80 | c & 0x3F).chr
  elsif c <= 0xFFFF
    # three bytes
    return (0xE0 | c >> 12).chr + (0x80 | c >> 6 & 0x3F).chr + (0x80 | c & 0x3F).chr
  elsif c <= 0x10FFFF
    # four bytes
    return (0xF0 | c >> 18).chr + (0x80 | c >> 12 & 0x3F).chr + (0x80 | c >> 6 & 0x3F).chr + (0x80 | c & 0x3F).chr
  else
    return ""
  end
end

#UTF8ArrayToUniArray(ta) ⇒ Object Also known as: utf8_array_to_uni_array

Convert an array of UTF8 values to array of unicode characters

@param string :ta

The input array of UTF8 values. (UCS4)

@return

Return array of unicode characters (UTF-8)

@access public
@since 4.5.037 (2009-04-07)


4729
4730
4731
4732
4733
4734
4735
# File 'lib/rbpdf.rb', line 4729

def UTF8ArrayToUniArray(ta)
  string = []
  ta.each do |i|
    string << unichr(i)
  end
  return string
end

#UTF8ArrSubString(strarr, start = 0, last = strarr.size) ⇒ Object Also known as: utf8_arr_sub_string

Extract a slice of the :strarr array and return it as string.

@param string :strarr

The input array of characters. (UCS4)

@param int :start

the starting element of :strarr.

@param int :last

first element that will not be returned.

@return

Return part of a string (UTF-8)

@access public


4695
4696
4697
4698
4699
4700
4701
# File 'lib/rbpdf.rb', line 4695

def UTF8ArrSubString(strarr, start=0, last=strarr.size)
  string = ""
  start.upto(last - 1) do |i|
    string << unichr(strarr[i])
  end
  return string
end

#Write(h, txt, link = nil, fill = 0, align = '', ln = false, stretch = 0, firstline = false, firstblock = false, maxh = 0) ⇒ Object Also known as: write

This method prints text from the current position.

@param float :h

Line height

@param string :txt

String to print

@param mixed :link

URL or identifier returned by AddLink()

@param int :fill

Indicates if the background must be painted (1) or transparent (0). Default value: 0.

@param string :align

Allows to center or align the text. Possible values are:

  • L or empty string: left align (default value)

  • C: center

  • R: right align

  • J: justify

@param boolean :ln

if true set cursor at the bottom of the line, otherwise set cursor at the top of the line.

@param int :stretch

stretch carachter mode:

  • 0 = disabled

  • 1 = horizontal scaling only if necessary

  • 2 = forced horizontal scaling

  • 3 = character spacing only if necessary

  • 4 = forced character spacing

@param boolean :firstline

if true prints only the first line and return the remaining string.

@param boolean :firstblock

if true the string is the starting of a line.

@param float :maxh

maximum height. The remaining unprinted text will be returned. It should be >= :h and less then remaining space to the bottom of the page, or 0 for disable this feature.

@return mixed

Return the number of cells or the remaining string if :firstline = true.

@access public
@since 1.5


4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
# File 'lib/rbpdf.rb', line 4333

def Write(h, txt, link=nil, fill=0, align='', ln=false, stretch=0, firstline=false, firstblock=false, maxh=0)
  txt = txt.dup
  txt.force_encoding('ASCII-8BIT') if txt.respond_to?(:force_encoding)
  if txt.length == 0
    txt = ' '
  end

  # remove carriage returns
  s = txt.gsub("\r", '');

  # check if string contains arabic text
  if s =~ @@k_re_pattern_arabic
    arabic = true
  else
    arabic = false
  end

  # check if string contains RTL text
  if arabic or isRTLTextDir or (txt =~ @@k_re_pattern_rtl)
    rtlmode = true
  else
    rtlmode = false
  end

  # get a char width
  chrwidth = GetCharWidth('.')
  # get array of unicode values
  chars = UTF8StringToArray(s)
  # get array of chars
  uchars = UTF8ArrayToUniArray(chars)

  # get the number of characters
  nb = chars.size

  # replacement for SHY character (minus symbol)
  shy_replacement = 45
  shy_replacement_char = unichr(shy_replacement)
  # widht for SHY replacement
  shy_replacement_width = GetCharWidth(shy_replacement)

  # store current position
  prevx = @x
  prevy = @y

  # max Y
  maxy = @y + maxh - h - (2 * @c_margin)

  # calculating remaining line width (w)
  if @rtl
    w = @x - @l_margin
  else
    w = @w - @r_margin - @x
  end

  # max column width
  wmax = w - (2 * @c_margin)
  if !firstline and (chrwidth > wmax or (GetCharWidth(chars[0]) > wmax))
    # a single character do not fit on column
    return ''
  end

  i = 0    # character position
  j = 0    # current starting position
  sep = -1 # position of the last blank space
  shy = false # true if the last blank is a soft hypen (SHY)
  l = 0    # current string length
  nl = 0   # number of lines
  linebreak = false

  pc = 0 # previous character
  # for each character
  while(i<nb)
    if (maxh > 0) and (@y >= maxy)
      break
    end
    # Get the current character
    c = chars[i]
    if (c == 10) # 10 = "\n" = new line
      #Explicit line break
      if align == 'J'
        if @rtl
          talign = 'R'
        else
          talign = 'L'
        end
      else
        talign = align
      end
      tmpstr = UniArrSubString(uchars, j, i)
      if firstline
        startx = @x
        tmparr = chars[j, i - j]
        if rtlmode
          tmparr = utf8Bidi(tmparr, tmpstr, rtl_text_dir)
        end
        linew = GetArrStringWidth(tmparr)
        tmparr = ''
        if @rtl
          @endlinex = startx - linew
        else
          @endlinex = startx + linew
        end
        w = linew
        tmpcmargin = @c_margin
        if maxh == 0
          @c_margin = 0
        end
      end
      if firstblock and isRTLTextDir()
        tmpstr = tmpstr.rstrip
      end
      Cell(w, h, tmpstr, 0, 1, talign, fill, link, stretch)
      tmpstr = ''
      if firstline
        @c_margin = tmpcmargin
        return UniArrSubString(uchars, i)
      end
      nl += 1
      j = i + 1
      l = 0
      sep = -1
      shy = false;
      # account for margin changes
      if ((@y + @lasth) > @page_break_trigger) and !@in_footer
        AcceptPageBreak()
      end
      w = getRemainingWidth()
      wmax = w - (2 * @c_margin)
    else
      # 160 is the non-breaking space, 173 is SHY (Soft Hypen)
      if (c != 160) and ((unichr(c) =~ /\s/) or (c == 173))
        # update last blank space position
        sep = i
        # check if is a SHY
        if c == 173
          shy = true
          if pc == 45
            tmp_shy_replacement_width = 0
            tmp_shy_replacement_char = ''
          else
            tmp_shy_replacement_width = shy_replacement_width
            tmp_shy_replacement_char = shy_replacement_char
          end
        else
          shy = false
        end
      end

      # update string length
      if ((@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont0')) and arabic
        # with bidirectional algorithm some chars may be changed affecting the line length
        # *** very slow ***
        l = GetArrStringWidth(utf8Bidi(chars[j,i-j], '', rtl_text_dir))
      else
        l += GetCharWidth(c)
      end

      if (l > wmax) or ((c == 173) and ((l + tmp_shy_replacement_width) > wmax))
        # we have reached the end of column
        if (sep == -1)
          # check if the line was already started
          if (@rtl and (@x <= @w - @r_margin - chrwidth)) or (!@rtl and (@x >= @l_margin + chrwidth))
            # print a void cell and go to next line
            Cell(w, h, '', 0, 1)
            linebreak = true
            if firstline
              return UniArrSubString(uchars, j)
            end
          else
            # truncate the word because do not fit on column
            tmpstr = UniArrSubString(uchars, j, i)
            if firstline
              startx = @x
              tmparr = chars[j, i - j]
              if rtlmode
                tmparr = utf8Bidi(tmparr, tmpstr, rtl_text_dir)
              end
              linew = GetArrStringWidth(tmparr)
              tmparr = ''
              if @rtl
                @endlinex = startx - linew
              else
                @endlinex = startx + linew
              end
              w = linew
              tmpcmargin = @c_margin
              if maxh == 0
                @c_margin = 0
              end
            end
            if firstblock and isRTLTextDir()
              tmpstr = tmpstr.rstrip
            end
            Cell(w, h, tmpstr, 0, 1, align, fill, link, stretch)
            tmpstr = ''
            if firstline
              @c_margin = tmpcmargin
              return UniArrSubString(uchars, i)
            end
            j = i
            i -= 1
          end
        else
          # word wrapping
          if @rtl and !firstblock
            endspace = 1
          else
            endspace = 0
          end
          if shy
            # add hypen (minus symbol) at the end of the line
            shy_width = tmp_shy_replacement_width
            if @rtl
              shy_char_left = tmp_shy_replacement_char
              shy_char_right = ''
            else
              shy_char_left = ''
              shy_char_right = tmp_shy_replacement_char
            end
          else
            shy_width = 0
            shy_char_left = ''
            shy_char_right = ''
          end
          tmpstr = UniArrSubString(uchars, j, sep + endspace)
          if firstline
            startx = @x
            tmparr = chars[j, sep + endspace - j]
            if rtlmode
              tmparr = utf8Bidi(tmparr, tmpstr, rtl_text_dir)
            end
            linew = GetArrStringWidth(tmparr)
            tmparr = ''
            if @rtl
              @endlinex = startx - linew - shy_width
            else
              @endlinex = startx + linew + shy_width
            end
            w = linew
            tmpcmargin = @c_margin
            if maxh == 0
              @c_margin = 0
            end
          end
          # print the line
          if firstblock and isRTLTextDir()
            tmpstr = tmpstr.rstrip
          end
          Cell(w, h, shy_char_left + tmpstr + shy_char_right, 0, 1, align, fill, link, stretch)
          tmpstr = ''
          if firstline
            # return the remaining text
            @c_margin = tmpcmargin
            return UniArrSubString(uchars, sep + endspace)
          end
          i = sep
          sep = -1
          shy = false
          j = i + 1
        end
        # account for margin changes
        if (@y + @lasth > @page_break_trigger) and !@in_footer
          AcceptPageBreak()
        end
        w = getRemainingWidth()
        wmax = w - (2 * @c_margin)
        if linebreak
          linebreak = false
        else
          nl += 1
          l = 0
        end
      end
    end
    # save last character
    pc = c
    i +=1
  end # end while i < nb

  # print last substring (if any)
  if l > 0
    case align
    when 'J' , 'C'
      w = w
    when 'L'
      if @rtl
        w = w
      else
        w = l
      end
    when 'R'
      if @rtl
        w = l
      else
        w = w
      end
    else
      w = l
    end
    tmpstr = UniArrSubString(uchars, j, nb)
    if firstline
      startx = @x
      tmparr = chars[j, nb - j]
      if rtlmode
        tmparr = utf8Bidi(tmparr, tmpstr, rtl_text_dir)
      end
      linew = GetArrStringWidth(tmparr)
      tmparr = ''
      if @rtl
        @endlinex = startx - linew
      else
        @endlinex = startx + linew
      end
      w = linew
      tmpcmargin = @c_margin
      if maxh == 0
        @c_margin = 0
      end
    end
    if firstblock and isRTLTextDir()
      tmpstr = tmpstr.rstrip
    end
    Cell(w, h, tmpstr, 0, (ln ? 1 : 0), align, fill, link, stretch)
    tmpstr = ''
    if firstline
      @c_margin = tmpcmargin
      return UniArrSubString(uchars, nb)
    end
    nl += 1
  end

  if firstline
    return ''
  end
  return nl
rescue => err
  Error('Write Error.', err)
end

#writeHTML(html, ln = true, fill = 0, reseth = false, cell = false, align = '') ⇒ Object Also known as: write_html

Allows to preserve some HTML formatting (limited support). IMPORTANT: The HTML must be well formatted - try to clean-up it using an application like HTML-Tidy before submitting. Supported tags are: a, b, blockquote, br, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, img, li, ol, p, pre, small, span, strong, sub, sup, table, td, th, thead, tr, tt, u, ul

@param string :html

text to display

@param boolean :ln

if true add a new line after text (default = true)

@param int :fill

Indicates if the background must be painted (1:true) or transparent (0:false).

@param boolean :reseth

if true reset the last cell height (default false).

@param boolean :cell

if true add the default c_margin space to each Write (default false).

@param string :align

Allows to center or align the text. Possible values are:

  • L : left align

  • C : center

  • R : right align

  • ” : empty string : left for LTR or right for RTL

@access public


13016
13017
13018
13019
13020
13021
13022
13023
13024
13025
13026
13027
13028
13029
13030
13031
13032
13033
13034
13035
13036
13037
13038
13039
13040
13041
13042
13043
13044
13045
13046
13047
13048
13049
13050
13051
13052
13053
13054
13055
13056
13057
13058
13059
13060
13061
13062
13063
13064
13065
13066
13067
13068
13069
13070
13071
13072
13073
13074
13075
13076
13077
13078
13079
13080
13081
13082
13083
13084
13085
13086
13087
13088
13089
13090
13091
13092
13093
13094
13095
13096
13097
13098
13099
13100
13101
13102
13103
13104
13105
13106
13107
13108
13109
13110
13111
13112
13113
13114
13115
13116
13117
13118
13119
13120
13121
13122
13123
13124
13125
13126
13127
13128
13129
13130
13131
13132
13133
13134
13135
13136
13137
13138
13139
13140
13141
13142
13143
13144
13145
13146
13147
13148
13149
13150
13151
13152
13153
13154
13155
13156
13157
13158
13159
13160
13161
13162
13163
13164
13165
13166
13167
13168
13169
13170
13171
13172
13173
13174
13175
13176
13177
13178
13179
13180
13181
13182
13183
13184
13185
13186
13187
13188
13189
13190
13191
13192
13193
13194
13195
13196
13197
13198
13199
13200
13201
13202
13203
13204
13205
13206
13207
13208
13209
13210
13211
13212
13213
13214
13215
13216
13217
13218
13219
13220
13221
13222
13223
13224
13225
13226
13227
13228
13229
13230
13231
13232
13233
13234
13235
13236
13237
13238
13239
13240
13241
13242
13243
13244
13245
13246
13247
13248
13249
13250
13251
13252
13253
13254
13255
13256
13257
13258
13259
13260
13261
13262
13263
13264
13265
13266
13267
13268
13269
13270
13271
13272
13273
13274
13275
13276
13277
13278
13279
13280
13281
13282
13283
13284
13285
13286
13287
13288
13289
13290
13291
13292
13293
13294
13295
13296
13297
13298
13299
13300
13301
13302
13303
13304
13305
13306
13307
13308
13309
13310
13311
13312
13313
13314
13315
13316
13317
13318
13319
13320
13321
13322
13323
13324
13325
13326
13327
13328
13329
13330
13331
13332
13333
13334
13335
13336
13337
13338
13339
13340
13341
13342
13343
13344
13345
13346
13347
13348
13349
13350
13351
13352
13353
13354
13355
13356
13357
13358
13359
13360
13361
13362
13363
13364
13365
13366
13367
13368
13369
13370
13371
13372
13373
13374
13375
13376
13377
13378
13379
13380
13381
13382
13383
13384
13385
13386
13387
13388
13389
13390
13391
13392
13393
13394
13395
13396
13397
13398
13399
13400
13401
13402
13403
13404
13405
13406
13407
13408
13409
13410
13411
13412
13413
13414
13415
13416
13417
13418
13419
13420
13421
13422
13423
13424
13425
13426
13427
13428
13429
13430
13431
13432
13433
13434
13435
13436
13437
13438
13439
13440
13441
13442
13443
13444
13445
13446
13447
13448
13449
13450
13451
13452
13453
13454
13455
13456
13457
13458
13459
13460
13461
13462
13463
13464
13465
13466
13467
13468
13469
13470
13471
13472
13473
13474
13475
13476
13477
13478
13479
13480
13481
13482
13483
13484
13485
13486
13487
13488
13489
13490
13491
13492
13493
13494
13495
13496
13497
13498
13499
13500
13501
13502
13503
13504
13505
13506
13507
13508
13509
13510
13511
13512
13513
13514
13515
13516
13517
13518
13519
13520
13521
13522
13523
13524
13525
13526
13527
13528
13529
13530
13531
13532
13533
13534
13535
13536
13537
13538
13539
13540
13541
13542
13543
13544
13545
13546
13547
13548
13549
13550
13551
13552
13553
13554
13555
13556
13557
13558
13559
13560
13561
13562
13563
13564
13565
13566
13567
13568
13569
13570
13571
13572
13573
13574
13575
13576
13577
13578
13579
13580
13581
13582
13583
13584
13585
13586
13587
13588
13589
13590
13591
13592
13593
13594
13595
13596
13597
13598
13599
13600
13601
13602
13603
13604
13605
13606
13607
13608
13609
13610
13611
13612
13613
13614
13615
13616
13617
13618
13619
13620
13621
13622
13623
13624
13625
13626
13627
13628
13629
13630
13631
13632
13633
13634
13635
13636
13637
13638
13639
13640
13641
13642
13643
13644
13645
13646
13647
13648
13649
13650
13651
13652
13653
13654
13655
13656
13657
13658
13659
13660
13661
13662
13663
13664
13665
13666
13667
13668
13669
13670
13671
13672
13673
13674
13675
13676
13677
13678
13679
13680
13681
13682
13683
13684
13685
13686
13687
13688
13689
13690
13691
13692
13693
13694
13695
13696
13697
13698
13699
13700
13701
13702
13703
13704
13705
13706
13707
13708
13709
13710
13711
13712
13713
13714
13715
13716
13717
13718
13719
13720
13721
13722
13723
13724
13725
13726
13727
13728
13729
13730
13731
13732
13733
13734
13735
13736
13737
13738
13739
13740
13741
13742
13743
13744
13745
13746
13747
13748
13749
13750
13751
13752
13753
13754
13755
13756
13757
13758
13759
13760
13761
13762
13763
13764
13765
13766
13767
13768
13769
13770
13771
13772
13773
13774
13775
13776
13777
13778
13779
13780
13781
13782
13783
13784
13785
13786
13787
13788
13789
13790
13791
13792
13793
13794
13795
13796
13797
13798
13799
13800
13801
13802
13803
13804
13805
13806
13807
13808
13809
13810
13811
13812
13813
13814
13815
13816
13817
13818
13819
13820
13821
13822
13823
13824
13825
13826
13827
13828
13829
13830
13831
13832
13833
13834
13835
13836
13837
13838
13839
13840
13841
13842
13843
13844
13845
13846
13847
13848
13849
13850
13851
13852
13853
13854
13855
13856
13857
13858
13859
13860
13861
13862
13863
13864
13865
13866
13867
13868
13869
13870
13871
13872
13873
13874
13875
13876
13877
13878
13879
13880
13881
13882
13883
13884
13885
13886
13887
13888
13889
13890
13891
13892
13893
13894
13895
13896
13897
13898
13899
13900
13901
13902
13903
13904
13905
13906
13907
13908
13909
13910
13911
13912
13913
13914
13915
13916
13917
13918
13919
13920
13921
13922
13923
13924
13925
13926
13927
13928
13929
13930
13931
13932
13933
13934
13935
13936
13937
13938
13939
13940
13941
13942
13943
13944
13945
13946
13947
13948
13949
13950
13951
13952
13953
13954
13955
13956
13957
13958
13959
13960
13961
13962
13963
13964
13965
13966
13967
13968
13969
13970
13971
13972
13973
13974
13975
13976
13977
13978
13979
13980
13981
13982
13983
13984
13985
13986
13987
13988
13989
13990
13991
13992
13993
13994
13995
13996
13997
13998
13999
14000
14001
14002
14003
14004
14005
14006
14007
14008
14009
14010
14011
14012
14013
14014
14015
14016
14017
14018
14019
14020
14021
14022
14023
14024
14025
14026
14027
14028
14029
14030
14031
14032
14033
14034
14035
14036
14037
14038
14039
14040
14041
14042
14043
14044
14045
14046
14047
14048
14049
14050
14051
14052
14053
14054
14055
14056
14057
14058
14059
14060
14061
14062
14063
14064
14065
14066
14067
14068
14069
14070
14071
14072
14073
14074
14075
14076
14077
14078
14079
14080
14081
14082
14083
14084
14085
14086
14087
14088
14089
14090
14091
14092
14093
14094
14095
14096
14097
14098
14099
14100
14101
14102
14103
14104
14105
14106
14107
14108
14109
14110
14111
14112
14113
14114
14115
14116
14117
14118
14119
14120
14121
14122
14123
14124
14125
14126
14127
14128
14129
14130
14131
14132
14133
14134
14135
14136
14137
14138
14139
14140
14141
14142
14143
14144
14145
14146
14147
14148
14149
14150
14151
14152
14153
14154
14155
14156
14157
14158
14159
14160
14161
14162
14163
14164
14165
14166
14167
14168
14169
14170
14171
14172
# File 'lib/rbpdf.rb', line 13016

def writeHTML(html, ln=true, fill=0, reseth=false, cell=false, align='')
  ln = false if ln == 0
  reseth = false if reseth == 0
  cell = false if cell == 0
  case fill
  when true
    fill = 1
  when false
    fill = 0
  end

  gvars = getGraphicVars()
  # store current values
  prevPage = @page
  prevlMargin = @l_margin
  prevrMargin = @r_margin
  curfontname = @font_family
  curfontstyle = @font_style
  curfontsize = @font_size_pt
  curfontascent = getFontAscent(curfontname, curfontstyle, curfontsize)
  curfontdescent = getFontDescent(curfontname, curfontstyle, curfontsize)
  @newline = true
  startlinepage = @page
  minstartliney = @y
  maxbottomliney = 0
  startlinex = @x
  startliney = @y
  yshift = 0
  newline = true
  loop = 0
  curpos = 0
  opentagpos = nil
  this_method_vars = {}
  undo = false
  fontaligned = false
  @premode = false
  if !@page_annots[@page].nil?
    pask = @page_annots[@page].length
  else
    pask = 0
  end
  if !@in_footer
    if !@footerlen[@page].nil?
      @footerpos[@page] = @pagelen[@page] - @footerlen[@page]
    else
      @footerpos[@page] = @pagelen[@page]
    end
    startlinepos = @footerpos[@page]
  else
    startlinepos = @pagelen[@page]
  end
  lalign = align
  plalign = align
  if @rtl
    w = @x - @l_margin
  else
    w = @w - @r_margin - @x
  end
  w -= 2 * @c_margin

  if cell
    if @rtl
      @x -= @c_margin
    else
      @x += @c_margin
    end
  end
  if @customlistindent >= 0
    @listindent = @customlistindent
  else
    @listindent = GetStringWidth('0000')
  end
  @listindentlevel = 0
  # save previous states
  prev_cell_height_ratio = @cell_height_ratio
  prev_listnum = @listnum
  prev_listordered = @listordered
  prev_listcount = @listcount
  prev_lispacer = @lispacer
  prev_li_position_x = @li_position_x
  @listnum = 0
  @listordered = []
  @listcount = []
  @lispacer = ''
  if empty_string(@lasth) or reseth
    #set row height
    @lasth = @font_size * @cell_height_ratio
  end
  dom = getHtmlDomArray(html)
  maxel = dom.size
  key = 0
  while key < maxel
    if dom[key]['tag'] and dom[key]['attribute'] and dom[key]['attribute']['pagebreak']
      # check for pagebreak
      if (dom[key]['attribute']['pagebreak'] == 'true') or (dom[key]['attribute']['pagebreak'] == 'left') or (dom[key]['attribute']['pagebreak'] == 'right')
        # add a page (or trig AcceptPageBreak() for multicolumn mode)
        checkPageBreak(@page_break_trigger + 1)
      end
      if ((dom[key]['attribute']['pagebreak'] == 'left') and ((!@rtl and (@page % 2 == 0)) or (@rtl and (@page % 2 != 0)))) or ((dom[key]['attribute']['pagebreak'] == 'right') and ((!@rtl and (@page % 2 != 0)) or (@rtl and (@page % 2 == 0))))
        # add a page (or trig AcceptPageBreak() for multicolumn mode)
        checkPageBreak(@page_break_trigger + 1)
      end
    end
    if dom[key]['tag'] and dom[key]['opening'] and dom[key]['attribute']['nobr'] and (dom[key]['attribute']['nobr'] == 'true')
      if dom[(dom[key]['parent'])]['attribute']['nobr'] and (dom[(dom[key]['parent'])]['attribute']['nobr'] == 'true')
        dom[key]['attribute']['nobr'] = false
      else
        # store current object
        startTransaction()
        # save this method vars
        this_method_vars['html'] = html.dup
        this_method_vars['ln'] = ln
        this_method_vars['fill'] = fill
        this_method_vars['reseth'] = reseth
        this_method_vars['cell'] = cell
        this_method_vars['align'] = align.dup
        this_method_vars['gvars'] = Marshal.load(Marshal.dump(gvars))
        this_method_vars['prevPage'] = prevPage
        this_method_vars['prevlMargin'] = prevlMargin
        this_method_vars['prevrMargin'] = prevrMargin
        this_method_vars['curfontname'] = curfontname.dup
        this_method_vars['curfontstyle'] = curfontstyle.dup
        this_method_vars['curfontsize'] = curfontsize
        this_method_vars['curfontascent'] = curfontascent
        this_method_vars['curfontdescent'] = curfontdescent
        this_method_vars['minstartliney'] = minstartliney
        this_method_vars['maxbottomliney'] = maxbottomliney
        this_method_vars['yshift'] = yshift
        this_method_vars['startlinepage'] = startlinepage
        this_method_vars['startlinepos'] = startlinepos
        this_method_vars['startlinex'] = startlinex
        this_method_vars['startliney'] = startliney
        this_method_vars['newline'] = newline
        this_method_vars['loop'] = loop
        this_method_vars['curpos'] = curpos
        this_method_vars['pask'] = pask
        this_method_vars['lalign'] = lalign
        this_method_vars['plalign'] = plalign
        this_method_vars['w'] = w
        this_method_vars['prev_cell_height_ratio'] = prev_cell_height_ratio
        this_method_vars['prev_listnum'] = prev_listnum
        this_method_vars['prev_listordered'] = prev_listordered
        this_method_vars['prev_listcount'] = prev_listcount
        this_method_vars['prev_lispacer'] = prev_lispacer
        this_method_vars['fontaligned'] = fontaligned
        this_method_vars['key'] = key
        this_method_vars['dom'] = Marshal.load(Marshal.dump(dom))
      end
    end
    # print THEAD block
    if (dom[key]['value'] == 'tr') and dom[key]['thead'] and dom[key]['thead']
      if dom[key]['parent'] and dom[(dom[key]['parent'])]['thead'] and !empty_string(dom[(dom[key]['parent'])]['thead'])
        @in_thead = true

        prev_lMargin = @l_margin
        prev_rMargin = @r_margin
        @l_margin = @thead_margins['lmargin']
        @r_margin = @thead_margins['rmargin']

        # print table header (thead)
        writeHTML(@thead, false, false, false, false, '')

        @l_margin = prev_lMargin
        @r_margin = prev_rMargin

        if (@start_transaction_page == (@numpages - 1)) or (@y < @start_transaction_y) or checkPageBreak(@lasth, '', false)
          # restore previous object
          rollbackTransaction(true)
          # restore previous values
          this_method_vars.each {|vkey , vval|
            eval("#{vkey} = vval")
          }
          # add a page (or trig AcceptPageBreak() for multicolumn mode)
          pre_y = @y
          if !checkPageBreak(@page_break_trigger + 1) and (@y < pre_y)
            # fix for multicolumn mode
            startliney = @y
          end
          @start_transaction_page = @page
          @start_transaction_y = @y
        end
      end
      # move :key index forward to skip THEAD block
      while (key < maxel) and !((dom[key]['tag'] and dom[key]['opening'] and (dom[key]['value'] == 'tr') and (dom[key]['thead'].nil? or !dom[key]['thead'])) or (dom[key]['tag'] and !dom[key]['opening'] and (dom[key]['value'] == 'table')))
        key += 1
      end
    end
    if dom[key]['tag'] or (key == 0)
      if dom[key]['line-height']
        # set line height
        @cell_height_ratio = dom[key]['line-height']
        @lasth = @font_size * @cell_height_ratio
      end
      if ((dom[key]['value'] == 'table') or (dom[key]['value'] == 'tr')) and !dom[key]['align'].nil?
        dom[key]['align'] = @rtl ? 'R' : 'L'
      end
      # vertically align image in line
      if !@newline and (dom[key]['value'] == 'img') and dom[key]['height'] and (dom[key]['height'].to_i > 0)
        # get image height
        imgh = getHTMLUnitToUnits(dom[key]['height'], @lasth, 'px')
        # check for automatic line break
        autolinebreak = false
        if dom[key]['width'] and (dom[key]['width'].to_i > 0)
          imgw = getHTMLUnitToUnits(dom[key]['width'], 1, 'px', false)
          if (@rtl and (@x - imgw < @l_margin + @c_margin)) or (!@rtl and (@x + imgw > @w - @r_margin - @c_margin))
            # add automatic line break
            autolinebreak = true
            Ln('', cell)
            # go back to evaluate this line break
            key -= 1
          end
        end
        if !autolinebreak
          if !@in_footer
            pre_y = @y
            # check for page break
            if !checkPageBreak(imgh) and (@y < pre_y)
              # fix for multicolumn mode
              startliney = @y
            end
          end
          if @page > startlinepage
            # fix line splitted over two pages
            if !@footerlen[startlinepage].nil?
              curpos = @pagelen[startlinepage] - @footerlen[startlinepage]
            end
            # line to be moved one page forward
            pagebuff = getPageBuffer(startlinepage)
            linebeg = pagebuff[startlinepos, curpos - startlinepos]
            tstart = pagebuff[0, startlinepos]
            tend = pagebuff[curpos..-1]
            # remove line from previous page
            setPageBuffer(startlinepage, tstart + '' + tend)
            pagebuff = getPageBuffer(@page)
            tstart = pagebuff[0, @cntmrk[@page]]
            tend = pagebuff[@cntmrk[@page]..-1]
            # add line start to current page
            yshift = minstartliney - @y
            if fontaligned
              yshift += curfontsize / @k
            end
            try = sprintf('1 0 0 1 0 %.3f cm', (yshift * @k))
            setPageBuffer(@page, tstart + "\nq\n" + try + "\n" + linebeg + "\nQ\n" + tend)
            # shift the annotations and links
            if @page_annots[@page]
              next_pask = @page_annots[@page].length
            else
              next_pask = 0
            end
            if !@page_annots[startlinepage].nil?
              @page_annots[startlinepage].each_with_index { |pac, pak|
                if pak >= pask
                  @page_annots[@page].push pac
                  @page_annots[startlinepage].delete_at(pak)
                  npak = @page_annots[@page].length - 1
                  @page_annots[@page][npak]['y'] -= yshift
                end
              }
            end
            pask = next_pask
            startlinepos = @cntmrk[@page]
            startlinepage = @page
            startliney = @y
          end
          @y += ((curfontsize * @cell_height_ratio / @k) + curfontascent - curfontdescent) / 2.0  - imgh
          minstartliney = [@y, minstartliney].min
          maxbottomliney = startliney + @font_size * @cell_height_ratio
        end
      elsif !dom[key]['fontname'].nil? or !dom[key]['fontstyle'].nil? or !dom[key]['fontsize'].nil?
        # account for different font size
        pfontname = curfontname
        pfontstyle = curfontstyle
        pfontsize = curfontsize
        fontname  = !dom[key]['fontname'].nil?  ? dom[key]['fontname']  : curfontname
        fontstyle = !dom[key]['fontstyle'].nil? ? dom[key]['fontstyle'] : curfontstyle
        fontsize  = !dom[key]['fontsize'].nil?  ? dom[key]['fontsize']  : curfontsize
        fontascent = getFontAscent(fontname, fontstyle, fontsize)
        fontdescent = getFontDescent(fontname, fontstyle, fontsize)
        if (fontname != curfontname) or (fontstyle != curfontstyle) or (fontsize != curfontsize)
          if fontsize.is_a?(Numeric) and (fontsize >= 0) and curfontsize.is_a?(Numeric) and (curfontsize >= 0) and (fontsize != curfontsize) and !@newline and (key < maxel - 1)
            if !@newline and (@page > startlinepage)
              # fix lines splitted over two pages
              if !@footerlen[startlinepage].nil?
                curpos = @pagelen[startlinepage] - @footerlen[startlinepage]
              end
              # line to be moved one page forward
              pagebuff = getPageBuffer(startlinepage)
              linebeg = pagebuff[startlinepos, curpos - startlinepos]
              tstart = pagebuff[0, startlinepos]
              tend = pagebuff[curpos..-1]
              # remove line from previous page
              setPageBuffer(startlinepage, tstart + '' + tend)
              pagebuff = getPageBuffer(@page)
              tstart = pagebuff[0, @cntmrk[@page]]
              tend = pagebuff[@cntmrk[@page]..-1]
              # add line start to current page
              yshift = minstartliney - @y
              try = sprintf('1 0 0 1 0 %.3f cm', yshift * @k)
              setPageBuffer(@page, tstart + "\nq\n" + try + "\n" + linebeg + "\nQ\n" + tend)
              # shift the annotations and links
              if @page_annots[@page]
                next_pask = @page_annots[@page].length
              else
                next_pask = 0
              end
              if !@page_annots[startlinepage].nil?
                @page_annots[startlinepage].each_with_index { |pac, pak|
                  if pak >= pask
                    @page_annots[@page].push = pac
                    @page_annots[startlinepage].delete_at(pak)
                    npak = @page_annots[@page].length - 1
                    @page_annots[@page][npak]['y'] -= yshift
                  end
                }
              end
              pask = next_pask
              startlinepos = @cntmrk[@page]
              startlinepage = @page
              startliney = @y
            end
            if !dom[key]['block']
              @y += (((curfontsize - fontsize) * @cell_height_ratio / @k) + curfontascent - fontascent - curfontdescent + fontdescent) / 2.0
              if (dom[key]['value'] != 'sup') and (dom[key]['value'] != 'sub')
                minstartliney = [@y, minstartliney].min
                maxbottomliney = [@y + ((fontsize * @cell_height_ratio) / @k), maxbottomliney].max
              end
            end
            fontaligned = true
          end
          SetFont(fontname, fontstyle, fontsize)
          @lasth = @font_size * @cell_height_ratio
          curfontname = fontname
          curfontstyle = fontstyle
          curfontsize = fontsize
          curfontascent = fontascent
          curfontdescent = fontdescent
        end
      end
      # set text rendering mode
      textstroke = !dom[key]['stroke'].nil? ? dom[key]['stroke'] : @textstrokewidth
      textfill = !dom[key]['fill'].nil? ? dom[key]['fill'] : ((@textrendermode % 2) == 0)
      textclip = !dom[key]['clip'].nil? ? dom[key]['clip'] : (@textrendermode > 3)
      setTextRenderingMode(textstroke, textfill, textclip)
      if (plalign == 'J') and dom[key]['block']
        plalign = ''
      end
      # get current position on page buffer
      curpos = @pagelen[startlinepage]
      if !dom[key]['bgcolor'].nil? and (dom[key]['bgcolor'].length > 0)
        SetFillColorArray(dom[key]['bgcolor'])
        wfill = 1
      else
        wfill = fill
      end
      if !dom[key]['fgcolor'].nil? and (dom[key]['fgcolor'].length > 0)
        SetTextColorArray(dom[key]['fgcolor'])
      end
      if !dom[key]['strokecolor'].nil? and (dom[key]['strokecolor'].length > 0)
        SetDrawColorArray(dom[key]['strokecolor'])
      end
      if !dom[key]['align'].nil?
        lalign = dom[key]['align']
      end
      if empty_string(lalign)
        lalign = align
      end
    end
    # align lines
    if @newline and (dom[key]['value'].length > 0) and (dom[key]['value'] != 'td') and (dom[key]['value'] != 'th')
      newline = true
      fontaligned = false
      # we are at the beginning of a new line
      if !startlinex.nil?
        yshift = minstartliney - startliney
        if (yshift > 0) or (@page > startlinepage)
          yshift = 0
        end
        t_x = 0
        # the last line must be shifted to be aligned as requested
        linew = (@endlinex - startlinex).abs
        pstart = getPageBuffer(startlinepage)[0, startlinepos]
        if !opentagpos.nil? and !@footerlen[startlinepage].nil? and !@in_footer
          @footerpos[startlinepage] = @pagelen[startlinepage] - @footerlen[startlinepage]
          midpos = [opentagpos, @footerpos[startlinepage]].min
        elsif !opentagpos.nil?
          midpos = opentagpos
        elsif !@footerlen[startlinepage].nil? and !@in_footer
          @footerpos[startlinepage] = @pagelen[startlinepage] - @footerlen[startlinepage]
          midpos = @footerpos[startlinepage]
        else
          midpos = 0
        end
        if midpos > 0
          pmid = getPageBuffer(startlinepage)[startlinepos, midpos - startlinepos]
          pend = getPageBuffer(startlinepage)[midpos..-1]
        else
          pmid = getPageBuffer(startlinepage)[startlinepos..-1]
          pend = ''
        end
        if (!plalign.nil? and ((plalign == 'C') or (plalign == 'J') or ((plalign == 'R') and !@rtl) or ((plalign == 'L') and @rtl))) or (yshift < 0)
          # calculate shifting amount
          tw = w
          if (plalign == 'J') and isRTLTextDir() and (@num_columns > 1)
            tw += @c_margin
          end
          if @l_margin != prevlMargin
            tw += prevlMargin - @l_margin
          end
          if @r_margin != prevrMargin
            tw += prevrMargin - @r_margin
          end
          one_space_width = GetStringWidth(32.chr)
          mdiff = (tw - linew).abs
          if plalign == 'C'
            if @rtl
              t_x = -(mdiff / 2.0)
            else
              t_x = (mdiff / 2.0)
            end
          elsif (plalign == 'R') and !@rtl
            # right alignment on LTR document
            if revstrpos(pmid, ')]').to_i == revstrpos(pmid, ' )]').to_i + 1
              # remove last space (if any)
              linew -= one_space_width
              mdiff = (tw - linew).abs
            end
            t_x = mdiff
          elsif (plalign == 'L') and @rtl
            # left alignment on RTL document
            if revstrpos(pmid, '[(') and ((revstrpos(pmid, '[( ').to_i == revstrpos(pmid, '[(').to_i) or (revstrpos(pmid, '[(' + 0.chr + 32.chr).to_i == revstrpos(pmid, '[(').to_i))
              # remove first space (if any)
              linew -= one_space_width
            end
            if pmid.index('[(') and (pmid.index('[(').to_i == revstrpos(pmid, '[(').to_i)
              # remove last space (if any)
              linew -= one_space_width
              if (@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont0')
                linew -= one_space_width
              end
            end
            mdiff = (tw - linew).abs
            t_x = -mdiff
          elsif (plalign == 'J') and (plalign == lalign)
            # Justification
            if isRTLTextDir()
              t_x = @l_margin - @endlinex + @c_margin
            end
            no = 0 # spaces without trim
            ns = 0 # spaces with trim

            pmidtemp = pmid.dup
            # escape special characters
            pmidtemp.gsub!(/[\\][\(]/x, '\\#!#OP#!#')
            pmidtemp.gsub!(/[\\][\)]/x, '\\#!#CP#!#')
            # search spaces
            lnstring = pmidtemp.scan(/\[\(([^\)]*)\)\]/x)
            if !lnstring.empty?
              spacestr = getSpaceString()
              maxkk = lnstring.length - 1
              0.upto(maxkk) do |kk|
                # restore special characters
                lnstring[kk][0].gsub!('#!#OP#!#', '(')
                lnstring[kk][0].gsub!('#!#CP#!#', ')')
                if kk == maxkk
                  if isRTLTextDir()
                    tvalue = lnstring[kk][0].lstrip
                  else
                    tvalue = lnstring[kk][0].rstrip
                  end
                else
                  tvalue = lnstring[kk][0]
                end
                # store number of spaces on the strings
                lnstring[kk][1] = lnstring[kk][0].count(spacestr)
                lnstring[kk][2] = tvalue.count(spacestr)
                # count total spaces on line
                no += lnstring[kk][1]
                ns += lnstring[kk][2]
                lnstring[kk][3] = no
                lnstring[kk][4] = ns
              end
              if isRTLTextDir()
                t_x = @l_margin - @endlinex + @c_margin - ((no - ns) * one_space_width)
              end
              # calculate additional space to add to each space
              spacelen = one_space_width
              spacewidth = (((tw - linew) + ((no - ns) * spacelen)) / (ns ? ns : 1)) * @k
              spacewidthu = -1000 * ((tw - linew) + (no * spacelen)) / (ns ? ns : 1) / @font_size
              nsmax = ns
              ns = 0
              # reset(lnstring)
              offset = 0
              strcount = 0
              prev_epsposbeg = 0
              textpos = 0;
              if isRTLTextDir()
                textpos = @w_pt
              end
              while pmid_offset = pmid.index(/([0-9\.\+\-]*)[\s](Td|cm|m|l|c|re)[\s]/x, offset)
                pmid_data = $1
                pmid_mark = $2
                # check if we are inside a string section '[( ... )]'
                stroffset = pmid.index('[(', offset)
                if (stroffset != nil) and (stroffset <= pmid_offset)
                  # set offset to the end of string section
                  offset = pmid.index(')]', stroffset)
                  while (offset != nil) and (pmid[offset - 1, 1] == '\\')
                    offset = pmid.index(')]', offset + 1)
                  end
                  if offset == false
                    Error('HTML Justification: malformed PDF code.')
                  end
                  next
                end
                if isRTLTextDir()
                  spacew = spacewidth * (nsmax - ns)
                else
                  spacew = spacewidth * ns
                end
                offset = pmid_offset + $&.length
                epsposbeg = pmid.index('q' + @epsmarker, offset)
                epsposbeg = 0 if epsposbeg.nil?
                epsposend = pmid.index(@epsmarker + 'Q', offset)
                epsposend = 0 if epsposend.nil?
                epsposend += (@epsmarker + 'Q').length
                if ((epsposbeg > 0) and (epsposend > 0) and (offset > epsposbeg) and (offset < epsposend)) or ((epsposbeg === false) and (epsposend > 0) and (offset < epsposend))
                  # shift EPS images
                  trx = sprintf('1 0 0 1 %.3f 0 cm', spacew)
                  epsposbeg = pmid.index('q' + @epsmarker, prev_epsposbeg - 6)
                  epsposbeg = 0 if epsposbeg.nil?
                  pmid_b = pmid[0, epsposbeg]
                  pmid_m = pmid[epsposbeg, epsposend - epsposbeg]
                  pmid_e = pmid[epsposend..-1]
                  pmid = pmid_b + "\nq\n" + trx + "\n" + pmid_m + "\nQ\n" + pmid_e
                  offset = epsposend
                  next
                end
                prev_epsposbeg = epsposbeg
                currentxpos = 0
                # shift blocks of code
                case pmid_mark
                when 'Td', 'cm', 'm', 'l'
                  # get current X position
                  pmid =~ /([0-9\.\+\-]*)[\s](#{pmid_data})[\s](#{pmid_mark})([\s]*)/x
                  currentxpos = $1.to_i
                  textpos = currentxpos
                  if (strcount <= maxkk) and (pmid_mark == 'Td')
                    if strcount == maxkk
                      if isRTLTextDir()
                        tvalue = lnstring[strcount][0]
                      else
                        tvalue = lnstring[strcount][0].rstrip
                      end
                    else
                      tvalue = lnstring[strcount][0]
                    end
                    ns += tvalue.count(spacestr)
                    strcount += 1
                  end
                  if isRTLTextDir()
                    spacew = spacewidth * (nsmax - ns)
                  end
                  # justify block
                  pmid.sub!(/([0-9\.\+\-]*)[\s](#{pmid_data})[\s](#{pmid_mark})([\s]*)/x, "" + sprintf("%.2f", $1.to_f + spacew) + " " + $2 + " x*#!#*x" + $3 + $4)
                when 're'
                  # justify block
                  pmid =~ /([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s](#{pmid_data})[\s](re)([\s]*)/x
                  currentxpos = $1.to_i
                  x_diff = 0
                  w_diff = 0
                  if isRTLTextDir() # RTL
                    if currentxpos < textpos
                      x_diff = spacewidth * (nsmax - lnstring[strcount][4])
                      w_diff = spacewidth * lnstring[strcount][2]
                    else
                      if strcount > 0
                        x_diff = spacewidth * (nsmax - lnstring[strcount - 1][4])
                        w_diff = spacewidth * lnstring[strcount - 1][2]
                      end
                    end
                  else # LTR
                    if currentxpos > textpos
                      if strcount > 0
                        x_diff = spacewidth * lnstring[strcount - 1][3]
                      end
                      w_diff = spacewidth * lnstring[strcount][2]
                    else
                      if strcount > 1
                        x_diff = spacewidth * lnstring[strcount - 2][3]
                      end
                      if strcount > 0
                        w_diff = spacewidth * lnstring[strcount - 1][2]
                      end
                    end
                  end
                  pmid.sub!(/(#{$1})[\s](#{$2})[\s](#{$3})[\s](#{pmid_data})[\s](re)([\s]*)/x, "" + sprintf("%.2f", $1.to_f + x_diff) + " " + $2 + " " + sprintf("%.2f", $3.to_f + w_diff) + " " + $4 + " x*#!#*x" + $5 + $6)
                when 'c'
                  # get current X position
                  pmid =~ /([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s](#{pmid_data})[\s](c)([\s]*)/x
                  currentxpos = $1.to_i
                  # justify block
                  pmid.sub!(/(#{$1})[\s](#{$2})[\s](#{$3})[\s](#{$4})[\s](${5})[\s](#{pmid_data})[\s](c)([\s]*)/x, "" + sprintf("%.3f", $1.to_f + spacew) + " " + $2 + " " +  sprintf("%.3f", $3.to_f + spacew) + " " + $4 + " " + sprintf("%.3f", $5.to_f + spacew) + " " + $6 + " x*#!#*x" + $7 + $8)
                end
                # shift the annotations and links
                if !@page_annots[@page].nil?
                  cxpos = currentxpos / @k
                  lmpos = @l_margin + @c_margin + @feps

                  @page_annots[@page].each_with_index { |pac, pak|
                    if (pac['y'] >= minstartliney) and (pac['x'] * @k >= currentxpos - @feps) and (pac['x'] * @k <= currentxpos + @feps)
                      if cxpos > lmpos
                        @page_annots[@page][pak]['x'] += (spacew - one_space_width) / @k
                        @page_annots[@page][pak]['w'] += (spacewidth * pac['numspaces']) / @k
                      else
                        @page_annots[@page][pak]['w'] += ((spacewidth * pac['numspaces']) - one_space_width) / @k
                      end
                      break
                    end
                  }
                end
              end # end of while
              # remove markers
              pmid.gsub!('x*#!#*x', '')
              if (@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont0')
                # multibyte characters
                spacew = spacewidthu
                pmidtemp = pmid.dup
                # escape special characters
                pmidtemp.gsub!(/[\\][\(]/x, '\\#!#OP#!#')
                pmidtemp.gsub!(/[\\][\)]/x, '\\#!#CP#!#')
                pmidtemp =~ /\[\(([^\)]*)\)\]/x
                matches1 = $1.gsub("#!#OP#!#", "(")
                matches1.gsub!("#!#CP#!#", ")")
                pmid = pmidtemp.sub(/\[\(([^\)]*)\)\]/x,  "[(" + matches1.gsub(0.chr + 32.chr, ") " + sprintf("%.3f", spacew) + " (") + ")]")
                setPageBuffer(startlinepage, pstart + "\n" + pmid + "\n" + pend)
                endlinepos = (pstart + "\n" + pmid + "\n").length
              else
                # non-unicode (single-byte characters)
                rs = sprintf("%.3f Tw", spacewidth)
                pmid.gsub!(/\[\(/x, "#{rs} [(")
                setPageBuffer(startlinepage, pstart + "\n" + pmid + "\nBT 0 Tw ET\n" + pend)
                endlinepos = (pstart + "\n" + pmid + "\nBT 0 Tw ET\n").length
              end
            end
          end # end of J
        end # end if $startlinex
        if (t_x != 0) or (yshift < 0)
          # shift the line
          trx = sprintf('1 0 0 1 %.3f %.3f cm', t_x * @k, yshift * @k)
          setPageBuffer(startlinepage, pstart + "\nq\n" + trx + "\n" + pmid + "\nQ\n" + pend)
          endlinepos = (pstart + "\nq\n" + trx + "\n" + pmid + "\nQ\n").length
          # shift the annotations and links
          if !@page_annots[@page].nil?
            @page_annots[@page].each_with_index { |pac, pak|
              if pak >= pask
                @page_annots[@page][pak]['x'] += t_x
                @page_annots[@page][pak]['y'] -= yshift
              end
            }
          end
          @y -= yshift
        end
      end
      pbrk = checkPageBreak(@lasth)
      @y += @c_margin if pbrk and !dom[key]['tag'] and !empty_string(@thead) and !@in_thead ### fix ###
      @newline = false
      startlinex = @x
      startliney = @y
      if dom[dom[key]['parent']]['value'] == 'sup'
        startliney -= (0.3 * @font_size_pt) / @k
      elsif dom[dom[key]['parent']]['value'] == 'sub'
        startliney -= (@font_size_pt / 0.7) / @k
      else
        minstartliney = startliney
        maxbottomliney = startliney + @font_size * @cell_height_ratio
      end
      if startlinepage == @page and !endlinepos.nil? and !pbrk # fix startlinepos at page break case.
        startlinepos = endlinepos
      else
        startlinepage = @page
        if !@in_footer
          if !@footerlen[@page].nil?
            @footerpos[@page] = @pagelen[@page] - @footerlen[@page]
          else
            @footerpos[@page] = @pagelen[@page]
          end
          startlinepos = @footerpos[@page]
        else
          startlinepos = @pagelen[@page]
        end
      end
      endlinepos = nil
      plalign = lalign
      if !@page_annots[@page].nil?
        pask = @page_annots[@page].length
      else
        pask = 0
      end
      SetFont(fontname, fontstyle, fontsize)
      if wfill  == 1
        SetFillColorArray(@bgcolor)
      end
    end # end newline
    if !opentagpos.nil?
      opentagpos = nil
    end
    if dom[key]['tag']
      addHtmlAnchor(@html_anchor) if @html_anchor
      if dom[key]['opening']
        # get text indentation (if any)
        if dom[key]['text-indent'] and dom[key]['block']
          @textindent = dom[key]['text-indent']
          @newline = true
        end
        if dom[key]['value'] == 'table'
          # available page width
          if @rtl
            wtmp = @x - @l_margin
          else
            wtmp = @w - @r_margin - @x
          end
          if cell or (dom[key]['attribute']['nested'] and (dom[key]['attribute']['nested'] == 'true'))
            # add margin for nested tables
            wtmp -= @c_margin
          end
          # table width
          if !dom[key]['width'].nil?
            table_width = getHTMLUnitToUnits(dom[key]['width'], wtmp, 'px')
          else
            table_width = wtmp
          end
        end
        if (dom[key]['value'] == 'td') or (dom[key]['value'] == 'th')
          trid = dom[key]['parent']
          table_el = dom[trid]['parent']
          if dom[table_el]['cols'].nil?
            dom[table_el]['cols'] = dom[trid]['cols']
          end
          oldmargin = @c_margin
          currentcmargin = @c_margin
          if !dom[(dom[trid]['parent'])]['attribute']['cellpadding'].nil?
            currentcmargin = getHTMLUnitToUnits(dom[(dom[trid]['parent'])]['attribute']['cellpadding'], 1, 'px')
          end
          if currentcmargin < (@line_width / 2.0)
            currentcmargin = @line_width / 2.0
          end
          @c_margin = currentcmargin
          if !dom[(dom[trid]['parent'])]['attribute']['cellspacing'].nil?
            cellspacing = getHTMLUnitToUnits(dom[(dom[trid]['parent'])]['attribute']['cellspacing'], 1, 'px')
          else
            cellspacing = 0
          end
          if @rtl
            cellspacingx = -cellspacing
          else
            cellspacingx = cellspacing
          end
          colspan = dom[key]['attribute']['colspan']
          table_columns_width = table_width - (cellspacing * (dom[table_el]['cols'] - 1))
          wtmp = colspan * (table_columns_width / dom[table_el]['cols']) + (colspan - 1) * cellspacing
          if !dom[key]['width'].nil?
            cellw = getHTMLUnitToUnits(dom[key]['width'], table_columns_width, 'px')
          else
            cellw = wtmp
          end
          if !dom[key]['height'].nil?
            # minimum cell height
            cellh = getHTMLUnitToUnits(dom[key]['height'], 0, 'px')
          else
            cellh = 0
          end
          if !dom[key]['content'].nil?
            cell_content = dom[key]['content']
          else
            cell_content = '&nbsp;'
          end
          tagtype = dom[key]['value']
          parentid = key
          while (key < maxel) and !(dom[key]['tag'] and !dom[key]['opening'] and (dom[key]['value'] == tagtype) and (dom[key]['parent'] == parentid))
            # move :key index forward
            key += 1
          end
          if dom[trid]['startpage'].nil?
            dom[trid]['startpage'] = @page
          else
             setPage(dom[trid]['startpage'])
          end
          if dom[trid]['starty'].nil?
            dom[trid]['starty'] = @y
          else
            @y = dom[trid]['starty']
          end
          if dom[trid]['startx'].nil?
            dom[trid]['startx'] = @x
          else
            @x += (cellspacingx / 2.0)
          end
          if !dom[parentid]['attribute']['rowspan'].nil?
            rowspan = dom[parentid]['attribute']['rowspan'].to_i
          else
            rowspan = 1
          end
          # skip row-spanned cells started on the previous rows
          if !dom[table_el]['rowspans'].nil?
            rsk = 0
            rskmax = dom[table_el]['rowspans'].length
            while rsk < rskmax
              trwsp = dom[table_el]['rowspans'][rsk]
              rsstartx = trwsp['startx']
              rsendx = trwsp['endx']
              # account for margin changes
              if trwsp['startpage'] < @page
                if @rtl and (@pagedim[@page]['orm'] != @pagedim[trwsp['startpage']]['orm'])
                  dl = @pagedim[@page]['orm'] - @pagedim[trwsp['startpage']]['orm']
                  rsstartx -= dl
                  rsendx -= dl
                elsif !@rtl and (@pagedim[@page]['olm'] != @pagedim[trwsp['startpage']]['olm'])
                  dl = @pagedim[@page]['olm'] - @pagedim[trwsp['startpage']]['olm']
                  rsstartx += dl
                  rsendx += dl
                end
              end
              if  (trwsp['rowspan'] > 0) and (rsstartx > @x - cellspacing - currentcmargin - @feps) and (rsstartx < @x + cellspacing + currentcmargin + @feps) and ((trwsp['starty'] < @y - @feps) or (trwsp['startpage'] < @page))
                # set the starting X position of the current cell
                @x = rsendx + cellspacingx
                if (trwsp['rowspan'] == 1) and !dom[trid]['endy'].nil? and !dom[trid]['endpage'].nil? and (trwsp['endpage'] == dom[trid]['endpage'])
                  # set ending Y position for row
                  dom[table_el]['rowspans'][rsk]['endy'] = [dom[trid]['endy'], trwsp['endy']].max
                  dom[trid]['endy'] = dom[table_el]['rowspans'][rsk]['endy']
                end
                rsk = 0
              else
                rsk += 1
              end
            end
          end
          # add rowspan information to table element
          if rowspan > 1
            dom[table_el]['rowspans'].push({'trid' => trid, 'rowspan' => rowspan, 'mrowspan' => rowspan, 'colspan' => colspan, 'startpage' => @page, 'startx' => @x, 'starty' => @y})
            trsid = dom[table_el]['rowspans'].size
          end
          dom[trid]['cellpos'].push({'startx' => @x})
          cellid = dom[trid]['cellpos'].size
          if rowspan > 1
            dom[trid]['cellpos'][cellid - 1]['rowspanid'] = trsid - 1
          end
          # push background colors
          if !dom[parentid]['bgcolor'].nil? and (dom[parentid]['bgcolor'].length > 0)
            dom[trid]['cellpos'][cellid - 1]['bgcolor'] = dom[parentid]['bgcolor'].dup
          end
          prevLastH = @lasth
          # ****** write the cell content ******
          MultiCell(cellw, cellh, cell_content, 0, lalign, 0, 2, '', '', true, 0, true)
          @lasth = prevLastH
          @c_margin = oldmargin
          dom[trid]['cellpos'][cellid - 1]['endx'] = @x
          # update the end of row position
          if rowspan <= 1
            if !dom[trid]['endy'].nil?
              if @page == dom[trid]['endpage']
                dom[trid]['endy'] = [@y, dom[trid]['endy']].max
              elsif @page > dom[trid]['endpage']
                dom[trid]['endy'] = @y
              end
            else
              dom[trid]['endy'] = @y
            end
            if !dom[trid]['endpage'].nil?
              dom[trid]['endpage'] = [@page, dom[trid]['endpage']].max
            else
              dom[trid]['endpage'] = @page
            end
          else
            # account for row-spanned cells
            dom[table_el]['rowspans'][trsid - 1]['endx'] = @x
            dom[table_el]['rowspans'][trsid - 1]['endy'] = @y
            dom[table_el]['rowspans'][trsid - 1]['endpage'] = @page
          end
          if !dom[table_el]['rowspans'].nil?
            # update endy and endpage on rowspanned cells
            dom[table_el]['rowspans'].each_with_index { |trwsp, k|
              if trwsp['rowspan'] > 0
                if !dom[trid]['endpage'].nil?
                  if trwsp['endpage'] == dom[trid]['endpage']
                    dom[table_el]['rowspans'][k]['endy'] = [dom[trid]['endy'], trwsp['endy']].max
                  elsif trwsp['endpage'] < dom[trid]['endpage']
                    dom[table_el]['rowspans'][k]['endy'] = dom[trid]['endy']
                    dom[table_el]['rowspans'][k]['endpage'] = dom[trid]['endpage']
                  else
                    dom[trid]['endy'] = @pagedim[dom[trid]['endpage']]['hk'] - @pagedim[dom[trid]['endpage']]['bm']
                  end
                end
              end
            }
          end
          @x += (cellspacingx / 2.0)
        else
          # opening tag (or self-closing tag)
          if opentagpos.nil?
            if !@in_footer
              if !@footerlen[@page].nil?
                @footerpos[@page] = @pagelen[@page] - @footerlen[@page]
              else
                @footerpos[@page] = @pagelen[@page]
              end
              opentagpos = @footerpos[@page]
            end
          end
          dom = openHTMLTagHandler(dom, key, cell)
        end
      else
        # closing tag
        prev_numpages = @numpages
        dom = closeHTMLTagHandler(dom, key, cell, maxbottomliney)
        if prev_numpages > @numpages
          startlinepage = @page
        end
      end
    elsif dom[key]['value'].length > 0
      # print list-item
      if !empty_string(@lispacer)
        SetFont(pfontname, pfontstyle, pfontsize)
        @lasth = @font_size * @cell_height_ratio
        minstartliney = @y
        maxbottomliney = startliney + @font_size * @cell_height_ratio
        putHtmlListBullet(@listnum, @lispacer, pfontsize)
        SetFont(curfontname, curfontstyle, curfontsize)
        @lasth = @font_size * @cell_height_ratio
        if pfontsize.is_a?(Numeric) and (pfontsize > 0) and curfontsize.is_a?(Numeric) and (curfontsize > 0) and (pfontsize != curfontsize)
          pfontascent = getFontAscent(pfontname, pfontstyle, pfontsize)
          pfontdescent = getFontDescent(pfontname, pfontstyle, pfontsize)
          @y += ((pfontsize - curfontsize) * @cell_height_ratio / @k + pfontascent - curfontascent - pfontdescent + curfontdescent) / 2.0
          minstartliney = [@y, minstartliney].min
          maxbottomliney = [@y + pfontsize * @cell_height_ratio / @k, maxbottomliney].max
        end
      end
      # text
      @htmlvspace = 0 unless dom[key]['value'].strip.length == 0
      if !@premode and isRTLTextDir()
        # reverse spaces order
        len1 = dom[key]['value'].length
        lsp = len1 - dom[key]['value'].lstrip.length
        rsp = len1 - dom[key]['value'].rstrip.length
        tmpstr = ''
        if rsp > 0
          tmpstr << dom[key]['value'][-rsp..-1]
        end
        tmpstr << (dom[key]['value']).strip
        if lsp > 0
          tmpstr << dom[key]['value'][0, lsp]
        end
        dom[key]['value'] = tmpstr
      end
      if newline
        if !@premode
          prelen = dom[key]['value'].length
          if isRTLTextDir()
            dom[key]['value'] = dom[key]['value'].rstrip
          else
            dom[key]['value'] = dom[key]['value'].lstrip
          end
          postlen = dom[key]['value'].length
          if (postlen == 0) and (prelen > 0)
            dom[key]['trimmed_space'] = true
          end
        end
        newline = false
        firstblock = true
      else
        firstblock = false
      end
      strrest = ''
      if @rtl
        @x -= @textindent
      else
        @x += @textindent
      end
      if !@href.empty? and @href['url']
        # HTML <a> Link
        hrefcolor = ''
        if dom[(dom[key]['parent'])]['fgcolor'] and !dom[(dom[key]['parent'])]['fgcolor'].empty?
          hrefcolor = dom[(dom[key]['parent'])]['fgcolor']
        end
        hrefstyle = -1
        if dom[(dom[key]['parent'])]['fontstyle'] and (dom[(dom[key]['parent'])]['fontstyle'] != false)
          hrefstyle = dom[(dom[key]['parent'])]['fontstyle']
        end
        strrest = addHtmlLink(@href['url'], dom[key]['value'], wfill, true, hrefcolor, hrefstyle, true)
      else
        # ****** write only until the end of the line and get the rest ******
        strrest = Write(@lasth, dom[key]['value'], '', wfill, '', false, 0, true, firstblock, 0)
      end
      @textindent = 0

      if !strrest.nil? and strrest.length > 0
        # store the remaining string on the previous :key position
        @newline = true
        if cell
          if @rtl
            @x -= @c_margin
          else
            @x += @c_margin
          end
        end
        if strrest == dom[key]['value']
          # used to avoid infinite loop
          loop += 1
        else
          loop = 0
        end
        if !@href.empty? and @href['url']
          dom[key]['value'] = strrest.strip
        elsif @premode
          dom[key]['value'] = strrest
        elsif isRTLTextDir()
          dom[key]['value'] = strrest.rstrip
        else
          dom[key]['value'] = strrest.lstrip
        end
        if loop < 3
          key -= 1
        end
      else
        loop = 0
      end
    end
    key += 1
    if dom[key] and dom[key]['tag'] and (dom[key]['opening'].nil? or !dom[key]['opening']) and dom[(dom[key]['parent'])]['attribute']['nobr'] and (dom[(dom[key]['parent'])]['attribute']['nobr'] == 'true')
      if !undo and (@start_transaction_page == (@numpages - 1)) or (@y < @start_transaction_y)
        # restore previous object
        rollbackTransaction(true)
        # restore previous values
        this_method_vars.each {|vkey , vval|
          eval("#{vkey} = vval")
        }
        # add a page (or trig AcceptPageBreak() for multicolumn mode)
        pre_y = @y
        if !checkPageBreak(@page_break_trigger + 1) and (@y < pre_y)
          startliney = @y
        end
        undo = true # avoid infinite loop
      else
        undo = false
      end
    end
  end # end for each :key
  # align the last line
  if !startlinex.nil?
    yshift = minstartliney - startliney
    if (yshift > 0) or (@page > startlinepage)
      yshift = 0
    end
    t_x = 0
    # the last line must be shifted to be aligned as requested
    linew = (@endlinex - startlinex).abs
    pstart = getPageBuffer(startlinepage)[0, startlinepos]
    if !opentagpos.nil? and !@footerlen[startlinepage].nil? and !@in_footer
      @footerpos[startlinepage] = @pagelen[startlinepage] - @footerlen[startlinepage]
      midpos = [opentagpos, @footerpos[startlinepage]].min
    elsif !opentagpos.nil?
      midpos = opentagpos
    elsif !@footerlen[startlinepage].nil? and !@in_footer
      @footerpos[startlinepage] = @pagelen[startlinepage] - @footerlen[startlinepage]
      midpos = @footerpos[startlinepage]
    else
      midpos = 0
    end
    if midpos > 0
      pmid = getPageBuffer(startlinepage)[startlinepos, midpos - startlinepos]
      pend = getPageBuffer(startlinepage)[midpos..-1]
    else
      pmid = getPageBuffer(startlinepage)[startlinepos..-1]
      pend = ""
    end
    if (!plalign.nil? and (((plalign == 'C') or ((plalign == 'R') and !@rtl) or ((plalign == 'L') and @rtl)))) or (yshift < 0)
      # calculate shifting amount
      tw = w
      if @l_margin != prevlMargin
        tw += prevlMargin - @l_margin
      end
      if @r_margin != prevrMargin
        tw += prevrMargin - @r_margin
      end
      one_space_width = GetStringWidth(32.chr)
      mdiff = (tw - linew).abs
      if plalign == 'C'
        if @rtl
          t_x = -(mdiff / 2.0)
        else
          t_x = (mdiff / 2.0)
        end
      elsif (plalign == 'R') and !@rtl
        # right alignment on LTR document
        if revstrpos(pmid, ')]').to_i == revstrpos(pmid, ' )]').to_i + 1
          # remove last space (if any)
          linew -= one_space_width
          mdiff = (tw - linew).abs
        end
        t_x = mdiff
      elsif (plalign == 'L') and @rtl
        # left alignment on RTL document
        if revstrpos(pmid, '[(') and ((revstrpos(pmid, '[( ').to_i == revstrpos(pmid, '[(').to_i) or (revstrpos(pmid, '[(' + 0.chr + 32.chr).to_i == revstrpos(pmid, '[(').to_i))
          # remove first space (if any)
          linew -= one_space_width
        end
        if pmid.index('[(') and (pmid.index('[(').to_i == revstrpos(pmid, '[(').to_i)
          # remove last space (if any)
          linew -= one_space_width
          if (@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont0')
            linew -= one_space_width
          end
        end
        mdiff = (tw - linew).abs
        t_x = -mdiff
      end
    end # end if startlinex
    if (t_x != 0) or (yshift < 0)
      # shift the line
      trx = sprintf('1 0 0 1 %.3f %.3f cm', t_x * @k, yshift * @k)
      setPageBuffer(startlinepage, pstart + "\nq\n" + trx + "\n" + pmid + "\nQ\n" + pend)
      endlinepos = (pstart + "\nq\n" + trx + "\n" + pmid + "\nQ\n").length

      # shift the annotations and links
      if !@page_annots[@page].nil?
        @page_annots[@page].each_with_index { |pac, pak|
          if pak >= pask
            @page_annots[@page][pak]['x'] += t_x
            @page_annots[@page][pak]['y'] -= yshift
          end
        }
      end
      @y -= yshift
    end
  end
  if ln and !(cell and (dom[key-1]['value'] == 'table'))
    Ln(@lasth)
    if @y < maxbottomliney
      @y = maxbottomliney
    end
  end
  # restore previous values
  setGraphicVars(gvars)
  if @page > prevPage
    @l_margin = @pagedim[@page]['olm']
    @r_margin = @pagedim[@page]['orm']
  end
  # restore previous list state
  @cell_height_ratio = prev_cell_height_ratio
  @listnum = prev_listnum
  @listordered = prev_listordered
  @listcount = prev_listcount
  @lispacer = prev_lispacer
  @li_position_x = prev_li_position_x
  dom = nil
rescue => err
  Error('writeHTML Error.', err)
end

#writeHTMLCell(w, h, x, y, html = '', border = 0, ln = 0, fill = 0, reseth = true, align = '', autopadding = true) ⇒ Object Also known as: write_html_cell

Prints a cell (rectangular area) with optional borders, background color and html text string. The upper-left corner of the cell corresponds to the current position. After the call, the current position moves to the right or to the next line. If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting.

@param float :w

Cell width. If 0, the cell extends up to the right margin.

@param float :h

Cell minimum height. The cell extends automatically if needed.

@param float :x

upper-left corner X coordinate

@param float :y

upper-left corner Y coordinate

@param string :html

html text to print. Default value: empty string.

@param mixed :border

Indicates if borders must be drawn around the cell. The value can be either a number:

  • 0: no border (default)

  • 1: frame

or a string containing some or all of the following characters (in any order):

  • L: left

  • T: top

  • R: right

  • B: bottom

@param int :ln

Indicates where the current position should go after the call. Possible values are:

  • 0: to the right (or left for RTL language)

  • 1: to the beginning of the next line

  • 2: below

Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.

@param int :fill

Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.

@param boolean :reseth

if true reset the last cell height (default true).

@param string :align

Allows to center or align the text. Possible values are:

  • L : left align

  • C : center

  • R : right align

  • ” : empty string : left for LTR or right for RTL

@param boolean :autopadding

if true, uses internal padding and automatically adjust it to account for line width.

@access public
@uses

MultiCell()

@see

Multicell(), writeHTML(), Cell()



12982
12983
12984
12985
12986
12987
# File 'lib/rbpdf.rb', line 12982

def writeHTMLCell(w, h, x, y, html='', border=0, ln=0, fill=0, reseth=true, align='', autopadding=true)
  rtn = MultiCell(w, h, html, border, align, fill, ln, x, y, reseth, 0, true, autopadding, 0)
  return rtn
rescue => err
  Error('writeHTMLCell Error.', err)
end