Class: RBPDF

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

Overview

This is a Ruby class for generating PDF files on-the-fly without requiring external extensions.

  • This class is a Ruby port of the TCPDF class by Nicola Asuni (www.tcpdf.org).

  • This class is an extension and improvement of the FPDF class by Olivier Plathey (www.fpdf.org).

  • This version contains some changes: [porting to Ruby, support for UTF-8 Unicode, code style and formatting, php documentation (www.phpdoc.org), ISO page formats, minor improvements, image scale factor]

  • TCPDF project (www.tcpdf.org) has been originally derived in 2002 from the Public Domain FPDF class by Olivier Plathey (www.fpdf.org), but now is almost entirely rewritten.

  • To add your own TTF fonts please read /fonts/README.TXT

@name

RBPDF

@@version

5.1.002

@author

Nicola Asuni

@license

www.gnu.org/copyleft/lesser.html LGPL 2.1

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

@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

Since:

  • 1.0



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
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
# File 'lib/rbpdf.rb', line 244

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");
  # }

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

  # 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
  @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 ||= []
  @listindent ||= 0
  @listindentlevel ||= 0
  @lispacer ||= ""

  # bookmark
  @outlines ||= []

  # --- javascript and form ---
  @javascript ||= ''
  @js_objects ||= []

  @dpi = 72.0
  @newpagegroup ||= []
  @pagegroups ||= {}
  @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 ||= []
  @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 ||= []
  @apxo_start_obj_id ||= 400000
  @apxo_obj_id ||= 400000
  @annotation_fonts ||= {}
  @radiobutton_groups ||= []
  @radio_groups ||= []
  @textindent ||= 0
  @nested_table = false

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

  # 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
  @pages ||= []
  @prev_pages ||= []
  @state ||= 0
  @fonts ||= {}
  @font_files ||= {}
  @diffs ||= []
  @images ||= {}
  @links ||= []
  @gradients ||= []
  @in_footer ||= false
  @lasth ||= 0
  @font_family ||= 'helvetica'
  @font_style ||= ''
  @font_size_pt ||= 12
  @underline ||= false
  @overline ||= false
  @linethrough ||= false
  @draw_color ||= '0 G'
  @fill_color ||= '0 g'
  @text_color ||= '0 g'
  @color_flag ||= false

  # 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
end

Instance Attribute Details

#barcodeObject

Returns the value of attribute barcode.



132
133
134
# File 'lib/rbpdf.rb', line 132

def barcode
  @barcode
end

#bufferObject

Returns the value of attribute buffer.



134
135
136
# File 'lib/rbpdf.rb', line 134

def buffer
  @buffer
end

#cache_file_lengthObject

Returns the value of attribute cache_file_length.



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

def cache_file_length
  @cache_file_length
end

#color_flagObject

Returns the value of attribute color_flag.



138
139
140
# File 'lib/rbpdf.rb', line 138

def color_flag
  @color_flag
end

#default_fontObject

Returns the value of attribute default_font.



140
141
142
# File 'lib/rbpdf.rb', line 140

def default_font
  @default_font
end

#diffsObject

Returns the value of attribute diffs.



136
137
138
# File 'lib/rbpdf.rb', line 136

def diffs
  @diffs
end

#diskcacheObject

Returns the value of attribute diskcache.



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

def diskcache
  @diskcache
end

#draw_colorObject

Returns the value of attribute draw_color.



142
143
144
# File 'lib/rbpdf.rb', line 142

def draw_color
  @draw_color
end

#encodingObject

Returns the value of attribute encoding.



144
145
146
# File 'lib/rbpdf.rb', line 144

def encoding
  @encoding
end

#fill_colorObject

Returns the value of attribute fill_color.



146
147
148
# File 'lib/rbpdf.rb', line 146

def fill_color
  @fill_color
end

#font_familyObject

Returns the value of attribute font_family.



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

def font_family
  @font_family
end

#font_filesObject

Returns the value of attribute font_files.



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

def font_files
  @font_files
end

#font_size_ptObject

Returns the value of attribute font_size_pt.



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

def font_size_pt
  @font_size_pt
end

#font_styleObject

Returns the value of attribute font_style.



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

def font_style
  @font_style
end

#fontsObject

Returns the value of attribute fonts.



148
149
150
# File 'lib/rbpdf.rb', line 148

def fonts
  @fonts
end

#header_logoObject

Returns the value of attribute header_logo.



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

def 
  @header_logo
end

#header_logo_widthObject

Returns the value of attribute header_logo_width.



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

def header_logo_width
  @header_logo_width
end

#header_stringObject

Returns the value of attribute header_string.



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

def header_string
  @header_string
end

#header_titleObject

Returns the value of attribute header_title.



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

def header_title
  @header_title
end

#header_widthObject

Returns the value of attribute header_width.



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

def header_width
  @header_width
end

#imagesObject

Returns the value of attribute images.



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

def images
  @images
end

#img_scaleObject

Returns the value of attribute img_scale.



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

def img_scale
  @img_scale
end

Returns the value of attribute in_footer.



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

def in_footer
  @in_footer
end

#is_unicodeObject

Returns the value of attribute is_unicode.



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

