Class: RBPDF

Inherits:
Object
  • Object
show all
Includes:
ActionView::Helpers, Html_colors, Rbpdf, Unicode_data
Defined in:
lib/rbpdf.rb,
lib/rbpdf_encode_ok.rb,
lib/rbpdf_encode_ok2.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



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
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
# File 'lib/rbpdf.rb', line 252

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

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

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

  @@k_path_fonts = RBPDFFontDescriptor.getfontpath

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

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

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

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

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

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

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

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

  # bookmark
  @outlines ||= []

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

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

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

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

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

  @numfonts ||= 0
  @fontkeys ||= []
  @font_obj_ids ||= {}
  @pageopen ||= []
  @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

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

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

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

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

  #Some checks
  dochecks();

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

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

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

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

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

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

  # set default JPEG quality
  @jpeg_quality ||= 75

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

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

Instance Attribute Details

#barcodeObject

Returns the value of attribute barcode.



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

def barcode
  @barcode
end

#bufferObject

Returns the value of attribute buffer.



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

def buffer
  @buffer
end

#cache_file_lengthObject

Returns the value of attribute cache_file_length.



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

def cache_file_length
  @cache_file_length
end

#color_flagObject

Returns the value of attribute color_flag.



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

def color_flag
  @color_flag
end

#default_fontObject

Returns the value of attribute default_font.



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

def default_font
  @default_font
end

#diffsObject

Returns the value of attribute diffs.



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

def diffs
  @diffs
end

#diskcacheObject

Returns the value of attribute diskcache.



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

def diskcache
  @diskcache
end

#draw_colorObject

Returns the value of attribute draw_color.



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

def draw_color
  @draw_color
end

#encodingObject

Returns the value of attribute encoding.



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

def encoding
  @encoding
end

#fill_colorObject

Returns the value of attribute fill_color.



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

def fill_color
  @fill_color
end

#font_familyObject

Returns the value of attribute font_family.



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

def font_family
  @font_family
end

#font_filesObject

Returns the value of attribute font_files.



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

def font_files
  @font_files
end

#font_size_ptObject

Returns the value of attribute font_size_pt.



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

def font_size_pt
  @font_size_pt
end

#font_styleObject

Returns the value of attribute font_style.



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

def font_style
  @font_style
end

#fontsObject

Returns the value of attribute fonts.



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

def fonts
  @fonts
end

#header_logoObject

Returns the value of attribute header_logo.



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

def 
  @header_logo
end

#header_logo_widthObject

Returns the value of attribute header_logo_width.



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

def header_logo_width
  @header_logo_width
end

#header_stringObject

Returns the value of attribute header_string.



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

def header_string
  @header_string
end

#header_titleObject

Returns the value of attribute header_title.



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

def header_title
  @header_title
end

#header_widthObject

Returns the value of attribute header_width.



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

def header_width
  @header_width
end

#imagesObject

Returns the value of attribute images.



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

def images
  @images
end

#img_scaleObject

Returns the value of attribute img_scale.



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

def img_scale
  @img_scale
end

Returns the value of attribute in_footer.



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

def in_footer
  @in_footer
end

#is_unicodeObject

Returns the value of attribute is_unicode.



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

def is_unicode
  @is_unicode
end

#lasthObject

Returns the value of attribute lasth.



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

def lasth
  @lasth
end

Returns the value of attribute links.



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

def links
  @links
end

#lispacerObject

Returns the value of attribute lispacer.



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

def lispacer
  @lispacer
end

#listcountObject

Returns the value of attribute listcount.



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

def listcount
  @listcount
end

#listorderedObject

Returns the value of attribute listordered.



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

def listordered
  @listordered
end

#nObject

Returns the value of attribute n.



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

def n
  @n
end

#offsetsObject

Returns the value of attribute offsets.



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

def offsets
  @offsets
end

#pageObject

Returns the value of attribute page.



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

def page
  @page
end

#pagesObject

Returns the value of attribute pages.



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

def pages
  @pages
end

#pdf_versionObject

Returns the value of attribute pdf_version.



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

def pdf_version
  @pdf_version
end

#prev_pagesObject

Returns the value of attribute prev_pages.



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

def prev_pages
  @prev_pages
end

Returns the value of attribute print_footer.



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

def print_footer
  @print_footer
end

Returns the value of attribute print_header.



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

def print_header
  @print_header
end

#stateObject

Returns the value of attribute state.



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

def state
  @state
end

#text_colorObject

Returns the value of attribute text_color.



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

def text_color
  @text_color
end

#underlineObject

Returns the value of attribute underline.



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

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



3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
# File 'lib/rbpdf.rb', line 3222

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

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

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

Example

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

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

@param string :style

Font style. Possible values are (case insensitive):

  • empty string: regular (default)

  • B: bold

  • I: italic

  • BI or IB: bold italic

@param string :fontfile

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

@return array

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

@param boolean :subset

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

@access public
@since 1.5
@see

SetFont()



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
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
# File 'lib/rbpdf.rb', line 2628

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Adds HTML anchor and remembers it’s position

@param string :anchor

html anchor id

@access public


8459
8460
8461
# File 'lib/rbpdf.rb', line 8459

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

Output anchor link.

@param string :url

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

@param string :name

link name

@param int :fill

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

@param boolean :firstline

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

@param array :color

array of RGB text color

@param string :style

font style (U, D, B, I)

@param boolean :firstblock

if true the string is the starting of a line.

@return

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

@access public


8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
8437
8438
8439
8440
8441
8442
8443
8444
8445
8446
8447
8448
8449
8450
8451
# File 'lib/rbpdf.rb', line 8424

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

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

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

@param int :page

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

@param string :toc_name

name to use for TOC bookmark.

@param array :templates

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

@parma boolean :correct_align

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

@access public
@author

Nicola Asuni

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

addTOCPage(), endTOCPage(), addTOC()



14834
14835
14836
14837
14838
14839
14840
14841
14842
14843
14844
14845
14846
14847
14848
14849
14850
14851
14852
14853
14854
14855
14856
14857
14858
14859
14860
14861
14862
14863
14864
14865
14866
14867
14868
14869
14870
14871
14872
14873
14874
14875
14876
14877
14878
14879
14880
14881
14882
14883
14884
14885
14886
14887
14888
14889
14890
14891
14892
14893
14894
14895
14896
14897
14898
14899
14900
14901
14902
14903
14904
14905
14906
14907
14908
14909
14910
14911
14912
14913
14914
14915
14916
14917
14918
14919
14920
14921
14922
# File 'lib/rbpdf.rb', line 14834

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



2984
2985
2986
2987
2988
2989
# File 'lib/rbpdf.rb', line 2984

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



1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
# File 'lib/rbpdf.rb', line 1702

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



2220
2221
2222
2223
2224
2225
# File 'lib/rbpdf.rb', line 2220

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



14683
14684
14685
14686
14687
14688
14689
14690
14691
14692
14693
14694
14695
14696
14697
14698
14699
14700
14701
14702
14703
14704
14705
14706
14707
14708
14709
14710
14711
14712
14713
14714
14715
14716
14717
14718
14719
14720
14721
14722
14723
14724
14725
14726
14727
14728
14729
14730
14731
14732
14733
14734
14735
14736
14737
14738
14739
14740
14741
14742
14743
14744
14745
14746
14747
14748
14749
14750
14751
14752
14753
14754
14755
14756
14757
14758
14759
14760
14761
14762
14763
14764
14765
14766
14767
14768
14769
14770
14771
14772
14773
14774
14775
14776
14777
14778
14779
14780
14781
14782
14783
14784
14785
14786
14787
14788
14789
14790
14791
14792
14793
14794
14795
14796
14797
14798
14799
14800
14801
14802
14803
14804
14805
14806
14807
14808
14809
14810
14811
14812
14813
14814
14815
14816
14817
14818
# File 'lib/rbpdf.rb', line 14683

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



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

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



10269
10270
10271
# File 'lib/rbpdf.rb', line 10269

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



10298
10299
10300
10301
# File 'lib/rbpdf.rb', line 10298

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)


3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
# File 'lib/rbpdf.rb', line 3043

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)


9460
9461
9462
9463
9464
9465
9466
9467
9468
9469
9470
9471
9472
9473
9474
9475
9476
9477
9478
9479
9480
9481
9482
9483
9484
9485
9486
9487
9488
9489
9490
9491
9492
9493
9494
9495
9496
9497
9498
9499
9500
9501
# File 'lib/rbpdf.rb', line 9460

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)


10155
10156
10157
10158
10159
10160
10161
10162
10163
10164
10165
10166
10167
10168
10169
10170
10171
10172
10173
10174
10175
# File 'lib/rbpdf.rb', line 10155

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)


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

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



3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
# File 'lib/rbpdf.rb', line 3379

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)


9138
9139
9140
# File 'lib/rbpdf.rb', line 9138

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



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

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

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

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


14948
14949
14950
14951
14952
14953
14954
14955
14956
14957
14958
14959
14960
# File 'lib/rbpdf.rb', line 14948

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


8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
8523
8524
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534
8535
8536
8537
8538
8539
8540
8541
8542
# File 'lib/rbpdf.rb', line 8481

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)


8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
# File 'lib/rbpdf.rb', line 8972

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)