def is_unicode
  @is_unicode
end

#lasthObject

Returns the value of attribute lasth.



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

def lasth
  @lasth
end

Returns the value of attribute links.



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

def links
  @links
end

#lispacerObject

Returns the value of attribute lispacer.



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

def lispacer
  @lispacer
end

#listcountObject

Returns the value of attribute listcount.



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

def listcount
  @listcount
end

#listorderedObject

Returns the value of attribute listordered.



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

def listordered
  @listordered
end

#nObject

Returns the value of attribute n.



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

def n
  @n
end

#offsetsObject

Returns the value of attribute offsets.



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

def offsets
  @offsets
end

#pageObject

Returns the value of attribute page.



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

def page
  @page
end

#pagesObject

Returns the value of attribute pages.



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

def pages
  @pages
end

#pdf_versionObject

Returns the value of attribute pdf_version.



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

def pdf_version
  @pdf_version
end

#prev_pagesObject

Returns the value of attribute prev_pages.



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

def prev_pages
  @prev_pages
end

Returns the value of attribute print_footer.



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

def print_footer
  @print_footer
end

Returns the value of attribute print_header.



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

def print_header
  @print_header
end

#stateObject

Returns the value of attribute state.



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

def state
  @state
end

#text_colorObject

Returns the value of attribute text_color.



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

def text_color
  @text_color
end

#underlineObject

Returns the value of attribute underline.



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

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()



3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
# File 'lib/rbpdf.rb', line 3160

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 = '') ⇒ 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.

@access public
@since 1.5
@see

SetFont()



2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
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
# File 'lib/rbpdf.rb', line 2584

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

  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

  # search and include font file
  if empty_string(fontfile)
    # build a standard filenames for specified font
    fontfile1 = family.gsub(' ', '') + style.downcase + '.rb'
    fontfile2 = family.gsub(' ', '') + '.rb'
    # search files on various directories
    if (fontdir != false) and File.exists?(fontdir + fontfile1)
      fontfile = fontdir + fontfile1
      fontname = fontfile1
    elsif fontfile = getfontpath(fontfile1)
      fontname = fontfile1
    elsif File.exists?(fontfile1)
      fontfile = fontfile1
      fontname = fontfile1
    elsif (fontdir != false) and File.exists?(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.exists?(fontfile)
    require(fontfile)
  else
    Error('Could not include font definition file: ' + family + '')
  end

  font_desc = RBPDFFontDescriptor.font(fontname)
  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'}
    sname = 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
    setFontBuffer(fontkey, {'i' => @numfonts, 'type' => font_desc[:type], 'name' => sname, 'desc' => desc, 'cidinfo' => font_desc[:cidinfo], 'up' => font_desc[:up], 'ut' => font_desc[:ut], 'cw' => font_desc[:cw], 'dw' => font_desc[:dw], 'enc' => font_desc[:enc]})
  elsif font_desc[:type] == 'core'
    font_desc[:name] = @core_fonts[fontkey]
  elsif (font_desc[:type] == 'TrueType') or (font_desc[:type] == 'Type1')
    # ...
  elsif font_desc[:type] == 'TrueTypeUnicode'
    font_desc[:enc] = 'Identity-H'
  else
    Error('Unknow font type: ' + type + '')
  end
  setFontBuffer(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]})

  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_desc[:type] == 'TrueType') or (font_desc[:type] == 'TrueTypeUnicode')
      @font_files[font_desc[:file]] = {'length1' => font_desc[:originalsize], 'fontdir' => fontdir}
    elsif font_desc[:type] != 'core'
      @font_files[font_desc[:file]] = {'length1' => font_desc[:size1], 'length2' => font_desc[:size2], 'fontdir' => fontdir}
    end
  end
  return fontdata
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


7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
# File 'lib/rbpdf.rb', line 7932

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
    page = url.sub(/^#/, "").to_i
    url = AddLink()
    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()



14226
14227
14228
14229
14230
14231
14232
14233
14234
14235
14236
14237
14238
14239
14240
14241
14242
14243
14244
14245
14246
14247
14248
14249
14250
14251
14252
14253
14254
14255
14256
14257
14258
14259
14260
14261
14262
14263
14264
14265
14266
14267
14268
14269
14270
14271
14272
14273
14274
14275
14276
14277
14278
14279
14280
14281
14282
14283
14284
14285
14286
14287
14288
14289
14290
14291
14292
14293
14294
14295
14296
14297
14298
14299
14300
14301
14302
14303
14304
14305
14306
14307
14308
14309
14310
14311
14312
14313
14314
# File 'lib/rbpdf.rb', line 14226

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



2922
2923
2924
2925
2926
2927
# File 'lib/rbpdf.rb', line 2922

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()



1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
# File 'lib/rbpdf.rb', line 1661

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()



2177
2178
2179
2180
2181
2182
# File 'lib/rbpdf.rb', line 2177

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()



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
14173
14174
14175
14176
14177
14178
14179
14180
14181
14182
14183
14184
14185
14186
14187
14188
14189
14190
14191
14192
14193
14194
14195
14196
14197
14198
14199
14200
14201
14202
14203
14204
14205
14206
14207
14208
14209
14210
# File 'lib/rbpdf.rb', line 14075

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



1623
1624
1625
# File 'lib/rbpdf.rb', line 1623

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()



9750
9751
9752
# File 'lib/rbpdf.rb', line 9750

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()



9779
9780
9781
9782
# File 'lib/rbpdf.rb', line 9779

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)


2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
# File 'lib/rbpdf.rb', line 2981

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)


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
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
# File 'lib/rbpdf.rb', line 8945

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)


9636
9637
9638
9639
9640
9641
9642
9643
9644
9645
9646
9647
9648
9649
9650
9651
9652
9653
9654
9655
9656
# File 'lib/rbpdf.rb', line 9636

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)


3226
3227
3228
3229
3230
3231
3232
3233
# File 'lib/rbpdf.rb', line 3226

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

#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()



3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
# File 'lib/rbpdf.rb', line 3289

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


8623
8624
8625
# File 'lib/rbpdf.rb', line 8623

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()



1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
# File 'lib/rbpdf.rb', line 1499

def Close()
  #Terminate document
  if (@state==3)
    return;
  end
  if (@page==0)
    AddPage();
  end
  # close page
  endPage()
  lastPage()
  @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

#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)


14340
14341
14342
14343
14344
14345
14346
14347
14348
14349
14350
14351
14352
# File 'lib/rbpdf.rb', line 14340

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


7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
# File 'lib/rbpdf.rb', line 7966

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)


8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
# File 'lib/rbpdf.rb', line 8457

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)


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
# File 'lib/rbpdf.rb', line 13929

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|
    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


5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
# File 'lib/rbpdf.rb', line 5535

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


8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
# File 'lib/rbpdf.rb', line 8489

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)


14417
14418
14419
# File 'lib/rbpdf.rb', line 14417

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()



1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
# File 'lib/rbpdf.rb', line 1682

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()



1634
1635
1636
# File 'lib/rbpdf.rb', line 1634

def endTOCPage()
  endPage(true)
end

#Error(msg) ⇒ 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

@access public
@since 1.0


1474
1475
1476
1477
1478
# File 'lib/rbpdf.rb', line 1474

def Error(msg)
  destroy(true)
  #Fatal error
  raise ("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


1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
# File 'lib/rbpdf.rb', line 1993

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).round
  #  write1DBarcode(barcode, 'C128B', GetX(), cur_y + line_width, barcode_width, ((getFooterMargin() / 3) - 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()



5301
5302
5303
# File 'lib/rbpdf.rb', line 5301

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()



9763
9764
9765
9766
9767
9768
# File 'lib/rbpdf.rb', line 9763

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()



9793
9794
9795
9796
9797
9798
# File 'lib/rbpdf.rb', line 9793

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)


2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
# File 'lib/rbpdf.rb', line 2477

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()



1183
1184
1185
1186
1187
1188
# File 'lib/rbpdf.rb', line 1183

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



1191
1192
1193
1194
# File 'lib/rbpdf.rb', line 1191

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)


10039
10040
10041
# File 'lib/rbpdf.rb', line 10039

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)


2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
# File 'lib/rbpdf.rb', line 2514

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)


2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
# File 'lib/rbpdf.rb', line 2890

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


2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
# File 'lib/rbpdf.rb', line 2867

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


10340
10341
10342
# File 'lib/rbpdf.rb', line 10340

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)


10318
10319
10320
# File 'lib/rbpdf.rb', line 10318

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)


10329
10330
10331
# File 'lib/rbpdf.rb', line 10329

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)


10351
10352
10353
# File 'lib/rbpdf.rb', line 10351

def getFontStyle()
  return @font_style
end

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

Get Footer font.

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


7878
7879
7880
# File 'lib/rbpdf.rb', line 7878

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


1882
1883
1884
# File 'lib/rbpdf.rb', line 1882

def getFooterMargin()
  return @footer_margin
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)


9807
9808
9809
# File 'lib/rbpdf.rb', line 9807

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()



9818
9819
9820
# File 'lib/rbpdf.rb', line 9818

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)


1823
1824
1825
1826
1827
1828
1829
1830
# File 'lib/rbpdf.rb', line 1823

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)


7851
7852
7853
# File 'lib/rbpdf.rb', line 7851

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


1855
1856
1857
# File 'lib/rbpdf.rb', line 1855

def getHeaderMargin()
  return @header_margin
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)


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
# File 'lib/rbpdf.rb', line 13228

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
  when 'em' # relative-size
    retval = value * refsize
  when 'ex' # height of lower case 'x' (about half the font-size)
    retval = value * (refsize / 2)
  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)


4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
# File 'lib/rbpdf.rb', line 4670

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


1922
1923
1924
# File 'lib/rbpdf.rb', line 1922

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


1932
1933
1934
# File 'lib/rbpdf.rb', line 1932

def getImageRBY()
  return @img_rb_y
end

#GetImageScaleObject



1071
1072
1073
1074
# File 'lib/rbpdf.rb', line 1071

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


1066
1067
1068
# File 'lib/rbpdf.rb', line 1066

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)


1037
1038
1039
# File 'lib/rbpdf.rb', line 1037

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()



8203
8204
8205
# File 'lib/rbpdf.rb', line 8203

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)