14537
14538
14539
14540
14541
14542
14543
14544
14545
14546
14547
14548
14549
14550
14551
14552
14553
14554
14555
14556
14557
14558
14559
14560
14561
14562
14563
14564
14565
14566
14567
14568
14569
14570
14571
14572
14573
14574
14575
14576
14577
14578
14579
14580
14581
14582
14583
14584
14585
14586
14587
14588
14589
14590
14591
14592
14593
14594
14595
14596
14597
14598
14599
14600
14601
14602
14603
14604
14605
14606
14607
14608
14609
14610
14611
14612
14613
14614
14615
14616
14617
14618
14619
14620
14621
14622
14623
14624
14625
14626
14627
14628
14629
14630
14631
14632
14633
14634
14635
14636
14637
14638
14639
14640
14641
14642
14643
14644
14645
14646
14647
14648
14649
14650
14651
14652
14653
14654
14655
14656
14657
14658
14659
14660
14661
14662
14663
14664
14665
14666
# File 'lib/rbpdf.rb', line 14537

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


5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
# File 'lib/rbpdf.rb', line 5586

def destroy(destroyall=false, preserve_objcopy=false)
  if destroyall and @diskcache and !preserve_objcopy and !empty_string(@buffer.path)
    # remove buffer file from cache
    File.delete(@buffer.path)
  end
  self.instance_variables.each { |val|
    if destroyall or ((val != '@internal_encoding') and (val != '@state') and (val != '@bufferlen') and (val != '@buffer') and (val != '@diskcache') and (val != '@sign') and (val != '@signature_data') and (val != '@signature_max_length') and (val != '@byterange_string'))
      if (!preserve_objcopy or (val.to_s != '@objcopy')) and !val.nil?
        eval("#{val} = nil")
      end
    end
  }
end

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

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

@param float :x0

Abscissa of center point.

@param float :y0

Ordinate of center point.

@param float :rx

Horizontal radius.

@param float :ry

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

@param float :angle

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

@param float :astart

Angle start of draw line. Default value: 0.

@param float :afinish

Angle finish of draw line. Default value: 360.

@param string :style

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

@param array :line_style

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

@param array :fill_color

Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K). Default value: default color (empty array).

@param integer :nc

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

@author

Nicola Asuni

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


9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
# File 'lib/rbpdf.rb', line 9004

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)


15025
15026
15027
# File 'lib/rbpdf.rb', line 15025

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



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

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



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

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


1513
1514
1515
1516
1517
# File 'lib/rbpdf.rb', line 1513

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


2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
# File 'lib/rbpdf.rb', line 2034

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

#GetAbsXObject Also known as: get_abs_x

Returns the absolute X value of current position.

@return float
@access public
@since 1.2
@see

SetY(), GetX(), SetX()



5350
5351
5352
# File 'lib/rbpdf.rb', line 5350

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



10282
10283
10284
10285
10286
10287
# File 'lib/rbpdf.rb', line 10282

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



10312
10313
10314
10315
10316
10317
# File 'lib/rbpdf.rb', line 10312

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)


2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
# File 'lib/rbpdf.rb', line 2520

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



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

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



1230
1231
1232
1233
# File 'lib/rbpdf.rb', line 1230

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)


10558
10559
10560
# File 'lib/rbpdf.rb', line 10558

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)


2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
# File 'lib/rbpdf.rb', line 2557

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)


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

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

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

Return the font descent value

@param string :font

font name

@param string :style

font style

@param float :size

The size (in points)

@return int

font descent

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


2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
# File 'lib/rbpdf.rb', line 2929

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

#getFontFamilyObject Also known as: get_font_family

Returns the current font family name.

@return string

current font family name

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


10859
10860
10861
# File 'lib/rbpdf.rb', line 10859

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)


10837
10838
10839
# File 'lib/rbpdf.rb', line 10837

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)


10848
10849
10850
# File 'lib/rbpdf.rb', line 10848

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)


10870
10871
10872
# File 'lib/rbpdf.rb', line 10870

def getFontStyle()
  return @font_style
end

#getFontSubsettingObject Also known as: get_font_subsetting

Get Font Subsetting.

@return boolean
@access public


8316
8317
8318
# File 'lib/rbpdf.rb', line 8316

def getFontSubsetting()
  return @font_subsetting
end

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

Get Footer font.

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


8370
8371
8372
# File 'lib/rbpdf.rb', line 8370

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


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

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)


10326
10327
10328
# File 'lib/rbpdf.rb', line 10326

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



10337
10338
10339
# File 'lib/rbpdf.rb', line 10337

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)


1864
1865
1866
1867
1868
1869
1870
1871
# File 'lib/rbpdf.rb', line 1864

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)


8343
8344
8345
# File 'lib/rbpdf.rb', line 8343

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


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

def getHeaderMargin()
  return @header_margin
end

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

Outputs HTML anchor position

@param string :anchor

html anchor id

@return array
Page, Y

of anchor

@access public


8470
8471
8472
# File 'lib/rbpdf.rb', line 8470

def getHtmlAnchorPosition(anchor)
  @html_anchors[anchor]
end

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

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

@param string :htmlval

string containing values and unit

@param string :refsize

reference value in points

@param string :defaultunit

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

@param boolean :point

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

@return float

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

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


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

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

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

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

@param string :imgfile

image file name

@param hash :iminfo

array of image information returned by getimagesize() function.

@return string

image type

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


4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
# File 'lib/rbpdf.rb', line 4731

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


1963
1964
1965
# File 'lib/rbpdf.rb', line 1963

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


1973
1974
1975
# File 'lib/rbpdf.rb', line 1973

def getImageRBY()
  return @img_rb_y
end

#GetImageScaleObject



1110
1111
1112
1113
# File 'lib/rbpdf.rb', line 1110

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


1105
1106
1107
# File 'lib/rbpdf.rb', line 1105

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)


1076
1077
1078
# File 'lib/rbpdf.rb', line 1076

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



8718
8719
8720
# File 'lib/rbpdf.rb', line 8718

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)


10803
10804
10805
10806
10807
10808
10809
10810
10811
10812
10813
10814
# File 'lib/rbpdf.rb', line 10803

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)


2585
2586
2587
2588
2589
2590
# File 'lib/rbpdf.rb', line 2585

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


4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
# File 'lib/rbpdf.rb', line 4133

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

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

#getNumPagesObject Also known as: get_num_pages

Get the total number of insered pages.

@return int

number of pages

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

setPage(), getPage(), lastPage()



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

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)


10825
10826
10827
10828
# File 'lib/rbpdf.rb', line 10825

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



1639
1640
1641
# File 'lib/rbpdf.rb', line 1639

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)


1171
1172
1173
1174
1175
1176
# File 'lib/rbpdf.rb', line 1171

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)


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

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

#GetPageHeightObject



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

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


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

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)


10366
10367
10368
10369
10370
10371
# File 'lib/rbpdf.rb', line 10366

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)


598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
# File 'lib/rbpdf.rb', line 598

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



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

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


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

def getPageWidth()
  return @w;
end

#getPDFDataObject Also known as: get_pdf_data

Returns the PDF data.

@access public


8399
8400
8401
8402
8403
8404
# File 'lib/rbpdf.rb', line 8399

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

#GetPDFDataObject



8407
8408
8409
8410
# File 'lib/rbpdf.rb', line 8407

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

#getRTLObject Also known as: get_rtl

Return the RTL status

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


1006
1007
1008
# File 'lib/rbpdf.rb', line 1006

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


1242
1243
1244
# File 'lib/rbpdf.rb', line 1242

def getScaleFactor()
  return @k;
end

#GetScaleFactorObject



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

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


4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
# File 'lib/rbpdf.rb', line 4240

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

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

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

@param string :s

The string whose length is to be computed

@param string :fontname

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

@param string :fontstyle

Font style. Possible values are (case insensitive):

  • empty string: regular

  • B: bold

  • I: italic

  • U: underline

  • D: line trough

  • O: overline

or any combination. The default value is regular.

@param float :fontsize

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

@param boolean :getarray

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

@return mixed int

total string length or array of characted widths

@author

Nicola Asuni

@access public
@since 1.2


2495
2496
2497
# File 'lib/rbpdf.rb', line 2495

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



5334
5335
5336
5337
5338
5339
5340
# File 'lib/rbpdf.rb', line 5334

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



5362
5363
5364
# File 'lib/rbpdf.rb', line 5362

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


1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
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
2023
2024
2025
2026
# File 'lib/rbpdf.rb', line 1983

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


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
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
# File 'lib/rbpdf.rb', line 4809

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

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

    info = false
    if !resize
      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 true
        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.0
    elsif palign == 'R'
      ximg = @w - @r_margin - w
    else
      ximg = x - w
    end
    @img_rb_x = ximg
  else
    if palign == 'L'
      ximg = @l_margin
    elsif palign == 'C'
      ximg = (@w + @l_margin - @r_margin - w) / 2.0
    elsif palign == 'R'
      ximg = @w - @r_margin - w
    else
      ximg = x
    end
    @img_rb_x = ximg + w
  end
  if ismask or hidden
    # image is not displayed
    return info['i']
  end
  xkimg = ximg * @k
  out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q', w * @k, h * @k, xkimg, (@h - (y + h)) * @k, info['i']))

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

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

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

#image_alpha_mask(file) ⇒ Object



5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
# File 'lib/rbpdf.rb', line 5228

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)


13882
13883
13884
13885
13886
13887
13888
13889
13890
13891
13892
13893
13894
13895
13896
13897
13898
13899
13900
13901
13902
13903
13904
13905
13906
13907
13908
13909
13910
13911
13912
13913
13914
13915
13916
13917
13918
13919
13920
13921
13922
13923
13924
13925
13926
13927
13928
13929
13930
13931
13932
13933
13934
13935
13936
13937
# File 'lib/rbpdf.rb', line 13882

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)


1035
1036
1037
1038
1039
1040
1041
# File 'lib/rbpdf.rb', line 1035

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



1627
1628
1629
# File 'lib/rbpdf.rb', line 1627

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



8888
8889
8890
8891
8892
8893
8894
8895
# File 'lib/rbpdf.rb', line 8888

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



3025
3026
3027
# File 'lib/rbpdf.rb', line 3025

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



5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
# File 'lib/rbpdf.rb', line 5302

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



106
107
108
109
110
111
112
113
114
115
# File 'lib/rbpdf.rb', line 106

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

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

Move a page to a previous position.

@param int :frompage

number of the source page

@param int :topage

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

@return

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

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


14396
14397
14398
14399
14400
14401
14402
14403
14404
14405
14406
14407
14408
14409
14410
14411
14412
14413
14414
14415
14416
14417
14418
14419
14420
14421
14422
14423
14424
14425
14426
14427
14428
14429
14430
14431
14432
14433
14434
14435
14436
14437
14438
14439
14440
14441
14442
14443
14444
14445
14446
14447
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
14496
14497
14498
14499
14500
14501
14502
14503
14504
14505
14506
14507
14508
14509
14510
14511
14512
14513
14514
14515
14516
14517
14518
14519
14520
14521
14522
14523
14524
14525
14526
14527
# File 'lib/rbpdf.rb', line 14396

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



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
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
# File 'lib/rbpdf.rb', line 3845

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.0)
      @c_margin = @line_width / 2.0
    end
    # Add top space if needed
    if (@lasth - @font_size) < @line_width
      @y += @line_width / 2.0
    end
    # add top padding
    @y += @c_margin
  end

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

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

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

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


15003
15004
15005
15006
15007
15008
15009
15010
15011
15012
15013
# File 'lib/rbpdf.rb', line 15003

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



1527
1528
1529
1530
# File 'lib/rbpdf.rb', line 1527

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



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
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
# File 'lib/rbpdf.rb', line 5460

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



2202
2203
2204
2205
# File 'lib/rbpdf.rb', line 2202

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



10405
10406
10407
# File 'lib/rbpdf.rb', line 10405

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


10649
10650
10651
# File 'lib/rbpdf.rb', line 10649

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


10671
10672
10673
10674
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687
10688
10689
10690
# File 'lib/rbpdf.rb', line 10671

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



8552
8553
8554
# File 'lib/rbpdf.rb', line 8552

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)


9176
9177
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
9207
9208
9209
9210
9211
9212
9213
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
# File 'lib/rbpdf.rb', line 9176

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)


9157
9158
9159
# File 'lib/rbpdf.rb', line 9157

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



8915
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
8949
8950
# File 'lib/rbpdf.rb', line 8915

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)


9278
9279
9280
9281
9282
9283
9284
9285
9286
9287
9288
9289
9290
9291
9292
9293
9294
# File 'lib/rbpdf.rb', line 9278

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

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

Removes SHY characters from text. Unicode Data:

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

input string

@return string

without SHY characters.

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


3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
# File 'lib/rbpdf.rb', line 3313

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

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

Find position of last occurrence of a substring in a string

@param string :haystack

The string to search in.

@param string :needle

substring to search.

@param int :offset

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

@return

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

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


15038
15039
15040
15041
15042
15043
15044
# File 'lib/rbpdf.rb', line 15038

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)


14970
14971
14972
14973
14974
14975
14976
14977
14978
14979
14980
14981
14982
14983
14984
14985
14986
14987
14988
14989
14990
14991
14992
14993
# File 'lib/rbpdf.rb', line 14970

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



8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
# File 'lib/rbpdf.rb', line 8645

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)


9370
9371
9372
# File 'lib/rbpdf.rb', line 9370

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)


9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
9436
9437
9438
9439
9440
9441
9442
9443
9444
# File 'lib/rbpdf.rb', line 9390

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

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

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

@param float :alpha

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

@param string :bm

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

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


10522
10523
10524
10525
# File 'lib/rbpdf.rb', line 10522

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



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

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



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

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)


13768
13769
13770
13771
13772
13773
13774
13775
13776
# File 'lib/rbpdf.rb', line 13768

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)


10548
10549
10550
# File 'lib/rbpdf.rb', line 10548

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



1332
1333
1334
# File 'lib/rbpdf.rb', line 1332

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


1431
1432
1433
1434
1435
1436
1437
1438
# File 'lib/rbpdf.rb', line 1431

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



1500
1501
1502
1503
# File 'lib/rbpdf.rb', line 1500

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


2972
2973
2974
# File 'lib/rbpdf.rb', line 2972

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


1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
# File 'lib/rbpdf.rb', line 1380

def SetDisplayMode(zoom, layout='SinglePage', mode='UseNone')
  #Set display mode in viewer
  if (zoom == 'fullpage' or zoom == 'fullwidth' or zoom == 'real' or zoom == 'default' or zoom.is_a?(Numeric))
    @zoom_mode = zoom
  else
    Error('Incorrect zoom display mode: ' + zoom)
  end

  case layout
  when 'default', 'single', 'SinglePage'
    @layout_mode = 'SinglePage'
  when 'continuous', 'OneColumn'
    @layout_mode = 'OneColumn'
  when 'two', 'TwoColumnLeft'
    @layout_mode = 'TwoColumnLeft'
  when 'TwoColumnRight'
    @layout_mode = 'TwoColumnRight'
  when 'TwoPageLeft'
    @layout_mode = 'TwoPageLeft'
  when 'TwoPageRight'
    @layout_mode = 'TwoPageRight'
  else
    @layout_mode = 'SinglePage'
  end

  case mode
  when 'UseNone'
    @page_mode = 'UseNone'
  when 'UseOutlines'
    @page_mode = 'UseOutlines'
  when 'UseThumbs'
    @page_mode = 'UseThumbs'
  when 'FullScreen'
    @page_mode = 'FullScreen'
  when 'UseOC'
    @page_mode = 'UseOC'
  when ''
    @page_mode = 'UseAttachments'
  else
    @page_mode = 'UseNone'
  end
end

#SetDrawColor(col1 = 0, col2 = -1,, col3 = -1,, col4 = -1)) ⇒ Object Also known as: set_draw_color

Defines the color used for all drawing operations (lines, rectangles and cell borders). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.

@param int :col1

Gray level for single color, or Red color for RGB, or Cyan color for CMYK. Value between 0 and 255

@param int :col2

Green color for RGB, or Magenta color for CMYK. Value between 0 and 255

@param int :col3

Blue color for RGB, or Yellow color for CMYK. Value between 0 and 255

@param int :col4

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

@access public
@since 1.3
@see

SetFillColor(), SetTextColor(), Line(), Rect(), Cell(), MultiCell()



2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
# File 'lib/rbpdf.rb', line 2261

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



2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
# File 'lib/rbpdf.rb', line 2237

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



2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
# File 'lib/rbpdf.rb', line 2333

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



2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
# File 'lib/rbpdf.rb', line 2309

def SetFillColorArray(color)
  if !color.nil?
    color = color.values if color.is_a? Hash
    r = !color[0].nil? ? color[0] : -1
    g = !color[1].nil? ? color[1] : -1
    b = !color[2].nil? ? color[2] : -1
    k = !color[3].nil? ? color[3] : -1
    if r >= 0
      SetFillColor(r, g, b, k)
    end
  end
end

#SetFont(family, style = '', size = 0, fontfile = '', subset = nil) ⇒ Object Also known as: set_font

Sets the font used to print character strings. The font can be either a standard one or a font added via the AddFont() method. Standard fonts use Windows encoding cp1252 (Western Europe). The method can be called before the first page is created and the font is retained from page to page. If you just wish to change the current font size, it is simpler to call SetFontSize().

  • Note: for the standard fonts, the font metric files must be accessible. There are three possibilities for this:

    • They are in the current directory (the one where the running script lies)

    • They are in one of the directories defined by the include_path parameter

    • They are in the directory defined by the FPDF_FONTPATH constant

@param string :family

Family font. It can be either a name defined by AddFont() or one of the standard Type1 families (case insensitive):

  • times (Times-Roman)

  • timesb (Times-Bold)

  • timesi (Times-Italic)

  • timesbi (Times-BoldItalic)

  • helvetica (Helvetica)

  • helveticab (Helvetica-Bold)

  • helveticai (Helvetica-Oblique)

  • helveticabi (Helvetica-BoldOblique)

  • courier (Courier)

  • courierb (Courier-Bold)

  • courieri (Courier-Oblique)

  • courierbi (Courier-BoldOblique)

  • symbol (Symbol)

  • zapfdingbats (ZapfDingbats)

It is also possible to pass an empty string. In that case, the current family is retained.

@param string :style

Font style. Possible values are (case insensitive):

  • empty string: regular

  • B: bold

  • I: italic

  • U: underline

  • D: line trough

  • O: overline

or any combination. The default value is regular. Bold and italic styles do not apply to Symbol and ZapfDingbats basic fonts or other fonts when not defined.

@param float :size

Font size in points. The default value is the current size. If no size has been specified since the beginning of the document, the value taken is 12

@param string :fontfile

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

@param boolean :subset

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

@author Nicola Asuni
@access public
@since 1.0
@see