10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
# File 'lib/rbpdf.rb', line 10284

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)


2542
2543
2544
2545
2546
2547
# File 'lib/rbpdf.rb', line 2542

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


4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
# File 'lib/rbpdf.rb', line 4072

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)
      cellMargin = lineWidth / 2
    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()



1610
1611
1612
# File 'lib/rbpdf.rb', line 1610

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)


10306
10307
10308
10309
# File 'lib/rbpdf.rb', line 10306

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()



1598
1599
1600
# File 'lib/rbpdf.rb', line 1598

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)


1132
1133
1134
1135
1136
1137
# File 'lib/rbpdf.rb', line 1132

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)


9831
9832
9833
9834
9835
9836
# File 'lib/rbpdf.rb', line 9831

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

#GetPageHeightObject



1169
1170
1171
1172
# File 'lib/rbpdf.rb', line 1169

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


1164
1165
1166
# File 'lib/rbpdf.rb', line 1164

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)


9847
9848
9849
9850
9851
9852
# File 'lib/rbpdf.rb', line 9847

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)


562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
# File 'lib/rbpdf.rb', line 562

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



1152
1153
1154
1155
# File 'lib/rbpdf.rb', line 1152

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


1147
1148
1149
# File 'lib/rbpdf.rb', line 1147

def getPageWidth()
  return @w;
end

#GetPDFDataObject



7915
7916
7917
7918
# File 'lib/rbpdf.rb', line 7915

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

#getPDFDataObject Also known as: get_pdf_data

Returns the PDF data.

@access public


7907
7908
7909
7910
7911
7912
# File 'lib/rbpdf.rb', line 7907

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

#getRTLObject Also known as: get_rtl

Return the RTL status

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


967
968
969
# File 'lib/rbpdf.rb', line 967

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


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

def getScaleFactor()
  return @k;
end

#GetScaleFactorObject



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

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


4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
# File 'lib/rbpdf.rb', line 4179

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)
      cellMargin = lineWidth / 2
    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


2452
2453
2454
# File 'lib/rbpdf.rb', line 2452

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()



5285
5286
5287
5288
5289
5290
5291
# File 'lib/rbpdf.rb', line 5285

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()



5313
5314
5315
# File 'lib/rbpdf.rb', line 5313

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


1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
# File 'lib/rbpdf.rb', line 1942

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 library and JPEG and GIF images supported by RMagick. 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. 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 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


4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
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
# File 'lib/rbpdf.rb', line 4748

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

  # 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('Missing image file: ' + 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('[Image] 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
    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
      if (type == 'jpeg')
        info=parsejpeg(file)
      elsif (type == 'png')
        info=parsepng(file);
      elsif (type == 'gif')
        tmpFile = imageToPNG(file)
        if tmpFile != false
          info=parsepng(tmpFile.path)
          tmpFile.delete
        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?(:Magick)
        info = ImagePngAlpha(file, x, y, w, h, 'PNG', link, align, resize, dpi, palign)
        if false != info
          return
        end
      end
    end
    if !info
      if 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 { self.quality = jpeg_quality }
        tmpname.close

        info = parsejpeg(tmpname.path)
        tmpname.delete
      else
        return false
      end
    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
    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
    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).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

#image_alpha_mask(file) ⇒ Object



5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
# File 'lib/rbpdf.rb', line 5064

def image_alpha_mask(file)
  img = Magick::ImageList.new(file)

  img2 = img.separate(Magick::OpacityChannel)
  img = img2.negate(true)

  #use a temporary file....
  tmpFile = Tempfile.new(['msk_', '.png'], @@k_path_cache)
  tmpFile.binmode
  tmpFile.print img.to_blob
  tmpFile
ensure
  tmpFile.close unless tmpFile.nil?
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)


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
# File 'lib/rbpdf.rb', line 13285

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)


996
997
998
999
1000
1001
1002
# File 'lib/rbpdf.rb', line 996

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()



1586
1587
1588
# File 'lib/rbpdf.rb', line 1586

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()



8373
8374
8375
8376
8377
8378
8379
8380
# File 'lib/rbpdf.rb', line 8373

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()



2963
2964
2965
# File 'lib/rbpdf.rb', line 2963

def Link(x, y, w, h, link, spaces=0)
  Annotation(x, y, w, h, link, {'Subtype'=>'Link'}, spaces)
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()



5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
# File 'lib/rbpdf.rb', line 5253

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



105
106
107
# File 'lib/rbpdf.rb', line 105

def logger
  Rails.logger
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)


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
# File 'lib/rbpdf.rb', line 13788

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
  #@javascript = preg_replace_callback('/this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/',
  #create_function('$matches', 'global $jfrompage, $jtopage;
  #  pagenum = matches[3].to_i + 1
  #  if (pagenum >= jtopage) and (pagenum < jfrompage)
  #    newpage = pagenum + 1
  #  elsif pagenum == jfrompage
  #    newpage = jtopage
  #  else
  #    newpage = pagenum
  #  end
  #  newpage -= 1
  #  return "this.addField(\'".$matches[1]."\',\'".$matches[2]."\',".$newpage."";'), $tmpjavascript);

  # 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()