AddFont(), SetFontSize()



2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
# File 'lib/rbpdf.rb', line 2879

def SetFont(family, style='', size=0, fontfile='', subset=nil)
  # Select a font; size given in points
  if size == 0
    size = @font_size_pt
  end
  # try to add font (if not already added)
  fontdata =  AddFont(family, style, fontfile, subset)
  @font_family = fontdata['family']
  @font_style = fontdata['style']
  @current_font = getFontBuffer(fontdata['fontkey'])
  SetFontSize(size)
end

#SetFontSize(size) ⇒ Object Also known as: set_font_size

Defines the size of the current font.

@param float :size

The size (in points)

@access public
@since 1.0
@see

SetFont()



2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
# File 'lib/rbpdf.rb', line 2900

def SetFontSize(size)
  #Set font size in points
  @font_size_pt = size;
  @font_size = size.to_f / @k;
  if !@current_font['desc'].nil? and !@current_font['desc']['Ascent'].nil? and (@current_font['desc']['Ascent'] > 0)
    @font_ascent = @current_font['desc']['Ascent'] * @font_size / 1000.0
  else
    @font_ascent = 0.85 * @font_size
  end
  if !@current_font['desc'].nil? and !@current_font['desc']['Descent'].nil? and (@current_font['desc']['Descent'] <= 0)
    @font_descent = - @current_font['desc']['Descent'] * @font_size / 1000.0
  else
    @font_descent = 0.15 * @font_size
  end
  if (@page > 0) and !@current_font['i'].nil?
    out(sprintf('BT /F%d %.2f Tf ET ', @current_font['i'], @font_size_pt));
  end
end

#setFontSubsetting(subset) ⇒ Object Also known as: set_font_subsetting

Set Font Subsetting.

@param boolean :subset

subset of the font default setting.

@access public


8306
8307
8308
# File 'lib/rbpdf.rb', line 8306

def setFontSubsetting(subset)
  @font_subsetting = (subset == true ? true : false)
end

#SetFooterFont(font) ⇒ Object



8359
8360
8361
8362
# File 'lib/rbpdf.rb', line 8359

def SetFooterFont(font)
  warn "[DEPRECATION] 'SetFooterFont' is deprecated. Please use 'set_footer_font' instead."
  setFooterFont(font)
end

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

Set footer font.

@param array :font

font

@access public
@since 1.1


8354
8355
8356
# File 'lib/rbpdf.rb', line 8354

def setFooterFont(font)
  @footer_font = 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


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

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

#SetFooterMargin(fm = 10) ⇒ Object



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

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


1841
1842
1843
1844
1845
1846
# File 'lib/rbpdf.rb', line 1841

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



1849
1850
1851
1852
# File 'lib/rbpdf.rb', line 1849

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



8332
8333
8334
8335
# File 'lib/rbpdf.rb', line 8332

def SetHeaderFont(font)
  warn "[DEPRECATION] 'SetHeaderFont' is deprecated. Please use 'set_header_font' instead."
  setHeaderFont(font)
end

#setHeaderFont(font) ⇒ Object Also known as: set_header_font

Set header font.

@param array :font

font

@access public
@since 1.1


8327
8328
8329
# File 'lib/rbpdf.rb', line 8327

def setHeaderFont(font)
  @header_font = 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


1880
1881
1882
# File 'lib/rbpdf.rb', line 1880

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

#SetHeaderMargin(hm = 10) ⇒ Object



1885
1886
1887
1888
# File 'lib/rbpdf.rb', line 1885

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)


13810
13811
13812
# File 'lib/rbpdf.rb', line 13810

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


1088
1089
1090
# File 'lib/rbpdf.rb', line 1088

def setImageScale(scale)
  @img_scale = scale;
end

#SetImageScale(scale) ⇒ Object



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

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)


10534
10535
10536
10537
10538
10539
# File 'lib/rbpdf.rb', line 10534

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



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

def SetKeywords(keywords)
  #Keywords of document
  @keywords = keywords
end

#SetLanguageArray(language) ⇒ Object



8390
8391
8392
8393
# File 'lib/rbpdf.rb', line 8390

def SetLanguageArray(language)
  warn "[DEPRECATION] 'SetLanguageArray' is deprecated. Please use 'set_language_array' instead."
  setLanguageArray(language)
end

#setLanguageArray(language) ⇒ Object Also known as: set_language_array

Set language array.

@param array :language
@since 1.1


8380
8381
8382
8383
8384
8385
8386
8387
# File 'lib/rbpdf.rb', line 8380

def setLanguageArray(language)
  @l = language;
  if @l['a_meta_dir']
    @rtl = (@l['a_meta_dir'] == 'rtl') ? true : false
  else
    @rtl = false
  end
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


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

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



1285
1286
1287
1288
1289
1290
1291
# File 'lib/rbpdf.rb', line 1285

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)


8736
8737
8738
8739
8740
8741
8742
8743
8744
8745
8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
8763
8764
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
# File 'lib/rbpdf.rb', line 8736

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



8701
8702
8703
8704
8705
8706
8707
8708
# File 'lib/rbpdf.rb', line 8701

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



3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
# File 'lib/rbpdf.rb', line 3000

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



1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
# File 'lib/rbpdf.rb', line 1262

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



1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
# File 'lib/rbpdf.rb', line 1579

def setPage(pnum, resetmargins=false)
  if pnum == @page
    return
  end
  if (pnum > 0) and (pnum <= @numpages)
    @state = 2
    # save current graphic settings
    # gvars = getGraphicVars()
    oldpage = @page
    @page = pnum
    @w_pt = @pagedim[@page]['w']
    @h_pt = @pagedim[@page]['h']
    @w = @pagedim[@page]['wk']
    @h = @pagedim[@page]['hk']
    @t_margin = @pagedim[@page]['tm']
    @b_margin = @pagedim[@page]['bm']
    @original_l_margin = @pagedim[@page]['olm']
    @original_r_margin = @pagedim[@page]['orm']
    @auto_page_break = @pagedim[@page]['pb']
    @cur_orientation = @pagedim[@page]['or']
    SetAutoPageBreak(@auto_page_break, @b_margin)
    # restore graphic settings
    # setGraphicVars(gvars)
    if resetmargins
      @l_margin = @pagedim[@page]['olm']
      @r_margin = @pagedim[@page]['orm']
      SetY(@t_margin)
    else
      # account for booklet mode
      if @pagedim[@page]['olm'] != @pagedim[oldpage]['olm']
        deltam = @pagedim[@page]['olm'] - @pagedim[@page]['orm']
        @l_margin += deltam
        @r_margin -= deltam
      end
    end
  else
    Error('Wrong page number on setPage() function.')
  end
end

#setPageBoxes(page, type, llx, lly, urx, ury, points = false) ⇒ Object Also known as: set_page_boxes

Set page boundaries.

@param int :page

page number

@param string :type

valid values are:

  • ‘MediaBox’ : the boundaries of the physical medium on which the page shall be displayed or printed

  • ‘CropBox’ : the visible region of default user space

  • ‘BleedBox’ : the region to which the contents of the page shall be clipped when output in a production environment

  • ‘TrimBox’ : the intended dimensions of the finished page after trimming

  • ‘ArtBox’ : the page’s meaningful content (including potential white space).

@param float :llx

lower-left x coordinate in user units

@param float :lly

lower-left y coordinate in user units

@param float :urx

upper-right x coordinate in user units

@param float :ury

upper-right y coordinate in user units

@param boolean :points

if true uses user units as unit of measure, if false uses PDF points

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


842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
# File 'lib/rbpdf.rb', line 842

def setPageBoxes(page, type, llx, lly, urx, ury, points=false)
  pageboxes = ['MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox']
  unless pageboxes.include?(type)
    return
  end
  if @pagedim[page].nil?
    # initialize array
    @pagedim[page] = {}
  end

  points ? k = 1 : k = @k
  @pagedim[page][type] = {}
  @pagedim[page][type]['llx'] = llx * k
  @pagedim[page][type]['lly'] = lly * k
  @pagedim[page][type]['urx'] = urx * k
  @pagedim[page][type]['ury'] = ury * k
end

#setPageMarkObject Also known as: set_page_mark

Set start-writing mark on current page stream used to put borders and fills. Borders and fills are always created after content and inserted on the position marked by this method. This function must be called after calling Image() function for a background image. Background images must be always inserted before calling Multicell() or WriteHTMLCell() or WriteHTML() functions.

@access public
@since 4.0.016 (2008-07-30)


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

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)


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
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
# File 'lib/rbpdf.rb', line 894

def setPageOrientation(orientation, autopagebreak='', bottommargin='')
  if @pagedim[@page].nil? or @pagedim[@page]['MediaBox'].nil?
    # the boundaries of the physical medium on which the page shall be displayed or printed
    setPageBoxes(@page, 'MediaBox', 0, 0, @fw_pt, @fh_pt, true)
  end
  if @pagedim[@page]['CropBox'].nil?
    # the visible region of default user space
    setPageBoxes(@page, 'CropBox', @pagedim[@page]['MediaBox']['llx'], @pagedim[@page]['MediaBox']['lly'], @pagedim[@page]['MediaBox']['urx'], @pagedim[@page]['MediaBox']['ury'], true)
  end
  if @pagedim[@page]['BleedBox'].nil?
    # the region to which the contents of the page shall be clipped when output in a production environment
    setPageBoxes(@page, 'BleedBox', @pagedim[@page]['CropBox']['llx'], @pagedim[@page]['CropBox']['lly'], @pagedim[@page]['CropBox']['urx'], @pagedim[@page]['CropBox']['ury'], true)
  end
  if @pagedim[@page]['TrimBox'].nil?
    # the intended dimensions of the finished page after trimming
    setPageBoxes(@page, 'TrimBox', @pagedim[@page]['CropBox']['llx'], @pagedim[@page]['CropBox']['lly'], @pagedim[@page]['CropBox']['urx'], @pagedim[@page]['CropBox']['ury'], true)
  end
  if @pagedim[@page]['ArtBox'].nil?
    # the page's meaningful content (including potential white space)
    setPageBoxes(@page, 'ArtBox', @pagedim[@page]['CropBox']['llx'], @pagedim[@page]['CropBox']['lly'], @pagedim[@page]['CropBox']['urx'], @pagedim[@page]['CropBox']['ury'], true)
  end
  if @pagedim[@page]['Rotate'].nil?
    # The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90.
    @pagedim[@page]['Rotate'] = 0
  end
  if @pagedim[@page]['PZ'].nil?
    # The page's preferred zoom (magnification) factor
    @pagedim[@page]['PZ'] = 1
  end
  if @fw_pt > @fh_pt
    # landscape
    default_orientation = 'L'
  else
    # portrait
    default_orientation = 'P'
  end
  valid_orientations = ['P', 'L']
  if orientation.empty?
    orientation = default_orientation
  else
    orientation = orientation[0, 1].upcase
  end
  if valid_orientations.include?(orientation) and (orientation != default_orientation)
    @cur_orientation = orientation
    @w_pt = @fh_pt
    @h_pt = @fw_pt
  else
    @cur_orientation = default_orientation
    @w_pt = @fw_pt
    @h_pt = @fh_pt
  end
  if ((@pagedim[@page]['MediaBox']['urx'] - @h_pt).abs < @feps) and ((@pagedim[@page]['MediaBox']['ury'] - @w_pt).abs < @feps)
    # swap X and Y coordinates (change page orientatio
    swapPageBoxCoordinates(@page)
  end
  @w = @w_pt / @k
  @h = @h_pt / @k
  if empty_string(autopagebreak)
    unless @auto_page_break.nil?
      autopagebreak = @auto_page_break
    else
      autopagebreak = true
    end
  end
  if empty_string(bottommargin)
    unless @b_margin.nil?
      bottommargin = @b_margin
    else
      # default value = 2 cm
      bottommargin = 2 * 28.35 / @k
    end
  end
  SetAutoPageBreak(autopagebreak, bottommargin)
  # store page dimensions
  @pagedim[@page]['w'] = @w_pt
  @pagedim[@page]['h'] = @h_pt
  @pagedim[@page]['wk'] = @w
  @pagedim[@page]['hk'] = @h
  @pagedim[@page]['tm'] = @t_margin
  @pagedim[@page]['bm'] = bottommargin
  @pagedim[@page]['lm'] = @l_margin
  @pagedim[@page]['rm'] = @r_margin
  @pagedim[@page]['pb'] = autopagebreak
  @pagedim[@page]['or'] = @cur_orientation
  @pagedim[@page]['olm'] = @original_l_margin
  @pagedim[@page]['orm'] = @original_r_margin
  @pagedim[@page]
end

#setPageUnit(unit) ⇒ Object Also known as: set_page_unit

Set the units of measure for the document.

@param string :unit

User measure unit. Possible values are:

  • pt: point

  • mm: millimeter (default)

  • cm: centimeter

  • in: inch

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

@access public
@since 3.0.015 (2008-06-06)


566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
# File 'lib/rbpdf.rb', line 566

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)


10569
10570
10571
# File 'lib/rbpdf.rb', line 10569

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


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

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

#SetPrintFooter(val = true) ⇒ Object



1953
1954
1955
1956
# File 'lib/rbpdf.rb', line 1953

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

#SetPrintHeader(val = true) ⇒ Object



1938
1939
1940
1941
# File 'lib/rbpdf.rb', line 1938

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


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

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



1317
1318
1319
1320
1321
1322
# File 'lib/rbpdf.rb', line 1317

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)


991
992
993
994
995
996
997
# File 'lib/rbpdf.rb', line 991

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



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

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)


1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
# File 'lib/rbpdf.rb', line 1017

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



2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
# File 'lib/rbpdf.rb', line 2423

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



2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
# File 'lib/rbpdf.rb', line 2399

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)


15056
15057
15058
15059
15060
15061
15062
15063
15064
15065
15066
15067
15068
15069
15070
15071
15072
15073
15074
15075
15076
15077
15078
15079
15080
15081
15082
15083
15084
15085
15086
15087
15088
15089
15090
15091
15092
15093
15094
15095
15096
15097
15098
15099
15100
15101
15102
15103
# File 'lib/rbpdf.rb', line 15056

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



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

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



1301
1302
1303
1304
1305
1306
1307
# File 'lib/rbpdf.rb', line 1301

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)


10629
10630
10631
# File 'lib/rbpdf.rb', line 10629

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)


10433
10434
10435
10436
10437
10438
10439
10440
10441
10442
10443
10444
10445
10446
10447
10448
10449
10450
10451
10452
# File 'lib/rbpdf.rb', line 10433

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



5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
# File 'lib/rbpdf.rb', line 5376

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



5437
5438
5439
5440
# File 'lib/rbpdf.rb', line 5437

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



5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
# File 'lib/rbpdf.rb', line 5404

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)


9325
9326
9327
9328
9329
9330
9331
9332
9333
9334
9335
9336
9337
9338
9339
9340
9341
9342
9343
9344
9345
9346
9347
9348
9349
9350
9351
9352
9353
# File 'lib/rbpdf.rb', line 9325

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



1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
# File 'lib/rbpdf.rb', line 1763

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)


10253
10254
10255
10256
10257
10258
# File 'lib/rbpdf.rb', line 10253

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)


14930
14931
14932
14933
14934
14935
14936
14937
14938
14939
14940
# File 'lib/rbpdf.rb', line 14930

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



8610
8611
8612
8613
8614
8615
# File 'lib/rbpdf.rb', line 8610

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



8626
8627
8628
8629
8630
8631
8632
8633
# File 'lib/rbpdf.rb', line 8626

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



3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
# File 'lib/rbpdf.rb', line 3199

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


8565
8566
8567
8568
8569
8570
8571
# File 'lib/rbpdf.rb', line 8565

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)


4670
4671
4672
4673
4674
4675
4676
# File 'lib/rbpdf.rb', line 4670

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)


4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
# File 'lib/rbpdf.rb', line 4703

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)


4686
4687
4688
4689
4690
4691
4692
# File 'lib/rbpdf.rb', line 4686

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