3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
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
# File 'lib/rbpdf.rb', line 3784

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)
  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)
      @c_margin = @line_width / 2
    end
    # Add top space if needed
    if (@lasth - @font_size) < @line_width
      @y += @line_width / 2
    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
    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)
      ccode = getCellCode(w, h, '', cborder, 1, '', fill, '', 0, false)
      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)
    # design a cell around the text
    ccode = getCellCode(w, h, '', border, 1, '', fill, '', 0, true)
    if (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
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)


14395
14396
14397
14398
14399
14400
14401
14402
14403
14404
14405
# File 'lib/rbpdf.rb', line 14395

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()



1488
1489
1490
1491
# File 'lib/rbpdf.rb', line 1488

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()



5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
# File 'lib/rbpdf.rb', line 5411

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()



2159
2160
2161
2162
# File 'lib/rbpdf.rb', line 2159

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()



9886
9887
9888
# File 'lib/rbpdf.rb', line 9886

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


10130
10131
10132
# File 'lib/rbpdf.rb', line 10130

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


10152
10153
10154
10155
10156
10157
10158
10159
10160
10161
10162
10163
10164
10165
10166
10167
10168
10169
10170
10171
# File 'lib/rbpdf.rb', line 10152

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()



8037
8038
8039
# File 'lib/rbpdf.rb', line 8037

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)


8661
8662
8663
8664
8665
8666
8667
8668
8669
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
8732
8733
# File 'lib/rbpdf.rb', line 8661

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)


8642
8643
8644
# File 'lib/rbpdf.rb', line 8642

def PolyLine(p, style='', line_style=nil, fill_color=nil)
  Polygon(p, style, line_style, fill_color, false)
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()



8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
# File 'lib/rbpdf.rb', line 8400

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)


8763
8764
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779
# File 'lib/rbpdf.rb', line 8763

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.

@param string :txt

input string

@return string

without SHY characters.

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


3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
# File 'lib/rbpdf.rb', line 3308

def removeSHY(txt='')
  txt = txt.dup
  # 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)

  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)


14430
14431
14432
14433
14434
14435
14436
# File 'lib/rbpdf.rb', line 14430

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)


14362
14363
14364
14365
14366
14367
14368
14369
14370
14371
14372
14373
14374
14375
14376
14377
14378
14379
14380
14381
14382
14383
14384
14385
# File 'lib/rbpdf.rb', line 14362

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()



8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
# File 'lib/rbpdf.rb', line 8130

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)


8855
8856
8857
# File 'lib/rbpdf.rb', line 8855

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)


8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911
8912
8913
8914
8915
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925
8926
8927
8928
8929
# File 'lib/rbpdf.rb', line 8875

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 * (::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)


10003
10004
10005
10006
# File 'lib/rbpdf.rb', line 10003

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()



1435
1436
1437
1438
# File 'lib/rbpdf.rb', line 1435

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()



1306
1307
1308
1309
1310
1311
# File 'lib/rbpdf.rb', line 1306

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)


13171
13172
13173
13174
13175
13176
13177
13178
13179
# File 'lib/rbpdf.rb', line 13171

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)


10029
10030
10031
# File 'lib/rbpdf.rb', line 10029

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()



1293
1294
1295
# File 'lib/rbpdf.rb', line 1293

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


1392
1393
1394
1395
1396
1397
1398
1399
# File 'lib/rbpdf.rb', line 1392

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()



1461
1462
1463
1464
# File 'lib/rbpdf.rb', line 1461

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


2910
2911
2912
# File 'lib/rbpdf.rb', line 2910

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


1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
# File 'lib/rbpdf.rb', line 1341

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?(String))
    @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()



2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
# File 'lib/rbpdf.rb', line 2218

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()



2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
# File 'lib/rbpdf.rb', line 2194

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()



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
2322
2323
2324
2325
2326
2327
2328
2329
# File 'lib/rbpdf.rb', line 2290

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()



2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
# File 'lib/rbpdf.rb', line 2266

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 = '') ⇒ 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.

@access public
@since 1.0
@see

AddFont(), SetFontSize()



2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
# File 'lib/rbpdf.rb', line 2817

def SetFont(family, style='', size=0, fontfile='')
  # 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)
  @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()



2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
# File 'lib/rbpdf.rb', line 2838

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
  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
  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

#setFooterFont(font) ⇒ Object Also known as: set_footer_font

Set footer font.

@param array :font

font

@access public
@since 1.1


7862
7863
7864
# File 'lib/rbpdf.rb', line 7862

def setFooterFont(font)
  @footer_font = font;
end

#SetFooterFont(font) ⇒ Object



7867
7868
7869
7870
# File 'lib/rbpdf.rb', line 7867

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


1866
1867
1868
# File 'lib/rbpdf.rb', line 1866

def setFooterMargin(fm=10)
  @footer_margin = fm;
end

#SetFooterMargin(fm = 10) ⇒ Object



1871
1872
1873
1874
# File 'lib/rbpdf.rb', line 1871

def SetFooterMargin(fm=10)
  warn "[DEPRECATION] 'SetFooterMargin' is deprecated. Please use 'set_footer_margin' instead."
  setFooterMargin(fm)
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


1800
1801
1802
1803
1804
1805
# File 'lib/rbpdf.rb', line 1800

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



1808
1809
1810
1811
# File 'lib/rbpdf.rb', line 1808

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


7835
7836
7837
# File 'lib/rbpdf.rb', line 7835

def setHeaderFont(font)
  @header_font = font;
end

#SetHeaderFont(font) ⇒ Object



7840
7841
7842
7843
# File 'lib/rbpdf.rb', line 7840

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


1839
1840
1841
# File 'lib/rbpdf.rb', line 1839

def setHeaderMargin(hm=10)
  @header_margin = hm;
end

#SetHeaderMargin(hm = 10) ⇒ Object



1844
1845
1846
1847
# File 'lib/rbpdf.rb', line 1844

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)


13213
13214
13215
# File 'lib/rbpdf.rb', line 13213

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


1049
1050
1051
# File 'lib/rbpdf.rb', line 1049

def setImageScale(scale)
  @img_scale = scale;
end

#SetImageScale(scale) ⇒ Object



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

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)


10015
10016
10017
10018
10019
10020
# File 'lib/rbpdf.rb', line 10015

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()



1448
1449
1450
1451
# File 'lib/rbpdf.rb', line 1448

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


7888
7889
7890
7891
7892
7893
7894
7895
# File 'lib/rbpdf.rb', line 7888

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



7898
7899
7900
7901
# File 'lib/rbpdf.rb', line 7898

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


1026
1027
1028
# File 'lib/rbpdf.rb', line 1026

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()



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

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)


8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
# File 'lib/rbpdf.rb', line 8221

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 =~ /^.+,/
        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()



8186
8187
8188
8189
8190
8191
8192
8193
# File 'lib/rbpdf.rb', line 8186

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()



2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
# File 'lib/rbpdf.rb', line 2938

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()



1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
# File 'lib/rbpdf.rb', line 1223

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()



1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
# File 'lib/rbpdf.rb', line 1538

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) ⇒ 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

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


805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
# File 'lib/rbpdf.rb', line 805

def setPageBoxes(page, type, llx, lly, urx, ury)
  if @pagedim[@page].nil?
    # initialize array
    @pagedim[@page] = {}
  end
  pageboxes = ['MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox']
  unless pageboxes.include?(type)
    return
  end
  @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)


1767
1768
1769
1770
# File 'lib/rbpdf.rb', line 1767

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)


855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
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
# File 'lib/rbpdf.rb', line 855

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 / @k), (@fh_pt / @k))
  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'])
  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'])
  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'])
  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'])
  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)


530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
# File 'lib/rbpdf.rb', line 530

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)


10050
10051
10052
# File 'lib/rbpdf.rb', line 10050

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


1907
1908
1909
# File 'lib/rbpdf.rb', line 1907

def setPrintFooter(val=true)
  @print_footer = val;
end

#SetPrintFooter(val = true) ⇒ Object



1912
1913
1914
1915
# File 'lib/rbpdf.rb', line 1912

def SetPrintFooter(val=true)
  warn "[DEPRECATION] 'SetPrintFooter' is deprecated. Please use 'set_print_footer' instead."
  setPrintFooter(val)
end

#SetPrintHeader(val = true) ⇒ Object



1897
1898
1899
1900
# File 'lib/rbpdf.rb', line 1897

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


1892
1893
1894
# File 'lib/rbpdf.rb', line 1892

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()



1278
1279
1280
1281
1282
1283
# File 'lib/rbpdf.rb', line 1278

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)


952
953
954
955
956
957
958
# File 'lib/rbpdf.rb', line 952

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()



1422
1423
1424
1425
# File 'lib/rbpdf.rb', line 1422

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)


978
979
980
981
982
983
984
985
986
987
# File 'lib/rbpdf.rb', line 978

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()



2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
# File 'lib/rbpdf.rb', line 2380

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()



2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
# File 'lib/rbpdf.rb', line 2356

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)


14448
14449
14450
14451
14452
14453
14454
14455
14456
14457
14458
14459
14460
14461
14462
14463
14464
14465
14466
14467
14468
14469
14470
14471
14472
14473
14474
14475
14476
14477
14478
14479
14480
14481
14482
14483
14484
14485
14486
14487
14488
14489
14490
14491
14492
14493
14494
14495
# File 'lib/rbpdf.rb', line 14448

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()



1409
1410
1411
1412
# File 'lib/rbpdf.rb', line 1409

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()



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

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)


10110
10111
10112
# File 'lib/rbpdf.rb', line 10110

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)


9914
9915
9916
9917
9918
9919
9920
9921
9922
9923
9924
9925
9926
9927
9928
9929
9930
9931
9932
9933
# File 'lib/rbpdf.rb', line 9914

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()



5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
# File 'lib/rbpdf.rb', line 5327

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()



5388
5389
5390
5391
# File 'lib/rbpdf.rb', line 5388

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()



5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
# File 'lib/rbpdf.rb', line 5355

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)


8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
# File 'lib/rbpdf.rb', line 8810

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()



1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
# File 'lib/rbpdf.rb', line 1722

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)