4652
4653
4654
4655
4656
4657
4658
# File 'lib/rbpdf.rb', line 4652

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


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
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
# File 'lib/rbpdf.rb', line 4292

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


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
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454
12455
12456
12457
12458
12459
12460
12461
12462
12463
12464
12465
12466
12467
12468
12469
12470
12471
12472
12473
12474
12475
12476
12477
12478
12479
12480
12481
12482
12483
12484
12485
12486
12487
12488
12489
12490
12491
12492
12493
12494
12495
12496
12497
12498
12499
12500
12501
12502
12503
12504
12505
12506
12507
12508
12509
12510
12511
12512
12513
12514
12515
12516
12517
12518
12519
12520
12521
12522
12523
12524
12525
12526
12527
12528
12529
12530
12531
12532
12533
12534
12535
12536
12537
12538
12539
12540
12541
12542
12543
12544
12545
12546
12547
12548
12549
12550
12551
12552
12553
12554
12555
12556
12557
12558
12559
12560
12561
12562
12563
12564
12565
12566
12567
12568
12569
12570
12571
12572
12573
12574
12575
12576
12577
12578
12579
12580
12581
12582
12583
12584
12585
12586
12587
12588
12589
12590
12591
12592
12593
12594
12595
12596
12597
12598
12599
12600
12601
12602
12603
12604
12605
12606
12607
12608
12609
12610
12611
12612
12613
12614
12615
12616
12617
12618
12619
12620
12621
12622
12623
12624
12625
12626
12627
12628
12629
12630
12631
12632
12633
12634
12635
12636
12637
12638
12639
12640
12641
12642
12643
12644
12645
12646
12647
12648
12649
12650
12651
12652
12653
12654
12655
12656
12657
12658
12659
12660
12661
12662
12663
12664
12665
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678
12679
12680
12681
12682
12683
12684
12685
12686
12687
12688
12689
12690
12691
12692
12693
12694
12695
12696
12697
12698
12699
12700
12701
12702
12703
12704
12705
12706
12707
12708
12709
12710
12711
12712
12713
12714
12715
12716
12717
12718
12719
12720
12721
12722
12723
12724
12725
12726
12727
12728
12729
12730
12731
12732
12733
12734
12735
12736
12737
12738
12739
12740
12741
12742
12743
12744
12745
12746
12747
12748
12749
12750
12751
12752
12753
12754
12755
12756
12757
12758
12759
12760
12761
12762
12763
12764
12765
12766
12767
12768
12769
12770
12771
12772
12773
12774
12775
12776
12777
12778
12779
12780
12781
12782
12783
12784
12785
12786
12787
12788
12789
12790
12791
12792
12793
12794
12795
12796
12797
12798
12799
12800
12801
12802
12803
12804
12805
12806
12807
12808
12809
12810
12811
12812
12813
12814
12815
12816
12817
12818
12819
12820
12821
12822
12823
12824
12825
12826
12827
12828
12829
12830
12831
12832
12833
12834
12835
12836
12837
12838
12839
12840
12841
12842
12843
12844
12845
12846
12847
12848
12849
12850
12851
12852
12853
12854
12855
12856
12857
12858
12859
12860
12861
12862
12863
12864
12865
12866
12867
12868
12869
12870
12871
12872
12873
12874
12875
12876
12877
12878
12879
12880
12881
12882
12883
12884
12885
12886
12887
12888
12889
12890
12891
12892
12893
12894
12895
12896
12897
12898
12899
12900
12901
12902
12903
12904
12905
12906
12907
12908
12909
12910
12911
12912
12913
12914
12915
12916
12917
12918
12919
12920
12921
12922
12923
12924
12925
12926
12927
12928
12929
12930
12931
12932
12933
12934
12935
12936
12937
12938
12939
12940
12941
12942
12943
12944
12945
12946
12947
12948
12949
12950
12951
12952
12953
12954
12955
12956
12957
12958
12959
12960
12961
12962
12963
12964
12965
12966
12967
12968
12969
12970
12971
12972
12973
12974
12975
12976
12977
12978
12979
12980
12981
12982
12983
12984
12985
12986
12987
12988
12989
12990
12991
12992
12993
12994
12995
12996
12997
12998
12999
13000
13001
13002
13003
13004
13005
13006
13007
# File 'lib/rbpdf.rb', line 11855

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

        prev_lMargin = @l_margin
        prev_rMargin = @r_margin
        @l_margin = @thead_margins['lmargin']
        @r_margin = @thead_margins['rmargin']

        # print table header (thead)
        writeHTML(@thead, false, false, false, false, '')

        @l_margin = prev_lMargin
        @r_margin = prev_rMargin

        if (@start_transaction_page == (@numpages - 1)) or (@y < @start_transaction_y) or checkPageBreak(@lasth, '', false)
          # restore previous object
          rollbackTransaction(true)
          # restore previous values
          this_method_vars.each {|vkey , vval|
            eval("#{vkey} = vval")
          }
          # add a page (or trig AcceptPageBreak() for multicolumn mode)
          pre_y = @y
          if !checkPageBreak(@page_break_trigger + 1) and (@y < pre_y)
            # fix for multicolumn mode
            startliney = @y
          end
          @start_transaction_page = @page
          @start_transaction_y = @y
        end
      end
      # move :key index forward to skip THEAD block
      while (key < maxel) and !((dom[key]['tag'] and dom[key]['opening'] and (dom[key]['value'] == 'tr') and (dom[key]['thead'].nil? or !dom[key]['thead'])) or (dom[key]['tag'] and !dom[key]['opening'] and (dom[key]['value'] == 'table')))
        key += 1
      end
    end
    if dom[key]['tag'] or (key == 0)
      if dom[key]['line-height']
        # set line height
        @cell_height_ratio = dom[key]['line-height']
        @lasth = @font_size * @cell_height_ratio
      end
      if ((dom[key]['value'] == 'table') or (dom[key]['value'] == 'tr')) and !dom[key]['align'].nil?
        dom[key]['align'] = @rtl ? 'R' : 'L'
      end
      # vertically align image in line
      if !@newline and (dom[key]['value'] == 'img') and dom[key]['height'] and (dom[key]['height'].to_i > 0)
        # get image height
        imgh = getHTMLUnitToUnits(dom[key]['height'], @lasth, 'px')
        # check for automatic line break
        autolinebreak = false
        if dom[key]['width'] and (dom[key]['width'].to_i > 0)
          imgw = getHTMLUnitToUnits(dom[key]['width'], 1, 'px', false)
          if (@rtl and (@x - imgw < @l_margin + @c_margin)) or (!@rtl and (@x + imgw > @w - @r_margin - @c_margin))
            # add automatic line break
            autolinebreak = true
            Ln('', cell)
            # go back to evaluate this line break
            key -= 1
          end
        end
        if !autolinebreak
          if !@in_footer
            pre_y = @y
            # check for page break
            if !checkPageBreak(imgh) and (@y < pre_y)
              # fix for multicolumn mode
              startliney = @y
            end
          end
          if @page > startlinepage
            # fix line splitted over two pages
            if !@footerlen[startlinepage].nil?
              curpos = @pagelen[startlinepage] - @footerlen[startlinepage]
            end
            # line to be moved one page forward
            pagebuff = getPageBuffer(startlinepage)
            linebeg = pagebuff[startlinepos, curpos - startlinepos]
            tstart = pagebuff[0, startlinepos]
            tend = pagebuff[curpos..-1]
            # remove line from previous page
            setPageBuffer(startlinepage, tstart + '' + tend)
            pagebuff = getPageBuffer(@page)
            tstart = pagebuff[0, @cntmrk[@page]]
            tend = pagebuff[@cntmrk[@page]..-1]
            # add line start to current page
            yshift = minstartliney - @y
            if fontaligned
              yshift += curfontsize / @k
            end
            try = sprintf('1 0 0 1 0 %.3f cm', (yshift * @k))
            setPageBuffer(@page, tstart + "\nq\n" + try + "\n" + linebeg + "\nQ\n" + tend)
            # shift the annotations and links
            if @page_annots[@page]
              next_pask = @page_annots[@page].length
            else
              next_pask = 0
            end
            if !@page_annots[startlinepage].nil?
              @page_annots[startlinepage].each_with_index { |pac, pak|
                if pak >= pask
                  @page_annots[@page].push pac
                  @page_annots[startlinepage].delete_at(pak)
                  npak = @page_annots[@page].length - 1
                  @page_annots[@page][npak]['y'] -= yshift
                end
              }
            end
            pask = next_pask
            startlinepos = @cntmrk[@page]
            startlinepage = @page
            startliney = @y
          end
          @y += ((curfontsize * @cell_height_ratio / @k) + curfontascent - curfontdescent) / 2.0  - imgh
          minstartliney = [@y, minstartliney].min
          maxbottomliney = startliney + @font_size * @cell_height_ratio
        end
      elsif !dom[key]['fontname'].nil? or !dom[key]['fontstyle'].nil? or !dom[key]['fontsize'].nil?
        # account for different font size
        pfontname = curfontname
        pfontstyle = curfontstyle
        pfontsize = curfontsize
        fontname  = !dom[key]['fontname'].nil?  ? dom[key]['fontname']  : curfontname
        fontstyle = !dom[key]['fontstyle'].nil? ? dom[key]['fontstyle'] : curfontstyle
        fontsize  = !dom[key]['fontsize'].nil?  ? dom[key]['fontsize']  : curfontsize
        fontascent = getFontAscent(fontname, fontstyle, fontsize)
        fontdescent = getFontDescent(fontname, fontstyle, fontsize)
        if (fontname != curfontname) or (fontstyle != curfontstyle) or (fontsize != curfontsize)
          if fontsize.is_a?(Numeric) and (fontsize >= 0) and curfontsize.is_a?(Numeric) and (curfontsize >= 0) and (fontsize != curfontsize) and !@newline and (key < maxel - 1)
            if !@newline and (@page > startlinepage)
              # fix lines splitted over two pages
              if !@footerlen[startlinepage].nil?
                curpos = @pagelen[startlinepage] - @footerlen[startlinepage]
              end
              # line to be moved one page forward
              pagebuff = getPageBuffer(startlinepage)
              linebeg = pagebuff[startlinepos, curpos - startlinepos]
              tstart = pagebuff[0, startlinepos]
              tend = pagebuff[curpos..-1]
              # remove line from previous page
              setPageBuffer(startlinepage, tstart + '' + tend)
              pagebuff = getPageBuffer(@page)
              tstart = pagebuff[0, @cntmrk[@page]]
              tend = pagebuff[@cntmrk[@page]..-1]
              # add line start to current page
              yshift = minstartliney - @y
              try = sprintf('1 0 0 1 0 %.3f cm', yshift * @k)
              setPageBuffer(@page, tstart + "\nq\n" + try + "\n" + linebeg + "\nQ\n" + tend)
              # shift the annotations and links
              if @page_annots[@page]
                next_pask = @page_annots[@page].length
              else
                next_pask = 0
              end
              if !@page_annots[startlinepage].nil?
                @page_annots[startlinepage].each_with_index { |pac, pak|
                  if pak >= pask
                    @page_annots[@page].push = pac
                    @page_annots[startlinepage].delete_at(pak)
                    npak = @page_annots[@page].length - 1
                    @page_annots[@page][npak]['y'] -= yshift
                  end
                }
              end
              pask = next_pask
              startlinepos = @cntmrk[@page]
              startlinepage = @page
              startliney = @y
            end
            if !dom[key]['block']
              @y += (((curfontsize - fontsize) * @cell_height_ratio / @k) + curfontascent - fontascent - curfontdescent + fontdescent) / 2.0
              if (dom[key]['value'] != 'sup') and (dom[key]['value'] != 'sub')
                minstartliney = [@y, minstartliney].min
                maxbottomliney = [@y + ((fontsize * @cell_height_ratio) / @k), maxbottomliney].max
              end
            end
            fontaligned = true
          end
          SetFont(fontname, fontstyle, fontsize)
          @lasth = @font_size * @cell_height_ratio
          curfontname = fontname
          curfontstyle = fontstyle
          curfontsize = fontsize
          curfontascent = fontascent
          curfontdescent = fontdescent
        end
      end
      # set text rendering mode
      textstroke = !dom[key]['stroke'].nil? ? dom[key]['stroke'] : @textstrokewidth
      textfill = !dom[key]['fill'].nil? ? dom[key]['fill'] : ((@textrendermode % 2) == 0)
      textclip = !dom[key]['clip'].nil? ? dom[key]['clip'] : (@textrendermode > 3)
      setTextRenderingMode(textstroke, textfill, textclip)
      if (plalign == 'J') and dom[key]['block']
        plalign = ''
      end
      # get current position on page buffer
      curpos = @pagelen[startlinepage]
      if !dom[key]['bgcolor'].nil? and (dom[key]['bgcolor'].length > 0)
        SetFillColorArray(dom[key]['bgcolor'])
        wfill = 1
      else
        wfill = fill
      end
      if !dom[key]['fgcolor'].nil? and (dom[key]['fgcolor'].length > 0)
        SetTextColorArray(dom[key]['fgcolor'])
      end
      if !dom[key]['strokecolor'].nil? and (dom[key]['strokecolor'].length > 0)
        SetDrawColorArray(dom[key]['strokecolor'])
      end
      if !dom[key]['align'].nil?
        lalign = dom[key]['align']
      end
      if empty_string(lalign)
        lalign = align
      end
    end
    # align lines
    if @newline and (dom[key]['value'].length > 0) and (dom[key]['value'] != 'td') and (dom[key]['value'] != 'th')
      newline = true
      fontaligned = false
      # we are at the beginning of a new line
      if !startlinex.nil?
        yshift = minstartliney - startliney
        if (yshift > 0) or (@page > startlinepage)
          yshift = 0
        end
        t_x = 0
        # the last line must be shifted to be aligned as requested
        linew = (@endlinex - startlinex).abs
        pstart = getPageBuffer(startlinepage)[0, startlinepos]
        if !opentagpos.nil? and !@footerlen[startlinepage].nil? and !@in_footer
          @footerpos[startlinepage] = @pagelen[startlinepage] - @footerlen[startlinepage]
          midpos = [opentagpos, @footerpos[startlinepage]].min
        elsif !opentagpos.nil?
          midpos = opentagpos
        elsif !@footerlen[startlinepage].nil? and !@in_footer
          @footerpos[startlinepage] = @pagelen[startlinepage] - @footerlen[startlinepage]
          midpos = @footerpos[startlinepage]
        else
          midpos = 0
        end
        if midpos > 0
          pmid = getPageBuffer(startlinepage)[startlinepos, midpos - startlinepos]
          pend = getPageBuffer(startlinepage)[midpos..-1]
        else
          pmid = getPageBuffer(startlinepage)[startlinepos..-1]
          pend = ''
        end
        if (!plalign.nil? and ((plalign == 'C') or (plalign == 'J') or ((plalign == 'R') and !@rtl) or ((plalign == 'L') and @rtl))) or (yshift < 0)
          # calculate shifting amount
          tw = w
          if (plalign == 'J') and isRTLTextDir() and (@num_columns > 1)
            tw += @c_margin
          end
          if @l_margin != prevlMargin
            tw += prevlMargin - @l_margin
          end
          if @r_margin != prevrMargin
            tw += prevrMargin - @r_margin
          end
          one_space_width = GetStringWidth(32.chr)
          mdiff = (tw - linew).abs
          if plalign == 'C'
            if @rtl
              t_x = -(mdiff / 2.0)
            else
              t_x = (mdiff / 2.0)
            end
          elsif (plalign == 'R') and !@rtl
            # right alignment on LTR document
            if revstrpos(pmid, ')]').to_i == revstrpos(pmid, ' )]').to_i + 1
              # remove last space (if any)
              linew -= one_space_width
              mdiff = (tw - linew).abs
            end
            t_x = mdiff
          elsif (plalign == 'L') and @rtl
            # left alignment on RTL document
            if revstrpos(pmid, '[(') and ((revstrpos(pmid, '[( ').to_i == revstrpos(pmid, '[(').to_i) or (revstrpos(pmid, '[(' + 0.chr + 32.chr).to_i == revstrpos(pmid, '[(').to_i))
              # remove first space (if any)
              linew -= one_space_width
            end
            if pmid.index('[(') and (pmid.index('[(').to_i == revstrpos(pmid, '[(').to_i)
              # remove last space (if any)
              linew -= one_space_width
              if (@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont0')
                linew -= one_space_width
              end
            end
            mdiff = (tw - linew).abs
            t_x = -mdiff
          elsif (plalign == 'J') and (plalign == lalign)
            # Justification
            if isRTLTextDir()
              t_x = @l_margin - @endlinex + @c_margin
            end
            no = 0 # spaces without trim
            ns = 0 # spaces with trim

            pmidtemp = pmid
            # 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)
      @y += @c_margin if pbrk and !dom[key]['tag'] and !empty_string(@thead) and !@in_thead ### fix ###
      @newline = false
      startlinex = @x
      startliney = @y
      if dom[dom[key]['parent']]['value'] == 'sup'
        startliney -= (0.3 * @font_size_pt) / @k
      elsif dom[dom[key]['parent']]['value'] == 'sub'
        startliney -= (@font_size_pt / 0.7) / @k
      else
        minstartliney = startliney
        maxbottomliney = startliney + @font_size * @cell_height_ratio
      end
      if startlinepage == @page and !endlinepos.nil? and !pbrk # fix startlinepos at page break case.
        startlinepos = endlinepos
      else
        startlinepage = @page
        if !@in_footer
          if !@footerlen[@page].nil?
            @footerpos[@page] = @pagelen[@page] - @footerlen[@page]
          else
            @footerpos[@page] = @pagelen[@page]
          end
          startlinepos = @footerpos[@page]
        else
          startlinepos = @pagelen[@page]
        end
      end
      endlinepos = nil
      plalign = lalign
      if !@page_annots[@page].nil?
        pask = @page_annots[@page].length
      else
        pask = 0
      end
      SetFont(fontname, fontstyle, fontsize)
      if wfill  == 1
        SetFillColorArray(@bgcolor)
      end
    end # end newline
    if !opentagpos.nil?
      opentagpos = nil
    end
    if dom[key]['tag']
      addHtmlAnchor(@html_anchor) if @html_anchor
      if dom[key]['opening']
        # get text indentation (if any)
        if dom[key]['text-indent'] and dom[key]['block']
          @textindent = dom[key]['text-indent']
          @newline = true
        end
        if dom[key]['value'] == 'table'
          # available page width
          if @rtl
            wtmp = @x - @l_margin
          else
            wtmp = @w - @r_margin - @x
          end
          if cell or (dom[key]['attribute']['nested'] and (dom[key]['attribute']['nested'] == 'true'))
            # add margin for nested tables
            wtmp -= @c_margin
          end
          # table width
          if !dom[key]['width'].nil?
            table_width = getHTMLUnitToUnits(dom[key]['width'], wtmp, 'px')
          else
            table_width = wtmp
          end
        end
        if (dom[key]['value'] == 'td') or (dom[key]['value'] == 'th')
          trid = dom[key]['parent']
          table_el = dom[trid]['parent']
          if dom[table_el]['cols'].nil?
            dom[table_el]['cols'] = dom[trid]['cols']
          end
          oldmargin = @c_margin
          currentcmargin = @c_margin
          if !dom[(dom[trid]['parent'])]['attribute']['cellpadding'].nil?
            currentcmargin = getHTMLUnitToUnits(dom[(dom[trid]['parent'])]['attribute']['cellpadding'], 1, 'px')
          end
          if currentcmargin < (@line_width / 2.0)
            currentcmargin = @line_width / 2.0
          end
          @c_margin = currentcmargin
          if !dom[(dom[trid]['parent'])]['attribute']['cellspacing'].nil?
            cellspacing = getHTMLUnitToUnits(dom[(dom[trid]['parent'])]['attribute']['cellspacing'], 1, 'px')
          else
            cellspacing = 0
          end
          if @rtl
            cellspacingx = -cellspacing
          else
            cellspacingx = cellspacing
          end
          colspan = dom[key]['attribute']['colspan']
          table_columns_width = table_width - (cellspacing * (dom[table_el]['cols'] - 1))
          wtmp = colspan * (table_columns_width / dom[table_el]['cols']) + (colspan - 1) * cellspacing
          if !dom[key]['width'].nil?
            cellw = getHTMLUnitToUnits(dom[key]['width'], table_columns_width, 'px')
          else
            cellw = wtmp
          end
          if !dom[key]['height'].nil?
            # minimum cell height
            cellh = getHTMLUnitToUnits(dom[key]['height'], 0, 'px')
          else
            cellh = 0
          end
          if !dom[key]['content'].nil?
            cell_content = dom[key]['content']
          else
            cell_content = '&nbsp;'
          end
          tagtype = dom[key]['value']
          parentid = key
          while (key < maxel) and !(dom[key]['tag'] and !dom[key]['opening'] and (dom[key]['value'] == tagtype) and (dom[key]['parent'] == parentid))
            # move :key index forward
            key += 1
          end
          if dom[trid]['startpage'].nil?
            dom[trid]['startpage'] = @page
          else
             setPage(dom[trid]['startpage'])
          end
          if dom[trid]['starty'].nil?
            dom[trid]['starty'] = @y
          else
            @y = dom[trid]['starty']
          end
          if dom[trid]['startx'].nil?
            dom[trid]['startx'] = @x
          else
            @x += (cellspacingx / 2.0)
          end
          if !dom[parentid]['attribute']['rowspan'].nil?
            rowspan = dom[parentid]['attribute']['rowspan'].to_i
          else
            rowspan = 1
          end
          # skip row-spanned cells started on the previous rows
          if !dom[table_el]['rowspans'].nil?
            rsk = 0
            rskmax = dom[table_el]['rowspans'].length
            while rsk < rskmax
              trwsp = dom[table_el]['rowspans'][rsk]
              rsstartx = trwsp['startx']
              rsendx = trwsp['endx']
              # account for margin changes
              if trwsp['startpage'] < @page
                if @rtl and (@pagedim[@page]['orm'] != @pagedim[trwsp['startpage']]['orm'])
                  dl = @pagedim[@page]['orm'] - @pagedim[trwsp['startpage']]['orm']
                  rsstartx -= dl
                  rsendx -= dl
                elsif !@rtl and (@pagedim[@page]['olm'] != @pagedim[trwsp['startpage']]['olm'])
                  dl = @pagedim[@page]['olm'] - @pagedim[trwsp['startpage']]['olm']
                  rsstartx += dl
                  rsendx += dl
                end
              end
              if  (trwsp['rowspan'] > 0) and (rsstartx > @x - cellspacing - currentcmargin - @feps) and (rsstartx < @x + cellspacing + currentcmargin + @feps) and ((trwsp['starty'] < @y - @feps) or (trwsp['startpage'] < @page))
                # set the starting X position of the current cell
                @x = rsendx + cellspacingx
                if (trwsp['rowspan'] == 1) and !dom[trid]['endy'].nil? and !dom[trid]['endpage'].nil? and (trwsp['endpage'] == dom[trid]['endpage'])
                  # set ending Y position for row
                  dom[table_el]['rowspans'][rsk]['endy'] = [dom[trid]['endy'], trwsp['endy']].max
                  dom[trid]['endy'] = dom[table_el]['rowspans'][rsk]['endy']
                end
                rsk = 0
              else
                rsk += 1
              end
            end
          end
          # add rowspan information to table element
          if rowspan > 1
            dom[table_el]['rowspans'].push({'trid' => trid, 'rowspan' => rowspan, 'mrowspan' => rowspan, 'colspan' => colspan, 'startpage' => @page, 'startx' => @x, 'starty' => @y})
            trsid = dom[table_el]['rowspans'].size
          end
          dom[trid]['cellpos'].push({'startx' => @x})
          cellid = dom[trid]['cellpos'].size
          if rowspan > 1
            dom[trid]['cellpos'][cellid - 1]['rowspanid'] = trsid - 1
          end
          # push background colors
          if !dom[parentid]['bgcolor'].nil? and (dom[parentid]['bgcolor'].length > 0)
            dom[trid]['cellpos'][cellid - 1]['bgcolor'] = dom[parentid]['bgcolor'].dup
          end
          prevLastH = @lasth
          # ****** write the cell content ******
          MultiCell(cellw, cellh, cell_content, 0, lalign, 0, 2, '', '', true, 0, true)
          @lasth = prevLastH
          @c_margin = oldmargin
          dom[trid]['cellpos'][cellid - 1]['endx'] = @x
          # update the end of row position
          if rowspan <= 1
            if !dom[trid]['endy'].nil?
              if @page == dom[trid]['endpage']
                dom[trid]['endy'] = [@y, dom[trid]['endy']].max
              elsif @page > dom[trid]['endpage']
                dom[trid]['endy'] = @y
              end
            else
              dom[trid]['endy'] = @y
            end
            if !dom[trid]['endpage'].nil?
              dom[trid]['endpage'] = [@page, dom[trid]['endpage']].max
            else
              dom[trid]['endpage'] = @page
            end
          else
            # account for row-spanned cells
            dom[table_el]['rowspans'][trsid - 1]['endx'] = @x
            dom[table_el]['rowspans'][trsid - 1]['endy'] = @y
            dom[table_el]['rowspans'][trsid - 1]['endpage'] = @page
          end
          if !dom[table_el]['rowspans'].nil?
            # update endy and endpage on rowspanned cells
            dom[table_el]['rowspans'].each_with_index { |trwsp, k|
              if trwsp['rowspan'] > 0
                if !dom[trid]['endpage'].nil?
                  if trwsp['endpage'] == dom[trid]['endpage']
                    dom[table_el]['rowspans'][k]['endy'] = [dom[trid]['endy'], trwsp['endy']].max
                  elsif trwsp['endpage'] < dom[trid]['endpage']
                    dom[table_el]['rowspans'][k]['endy'] = dom[trid]['endy']
                    dom[table_el]['rowspans'][k]['endpage'] = dom[trid]['endpage']
                  else
                    dom[trid]['endy'] = @pagedim[dom[trid]['endpage']]['hk'] - @pagedim[dom[trid]['endpage']]['bm']
                  end
                end
              end
            }
          end
          @x += (cellspacingx / 2.0)
        else
          # opening tag (or self-closing tag)
          if opentagpos.nil?
            if !@in_footer
              if !@footerlen[@page].nil?
                @footerpos[@page] = @pagelen[@page] - @footerlen[@page]
              else
                @footerpos[@page] = @pagelen[@page]
              end
              opentagpos = @footerpos[@page]
            end
          end
          dom = openHTMLTagHandler(dom, key, cell)
        end
      else
        # closing tag
        prev_numpages = @numpages
        dom = closeHTMLTagHandler(dom, key, cell, maxbottomliney)
        if prev_numpages > @numpages
          startlinepage = @page
        end
      end
    elsif dom[key]['value'].length > 0
      # print list-item
      if !empty_string(@lispacer)
        SetFont(pfontname, pfontstyle, pfontsize)
        @lasth = @font_size * @cell_height_ratio
        minstartliney = @y
        maxbottomliney = startliney + @font_size * @cell_height_ratio
        putHtmlListBullet(@listnum, @lispacer, pfontsize)
        SetFont(curfontname, curfontstyle, curfontsize)
        @lasth = @font_size * @cell_height_ratio
        if pfontsize.is_a?(Numeric) and (pfontsize > 0) and curfontsize.is_a?(Numeric) and (curfontsize > 0) and (pfontsize != curfontsize)
          pfontascent = getFontAscent(pfontname, pfontstyle, pfontsize)
          pfontdescent = getFontDescent(pfontname, pfontstyle, pfontsize)
          @y += ((pfontsize - curfontsize) * @cell_height_ratio / @k + pfontascent - curfontascent - pfontdescent + curfontdescent) / 2.0
          minstartliney = [@y, minstartliney].min
          maxbottomliney = [@y + pfontsize * @cell_height_ratio / @k, maxbottomliney].max
        end
      end
      # text
      @htmlvspace = 0
      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.0)
        else
          t_x = (mdiff / 2.0)
        end
      elsif (plalign == 'R') and !@rtl
        # right alignment on LTR document
        if revstrpos(pmid, ')]').to_i == revstrpos(pmid, ' )]').to_i + 1
          # remove last space (if any)
          linew -= one_space_width
          mdiff = (tw - linew).abs
        end
        t_x = mdiff
      elsif (plalign == 'L') and @rtl
        # left alignment on RTL document
        if revstrpos(pmid, '[(') and ((revstrpos(pmid, '[( ').to_i == revstrpos(pmid, '[(').to_i) or (revstrpos(pmid, '[(' + 0.chr + 32.chr).to_i == revstrpos(pmid, '[(').to_i))
          # remove first space (if any)
          linew -= one_space_width
        end
        if pmid.index('[(') and (pmid.index('[(').to_i == revstrpos(pmid, '[(').to_i)
          # remove last space (if any)
          linew -= one_space_width
          if (@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont0')
            linew -= one_space_width
          end
        end
        mdiff = (tw - linew).abs
        t_x = -mdiff
      end
    end # end if startlinex
    if (t_x != 0) or (yshift < 0)
      # shift the line
      trx = sprintf('1 0 0 1 %.3f %.3f cm', t_x * @k, yshift * @k)
      setPageBuffer(startlinepage, pstart + "\nq\n" + trx + "\n" + pmid + "\nQ\n" + pend)
      endlinepos = (pstart + "\nq\n" + trx + "\n" + pmid + "\nQ\n").length

      # shift the annotations and links
      if !@page_annots[@page].nil?
        @page_annots[@page].each_with_index { |pac, pak|
          if pak >= pask
            @page_annots[@page][pak]['x'] += t_x
            @page_annots[@page][pak]['y'] -= yshift
          end
        }
      end
      @y -= yshift
    end
  end
  if ln and !(cell and (dom[key-1]['value'] == 'table'))
    Ln(@lasth)
    if @y < maxbottomliney
      @y = maxbottomliney
    end
  end
  # restore previous values
  setGraphicVars(gvars)
  if @page > prevPage
    @l_margin = @pagedim[@page]['olm']
    @r_margin = @pagedim[@page]['orm']
  end
  # restore previous list state
  @cell_height_ratio = prev_cell_height_ratio
  @listnum = prev_listnum
  @listordered = prev_listordered
  @listcount = prev_listcount
  @lispacer = prev_lispacer
  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()



11824
11825
11826
11827
# File 'lib/rbpdf.rb', line 11824

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