9734
9735
9736
9737
9738
9739
# File 'lib/rbpdf.rb', line 9734

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)


14322
14323
14324
14325
14326
14327
14328
14329
14330
14331
14332
# File 'lib/rbpdf.rb', line 14322

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()



8095
8096
8097
8098
8099
8100
# File 'lib/rbpdf.rb', line 8095

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()



8111
8112
8113
8114
8115
8116
8117
8118
# File 'lib/rbpdf.rb', line 8111

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()



3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
# File 'lib/rbpdf.rb', line 3137

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

#unhtmlentities(string) ⇒ Object

Reverse function for htmlentities. Convert entities in UTF-8.

@param :text_to_convert

Text to convert.

@return string

converted

@access public


8050
8051
8052
8053
8054
8055
8056
# File 'lib/rbpdf.rb', line 8050

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)


4609
4610
4611
4612
4613
4614
4615
# File 'lib/rbpdf.rb', line 4609

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)


4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
# File 'lib/rbpdf.rb', line 4642

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)


4625
4626
4627
4628
4629
4630
4631
# File 'lib/rbpdf.rb', line 4625

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


4591
4592
4593
4594
4595
4596
4597
# File 'lib/rbpdf.rb', line 4591

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


4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
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
# File 'lib/rbpdf.rb', line 4231

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
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


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
11346
11347
11348
11349
11350
11351
11352
11353
11354
11355
11356
11357
11358
11359
11360
11361
11362
11363
11364
11365
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377
11378
11379
11380
11381
11382
11383
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409
11410
11411
11412
11413
11414
11415
11416
11417
11418
11419
11420
11421
11422
11423
11424
11425
11426
11427
11428
11429
11430
11431
11432
11433
11434
11435
11436
11437
11438
11439
11440
11441
11442
11443
11444
11445
11446
11447
11448
11449
11450
11451
11452
11453
11454
11455
11456
11457
11458
11459
11460
11461
11462
11463
11464
11465
11466
11467
11468
11469
11470
11471
11472
11473
11474
11475
11476
11477
11478
11479
11480
11481
11482
11483
11484
11485
11486
11487
11488
11489
11490
11491
11492
11493
11494
11495
11496
11497
11498
11499
11500
11501
11502
11503
11504
11505
11506
11507
11508
11509
11510
11511
11512
11513
11514
11515
11516
11517
11518
11519
11520
11521
11522
11523
11524
11525
11526
11527
11528
11529
11530
11531
11532
11533
11534
11535
11536
11537
11538
11539
11540
11541
11542
11543
11544
11545
11546
11547
11548
11549
11550
11551
11552
11553
11554
11555
11556
11557
11558
11559
11560
11561
11562
11563
11564
11565
11566
11567
11568
11569
11570
11571
11572
11573
11574
11575
11576
11577
11578
11579
11580
11581
11582
11583
11584
11585
11586
11587
11588
11589
11590
11591
11592
11593
11594
11595
11596
11597
11598
11599
11600
11601
11602
11603
11604
11605
11606
11607
11608
11609
11610
11611
11612
11613
11614
11615
11616
11617
11618
11619
11620
11621
11622
11623
11624
11625
11626
11627
11628
11629
11630
11631
11632
11633
11634
11635
11636
11637
11638
11639
11640
11641
11642
11643
11644
11645
11646
11647
11648
11649
11650
11651
11652
11653
11654
11655
11656
11657
11658
11659
11660
11661
11662
11663
11664
11665
11666
11667
11668
11669
11670
11671
11672
11673
11674
11675
11676
11677
11678
11679
11680
11681
11682
11683
11684
11685
11686
11687
11688
11689
11690
11691
11692
11693
11694
11695
11696
11697
11698
11699
11700
11701
11702
11703
11704
11705
11706
11707
11708
11709
11710
11711
11712
11713
11714
11715
11716
11717
11718
11719
11720
11721
11722
11723
11724
11725
11726
11727
11728
11729
11730
11731
11732
11733
11734
11735
11736
11737
11738
11739
11740
11741
11742
11743
11744
11745
11746
11747
11748
11749
11750
11751
11752
11753
11754
11755
11756
11757
11758
11759
11760
11761
11762
11763
11764
11765
11766
11767
11768
11769
11770
11771
11772
11773
11774
11775
11776
11777
11778
11779
11780
11781
11782
11783
11784
11785
11786
11787
11788
11789
11790
11791
11792
11793
11794
11795
11796
11797
11798
11799
11800
11801
11802
11803
11804
11805
11806
11807
11808
11809
11810
11811
11812
11813
11814
11815
11816
11817
11818
11819
11820
11821
11822
11823
11824
11825
11826
11827
11828
11829
11830
11831
11832
11833
11834
11835
11836
11837
11838
11839
11840
11841
11842
11843
11844
11845
11846
11847
11848
11849
11850
11851
11852
11853
11854
11855
11856
11857
11858
11859
11860
11861
11862
11863
11864
11865
11866
11867
11868
11869
11870
11871
11872
11873
11874
11875
11876
11877
11878
11879
11880
11881
11882
11883
11884
11885
11886
11887
11888
11889
11890
11891
11892
11893
11894
11895
11896
11897
11898
11899
11900
11901
11902
11903
11904
11905
11906
11907
11908
11909
11910
11911
11912
11913
11914
11915
11916
11917
11918
11919
11920
11921
11922
11923
11924
11925
11926
11927
11928
11929
11930
11931
11932
11933
11934
11935
11936
11937
11938
11939
11940
11941
11942
11943
11944
11945
11946
11947
11948
11949
11950
11951
11952
11953
11954
11955
11956
11957
11958
11959
11960
11961
11962
11963
11964
11965
11966
11967
11968
11969
11970
11971
11972
11973
11974
11975
11976
11977
11978
11979
11980
11981
11982
11983
11984
11985
11986
11987
11988
11989
11990
11991
11992
11993
11994
11995
11996
11997
11998
11999
12000
12001
12002
12003
12004
12005
12006
12007
12008
12009
12010
12011
12012
12013
12014
12015
12016
12017
12018
12019
12020
12021
12022
12023
12024
12025
12026
12027
12028
12029
12030
12031
12032
12033
12034
12035
12036
12037
12038
12039
12040
12041
12042
12043
12044
12045
12046
12047
12048
12049
12050
12051
12052
12053
12054
12055
12056
12057
12058
12059
12060
12061
12062
12063
12064
12065
12066
12067
12068
12069
12070
12071
12072
12073
12074
12075
12076
12077
12078
12079
12080
12081
12082
12083
12084
12085
12086
12087
12088
12089
12090
12091
12092
12093
12094
12095
12096
12097
12098
12099
12100
12101
12102
12103
12104
12105
12106
12107
12108
12109
12110
12111
12112
12113
12114
12115
12116
12117
12118
12119
12120
12121
12122
12123
12124
12125
12126
12127
12128
12129
12130
12131
12132
12133
12134
12135
12136
12137
12138
12139
12140
12141
12142
12143
12144
12145
12146
12147
12148
12149
12150
12151
12152
12153
12154
12155
12156
12157
12158
12159
12160
12161
12162
12163
12164
12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
12177
12178
12179
12180
12181
12182
12183
12184
12185
12186
12187
12188
12189
12190
12191
12192
12193
12194
12195
12196
12197
12198
12199
12200
12201
12202
12203
12204
12205
12206
12207
12208
12209
12210
12211
12212
12213
12214
12215
12216
12217
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233
12234
12235
12236
12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
12247
12248
12249
12250
12251
12252
12253
12254
12255
12256
12257
12258
12259
12260
12261
12262
12263
12264
12265
12266
12267
12268
12269
12270
12271
12272
12273
12274
12275
12276
12277
12278
12279
12280
12281
12282
12283
12284
12285
12286
12287
12288
12289
12290
12291
12292
12293
12294
12295
12296
12297
12298
12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326
12327
12328
12329
12330
12331
12332
12333
12334
12335
12336
12337
12338
12339
12340
12341
12342
12343
12344
12345
12346
12347
12348
12349
12350
12351
12352
12353
12354
12355
12356
12357
12358
12359
12360
12361
12362
12363
12364
12365
12366
12367
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377
12378
12379
12380
12381
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401
12402
12403
12404
12405
12406
12407
12408
12409
12410
12411
12412
12413
12414
12415
12416
12417
12418
12419
12420
12421
12422
12423
12424
12425
12426
12427
12428
12429
12430
12431
12432
12433
12434
12435
12436
12437
12438
12439
12440
12441
12442
12443
# File 'lib/rbpdf.rb', line 11305

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
  @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
        # print table header (thead)
        writeHTML(@thead, false, false, false, false, '')
        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]['attribute']['height'].nil? and (dom[key]['attribute']['height'].to_i > 0)
        # get image height
        imgh = getHTMLUnitToUnits(dom[key]['attribute']['height'], @lasth, 'px')
        # check for automatic line break
        autolinebreak = false
        if dom[key]['attribute']['width'] and (dom[key]['attribute']['width'].to_i > 0)
          imgw = getHTMLUnitToUnits(dom[key]['attribute']['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  - 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
              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)
            else
              t_x = (mdiff / 2)
            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
            # 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
                # 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)
      @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']
      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 (@nested_table == true) 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
          if !dom[(dom[trid]['parent'])]['attribute']['cellpadding'].nil?
            currentcmargin = getHTMLUnitToUnits(dom[(dom[trid]['parent'])]['attribute']['cellpadding'], 1, 'px')
          else
            currentcmargin = 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)
          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)
        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
          minstartliney = [@y, minstartliney].min
          maxbottomliney = [@y + pfontsize * @cell_height_ratio / @k, maxbottomliney].max
        end
      end
      # text
      @htmlvspace = 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 + 0.chr
          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)
        else
          t_x = (mdiff / 2)
        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
  dom = nil
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()



11280
11281
11282
11283
11284
11285
# File 'lib/rbpdf.rb', line 11280

def writeHTMLCell(w, h, x, y, html='', border=0, ln=0, fill=0, reseth=true, align='', autopadding=true)
  @nested_table = true
  rtn = MultiCell(w, h, html, border, align, fill, ln, x, y, reseth, 0, true, autopadding, 0)
  @nested_table = false
  return rtn
end