Revision 1297:0a574315af3e .svn/pristine/56

View differences:

.svn/pristine/56/56704f7daca6d78375b66cf72eeaa2ff41f9c20d.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2012  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require File.expand_path('../../test_helper', __FILE__)
19

  
20
class GroupsControllerTest < ActionController::TestCase
21
  fixtures :projects, :users, :members, :member_roles, :roles, :groups_users
22

  
23
  def setup
24
    @request.session[:user_id] = 1
25
  end
26

  
27
  def test_index
28
    get :index
29
    assert_response :success
30
    assert_template 'index'
31
  end
32

  
33
  def test_show
34
    get :show, :id => 10
35
    assert_response :success
36
    assert_template 'show'
37
  end
38

  
39
  def test_show_invalid_should_return_404
40
    get :show, :id => 99
41
    assert_response 404
42
  end
43

  
44
  def test_new
45
    get :new
46
    assert_response :success
47
    assert_template 'new'
48
    assert_select 'input[name=?]', 'group[name]'
49
  end
50

  
51
  def test_create
52
    assert_difference 'Group.count' do
53
      post :create, :group => {:name => 'New group'}
54
    end
55
    assert_redirected_to '/groups'
56
    group = Group.first(:order => 'id DESC')
57
    assert_equal 'New group', group.name
58
    assert_equal [], group.users
59
  end
60

  
61
  def test_create_and_continue
62
    assert_difference 'Group.count' do
63
      post :create, :group => {:name => 'New group'}, :continue => 'Create and continue'
64
    end
65
    assert_redirected_to '/groups/new'
66
    group = Group.first(:order => 'id DESC')
67
    assert_equal 'New group', group.name
68
  end
69

  
70
  def test_create_with_failure
71
    assert_no_difference 'Group.count' do
72
      post :create, :group => {:name => ''}
73
    end
74
    assert_response :success
75
    assert_template 'new'
76
  end
77

  
78
  def test_edit
79
    get :edit, :id => 10
80
    assert_response :success
81
    assert_template 'edit'
82
    assert_tag 'div', :attributes => {:id => 'tab-content-users'}
83
    assert_tag 'div', :attributes => {:id => 'tab-content-memberships'}
84
  end
85

  
86
  def test_update
87
    new_name = 'New name'
88
    put :update, :id => 10, :group => {:name => new_name}
89
    assert_redirected_to '/groups'
90
    group = Group.find(10)
91
    assert_equal new_name, group.name
92
  end
93

  
94
  def test_update_with_failure
95
    put :update, :id => 10, :group => {:name => ''}
96
    assert_response :success
97
    assert_template 'edit'
98
  end
99

  
100
  def test_destroy
101
    assert_difference 'Group.count', -1 do
102
      post :destroy, :id => 10
103
    end
104
    assert_redirected_to '/groups'
105
  end
106

  
107
  def test_add_users
108
    assert_difference 'Group.find(10).users.count', 2 do
109
      post :add_users, :id => 10, :user_ids => ['2', '3']
110
    end
111
  end
112

  
113
  def test_xhr_add_users
114
    assert_difference 'Group.find(10).users.count', 2 do
115
      xhr :post, :add_users, :id => 10, :user_ids => ['2', '3']
116
      assert_response :success
117
      assert_template 'add_users'
118
      assert_equal 'text/javascript', response.content_type
119
    end
120
    assert_match /John Smith/, response.body
121
  end
122

  
123
  def test_remove_user
124
    assert_difference 'Group.find(10).users.count', -1 do
125
      delete :remove_user, :id => 10, :user_id => '8'
126
    end
127
  end
128

  
129
  def test_xhr_remove_user
130
    assert_difference 'Group.find(10).users.count', -1 do
131
      xhr :delete, :remove_user, :id => 10, :user_id => '8'
132
      assert_response :success
133
      assert_template 'remove_user'
134
      assert_equal 'text/javascript', response.content_type
135
    end
136
  end
137

  
138
  def test_new_membership
139
    assert_difference 'Group.find(10).members.count' do
140
      post :edit_membership, :id => 10, :membership => { :project_id => 2, :role_ids => ['1', '2']}
141
    end
142
  end
143

  
144
  def test_xhr_new_membership
145
    assert_difference 'Group.find(10).members.count' do
146
      xhr :post, :edit_membership, :id => 10, :membership => { :project_id => 2, :role_ids => ['1', '2']}
147
      assert_response :success
148
      assert_template 'edit_membership'
149
      assert_equal 'text/javascript', response.content_type
150
    end
151
    assert_match /OnlineStore/, response.body
152
  end
153

  
154
  def test_xhr_new_membership_with_failure
155
    assert_no_difference 'Group.find(10).members.count' do
156
      xhr :post, :edit_membership, :id => 10, :membership => { :project_id => 999, :role_ids => ['1', '2']}
157
      assert_response :success
158
      assert_template 'edit_membership'
159
      assert_equal 'text/javascript', response.content_type
160
    end
161
    assert_match /alert/, response.body, "Alert message not sent"
162
  end
163

  
164
  def test_edit_membership
165
    assert_no_difference 'Group.find(10).members.count' do
166
      post :edit_membership, :id => 10, :membership_id => 6, :membership => { :role_ids => ['1', '3']}
167
    end
168
  end
169

  
170
  def test_xhr_edit_membership
171
    assert_no_difference 'Group.find(10).members.count' do
172
      xhr :post, :edit_membership, :id => 10, :membership_id => 6, :membership => { :role_ids => ['1', '3']}
173
      assert_response :success
174
      assert_template 'edit_membership'
175
      assert_equal 'text/javascript', response.content_type
176
    end
177
  end
178

  
179
  def test_destroy_membership
180
    assert_difference 'Group.find(10).members.count', -1 do
181
      post :destroy_membership, :id => 10, :membership_id => 6
182
    end
183
  end
184

  
185
  def test_xhr_destroy_membership
186
    assert_difference 'Group.find(10).members.count', -1 do
187
      xhr :post, :destroy_membership, :id => 10, :membership_id => 6
188
      assert_response :success
189
      assert_template 'destroy_membership'
190
      assert_equal 'text/javascript', response.content_type
191
    end
192
  end
193

  
194
  def test_autocomplete_for_user
195
    get :autocomplete_for_user, :id => 10, :q => 'mis'
196
    assert_response :success
197
    users = assigns(:users)
198
    assert_not_nil users
199
    assert users.any?
200
    assert !users.include?(Group.find(10).users.first)
201
  end
202
end
.svn/pristine/56/56813b39ed887e573bb8518a2b58c7a03d6e9767.svn-base
1
#============================================================+
2
# File name   : tcpdf.rb
3
# Begin       : 2002-08-03
4
# Last Update : 2007-03-20
5
# Author      : Nicola Asuni
6
# Version     : 1.53.0.TC031
7
# License     : GNU LGPL (http://www.gnu.org/copyleft/lesser.html)
8
#
9
# Description : This is a Ruby class for generating PDF files 
10
#               on-the-fly without requiring external 
11
#               extensions.
12
#
13
# IMPORTANT:
14
# This class is an extension and improvement of the Public Domain 
15
# FPDF class by Olivier Plathey (http://www.fpdf.org).
16
#
17
# Main changes by Nicola Asuni:
18
#    Ruby porting;
19
#    UTF-8 Unicode support;
20
#    code refactoring;
21
#    source code clean up;
22
#    code style and formatting;
23
#    source code documentation using phpDocumentor (www.phpdoc.org);
24
#    All ISO page formats were included;
25
#    image scale factor;
26
#    includes methods to parse and printsome XHTML code, supporting the following elements: h1, h2, h3, h4, h5, h6, b, u, i, a, img, p, br, strong, em, font, blockquote, li, ul, ol, hr, td, th, tr, table, sup, sub, small;
27
#    includes a method to print various barcode formats using an improved version of "Generic Barcode Render Class" by Karim Mribti (http://www.mribti.com/barcode/) (require GD library: http://www.boutell.com/gd/);
28
#    defines standard Header() and Footer() methods.
29
#
30
#   Ported to Ruby by Ed Moss 2007-08-06
31
#
32
#============================================================+
33

  
34
require 'tempfile'
35
require 'core/rmagick'
36

  
37
#
38
# TCPDF Class.
39
# @package com.tecnick.tcpdf
40
#
41
 
42
@@version = "1.53.0.TC031"
43
@@fpdf_charwidths = {}
44

  
45
PDF_PRODUCER = 'TCPDF via RFPDF 1.53.0.TC031 (http://tcpdf.sourceforge.net)'
46

  
47
module TCPDFFontDescriptor
48
  @@descriptors = { 'freesans' => {} }
49
  @@font_name = 'freesans'
50

  
51
  def self.font(font_name)
52
    @@descriptors[font_name.gsub(".rb", "")]
53
  end
54

  
55
  def self.define(font_name = 'freesans')
56
    @@descriptors[font_name] ||= {}
57
    yield @@descriptors[font_name]
58
  end
59
end
60

  
61
# This is a Ruby class for generating PDF files on-the-fly without requiring external extensions.<br>
62
# This class is an extension and improvement of the FPDF class by Olivier Plathey (http://www.fpdf.org).<br>
63
# 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]<br>
64
# TCPDF project (http://tcpdf.sourceforge.net) is based on the Public Domain FPDF class by Olivier Plathey (http://www.fpdf.org).<br>
65
# To add your own TTF fonts please read /fonts/README.TXT
66
# @name TCPDF
67
# @package com.tecnick.tcpdf
68
# @@version 1.53.0.TC031
69
# @author Nicola Asuni
70
# @link http://tcpdf.sourceforge.net
71
# @license http://www.gnu.org/copyleft/lesser.html LGPL
72
#
73
class TCPDF
74
  include RFPDF
75
  include Core::RFPDF
76
  include RFPDF::Math
77
  
78
  def logger
79
    Rails.logger
80
  end
81

  
82
  cattr_accessor :k_cell_height_ratio
83
  @@k_cell_height_ratio = 1.25
84

  
85
  cattr_accessor :k_blank_image
86
  @@k_blank_image = ""
87
  
88
  cattr_accessor :k_small_ratio  
89
  @@k_small_ratio = 2/3.0
90
  
91
  cattr_accessor :k_path_cache
92
  @@k_path_cache = Rails.root.join('tmp')
93
  
94
  cattr_accessor :k_path_url_cache
95
  @@k_path_url_cache = Rails.root.join('tmp')
96
  
97
  cattr_accessor :decoder
98
		
99
	attr_accessor :barcode
100
	
101
	attr_accessor :buffer
102
	
103
	attr_accessor :diffs
104
	
105
	attr_accessor :color_flag
106
	
107
	attr_accessor :default_table_columns
108

  
109
	attr_accessor :max_table_columns
110
	
111
	attr_accessor :default_font
112

  
113
	attr_accessor :draw_color
114
	
115
	attr_accessor :encoding
116
	
117
	attr_accessor :fill_color
118
	
119
	attr_accessor :fonts
120
	
121
	attr_accessor :font_family
122
	
123
	attr_accessor :font_files
124
	
125
	cattr_accessor :font_path
126
	
127
	attr_accessor :font_style
128
	
129
	attr_accessor :font_size_pt
130
	
131
	attr_accessor :header_width
132
	
133
	attr_accessor :header_logo
134
	
135
	attr_accessor :header_logo_width
136
	
137
	attr_accessor :header_title
138
	
139
	attr_accessor :header_string
140
	
141
	attr_accessor :images
142
	
143
	attr_accessor :img_scale
144
	
145
	attr_accessor :in_footer
146
	
147
	attr_accessor :is_unicode
148

  
149
	attr_accessor :lasth
150
	
151
	attr_accessor :links
152
	
153
	attr_accessor :list_ordered
154
	
155
	attr_accessor :list_count
156
	
157
	attr_accessor :li_spacer
158
	
159
	attr_accessor :n
160
	
161
	attr_accessor :offsets
162
	
163
	attr_accessor :orientation_changes
164
	
165
	attr_accessor :page
166
	
167
	attr_accessor :page_links
168
	
169
	attr_accessor :pages
170
	
171
	attr_accessor :pdf_version
172
	
173
	attr_accessor :prevfill_color
174
	
175
	attr_accessor :prevtext_color
176
	
177
	attr_accessor :print_header
178
	
179
	attr_accessor :print_footer
180
	
181
	attr_accessor :state
182
	
183
	attr_accessor :tableborder
184
	
185
	attr_accessor :tdbegin
186
	
187
	attr_accessor :tdwidth
188
	
189
	attr_accessor :tdheight
190
	
191
	attr_accessor :tdalign
192
	
193
	attr_accessor :tdfill
194
	
195
	attr_accessor :tempfontsize
196
	
197
	attr_accessor :text_color
198
	
199
	attr_accessor :underline
200
	
201
	attr_accessor :ws
202
	
203
	#
204
	# This is the class constructor. 
205
	# It allows to set up the page format, the orientation and 
206
	# the measure unit used in all the methods (except for the font sizes).
207
	# @since 1.0
208
	# @param string :orientation page orientation. Possible values are (case insensitive):<ul><li>P or Portrait (default)</li><li>L or Landscape</li></ul>
209
	# @param string :unit User measure unit. Possible values are:<ul><li>pt: point</li><li>mm: millimeter (default)</li><li>cm: centimeter</li><li>in: inch</li></ul><br />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.
210
	# @param mixed :format The format used for pages. It can be either one of the following values (case insensitive) or a custom format in the form of a two-element array containing the width and the height (expressed in the unit given by unit).<ul><li>4A0</li><li>2A0</li><li>A0</li><li>A1</li><li>A2</li><li>A3</li><li>A4 (default)</li><li>A5</li><li>A6</li><li>A7</li><li>A8</li><li>A9</li><li>A10</li><li>B0</li><li>B1</li><li>B2</li><li>B3</li><li>B4</li><li>B5</li><li>B6</li><li>B7</li><li>B8</li><li>B9</li><li>B10</li><li>C0</li><li>C1</li><li>C2</li><li>C3</li><li>C4</li><li>C5</li><li>C6</li><li>C7</li><li>C8</li><li>C9</li><li>C10</li><li>RA0</li><li>RA1</li><li>RA2</li><li>RA3</li><li>RA4</li><li>SRA0</li><li>SRA1</li><li>SRA2</li><li>SRA3</li><li>SRA4</li><li>LETTER</li><li>LEGAL</li><li>EXECUTIVE</li><li>FOLIO</li></ul>
211
	# @param boolean :unicode TRUE means that the input text is unicode (default = true)
212
	# @param String :encoding charset encoding; default is UTF-8
213
	#
214
	def initialize(orientation = 'P',  unit = 'mm', format = 'A4', unicode = true, encoding = "UTF-8")
215
		
216
		# Set internal character encoding to ASCII#
217
		#FIXME 2007-05-25 (EJM) Level=0 - 
218
		# if (respond_to?("mb_internal_encoding") and mb_internal_encoding())
219
		# 	@internal_encoding = mb_internal_encoding();
220
		# 	mb_internal_encoding("ASCII");
221
		# }
222
			
223
		#Some checks
224
		dochecks();
225
		
226
		begin	  
227
		  @@decoder = HTMLEntities.new 
228
		rescue
229
		  @@decoder = nil
230
		end
231
		
232
		#Initialization of properties
233
  	@barcode ||= false
234
		@buffer ||= ''
235
		@diffs ||= []
236
		@color_flag ||= false
237
  	@default_table_columns ||= 4
238
  	@table_columns ||= 0
239
  	@max_table_columns ||= []
240
  	@tr_id ||= 0
241
  	@max_td_page ||= []
242
  	@max_td_y ||= []
243
  	@t_columns ||= 0
244
  	@default_font ||= "FreeSans" if unicode
245
  	@default_font ||= "Helvetica"
246
		@draw_color ||= '0 G'
247
  	@encoding ||= "UTF-8"
248
		@fill_color ||= '0 g'
249
		@fonts ||= {}
250
		@font_family ||= ''
251
		@font_files ||= {}
252
		@font_style ||= ''
253
		@font_size ||= 12
254
		@font_size_pt ||= 12
255
  	@header_width ||= 0
256
  	@header_logo ||= ""
257
  	@header_logo_width ||= 30
258
  	@header_title ||= ""
259
  	@header_string ||= ""
260
		@images ||= {}
261
  	@img_scale ||= 1
262
		@in_footer ||= false
263
		@is_unicode = unicode
264
		@lasth ||= 0
265
		@links ||= []
266
  	@list_ordered ||= []
267
  	@list_count ||= []
268
  	@li_spacer ||= ""
269
  	@li_count ||= 0
270
  	@spacer ||= ""
271
  	@quote_count ||= 0
272
  	@prevquote_count ||= 0
273
  	@quote_top ||= []
274
  	@quote_page ||= []
275
		@n ||= 2
276
		@offsets ||= []
277
		@orientation_changes ||= []
278
		@page ||= 0
279
		@page_links ||= {}
280
		@pages ||= []
281
  	@pdf_version ||= "1.3"
282
  	@prevfill_color ||= [255,255,255]
283
  	@prevtext_color ||= [0,0,0]
284
  	@print_header ||= false
285
  	@print_footer ||= false
286
		@state ||= 0
287
  	@tableborder ||= 0
288
  	@tdbegin ||= false
289
	@tdtext ||= ''
290
  	@tdwidth ||= 0
291
  	@tdheight ||= 0
292
  	@tdalign ||= "L"
293
  	@tdfill ||= 0
294
  	@tempfontsize ||= 10
295
		@text_color ||= '0 g'
296
		@underline ||= false
297
		@deleted ||= false
298
		@ws ||= 0
299
		
300
		#Standard Unicode fonts
301
		@core_fonts = {
302
		'courier'=>'Courier',
303
		'courierB'=>'Courier-Bold',
304
		'courierI'=>'Courier-Oblique',
305
		'courierBI'=>'Courier-BoldOblique',
306
		'helvetica'=>'Helvetica',
307
		'helveticaB'=>'Helvetica-Bold',
308
		'helveticaI'=>'Helvetica-Oblique',
309
		'helveticaBI'=>'Helvetica-BoldOblique',
310
		'times'=>'Times-Roman',
311
		'timesB'=>'Times-Bold',
312
		'timesI'=>'Times-Italic',
313
		'timesBI'=>'Times-BoldItalic',
314
		'symbol'=>'Symbol',
315
		'zapfdingbats'=>'ZapfDingbats'}
316

  
317
		#Scale factor
318
		case unit.downcase
319
			when 'pt' ; @k=1
320
			when 'mm' ; @k=72/25.4
321
			when 'cm' ; @k=72/2.54
322
			when 'in' ; @k=72
323
			else Error("Incorrect unit: #{unit}")
324
		end
325

  
326
		#Page format
327
		if format.is_a?(String)
328
			# Page formats (45 standard ISO paper formats and 4 american common formats).
329
			# Paper cordinates are calculated in this way: (inches# 72) where (1 inch = 2.54 cm)
330
			case (format.upcase)
331
				when  '4A0' ; format = [4767.87,6740.79]
332
				when  '2A0' ; format = [3370.39,4767.87]
333
				when  'A0' ; format = [2383.94,3370.39]
334
				when  'A1' ; format = [1683.78,2383.94]
335
				when  'A2' ; format = [1190.55,1683.78]
336
				when  'A3' ; format = [841.89,1190.55]
337
				when  'A4' ; format = [595.28,841.89] # ; default
338
				when  'A5' ; format = [419.53,595.28]
339
				when  'A6' ; format = [297.64,419.53]
340
				when  'A7' ; format = [209.76,297.64]
341
				when  'A8' ; format = [147.40,209.76]
342
				when  'A9' ; format = [104.88,147.40]
343
				when  'A10' ; format = [73.70,104.88]
344
				when  'B0' ; format = [2834.65,4008.19]
345
				when  'B1' ; format = [2004.09,2834.65]
346
				when  'B2' ; format = [1417.32,2004.09]
347
				when  'B3' ; format = [1000.63,1417.32]
348
				when  'B4' ; format = [708.66,1000.63]
349
				when  'B5' ; format = [498.90,708.66]
350
				when  'B6' ; format = [354.33,498.90]
351
				when  'B7' ; format = [249.45,354.33]
352
				when  'B8' ; format = [175.75,249.45]
353
				when  'B9' ; format = [124.72,175.75]
354
				when  'B10' ; format = [87.87,124.72]
355
				when  'C0' ; format = [2599.37,3676.54]
356
				when  'C1' ; format = [1836.85,2599.37]
357
				when  'C2' ; format = [1298.27,1836.85]
358
				when  'C3' ; format = [918.43,1298.27]
359
				when  'C4' ; format = [649.13,918.43]
360
				when  'C5' ; format = [459.21,649.13]
361
				when  'C6' ; format = [323.15,459.21]
362
				when  'C7' ; format = [229.61,323.15]
363
				when  'C8' ; format = [161.57,229.61]
364
				when  'C9' ; format = [113.39,161.57]
365
				when  'C10' ; format = [79.37,113.39]
366
				when  'RA0' ; format = [2437.80,3458.27]
367
				when  'RA1' ; format = [1729.13,2437.80]
368
				when  'RA2' ; format = [1218.90,1729.13]
369
				when  'RA3' ; format = [864.57,1218.90]
370
				when  'RA4' ; format = [609.45,864.57]
371
				when  'SRA0' ; format = [2551.18,3628.35]
372
				when  'SRA1' ; format = [1814.17,2551.18]
373
				when  'SRA2' ; format = [1275.59,1814.17]
374
				when  'SRA3' ; format = [907.09,1275.59]
375
				when  'SRA4' ; format = [637.80,907.09]
376
				when  'LETTER' ; format = [612.00,792.00]
377
				when  'LEGAL' ; format = [612.00,1008.00]
378
				when  'EXECUTIVE' ; format = [521.86,756.00]
379
				when  'FOLIO' ; format = [612.00,936.00]
380
				#else then Error("Unknown page format: #{format}"
381
			end
382
			@fw_pt = format[0]
383
			@fh_pt = format[1]
384
		else
385
			@fw_pt = format[0]*@k
386
			@fh_pt = format[1]*@k
387
		end
388

  
389
		@fw = @fw_pt/@k
390
		@fh = @fh_pt/@k
391

  
392
		#Page orientation
393
		orientation = orientation.downcase
394
		if orientation == 'p' or orientation == 'portrait'
395
			@def_orientation = 'P'
396
			@w_pt = @fw_pt
397
			@h_pt = @fh_pt
398
		elsif orientation == 'l' or orientation == 'landscape'
399
			@def_orientation = 'L'
400
			@w_pt = @fh_pt
401
			@h_pt = @fw_pt
402
		else
403
			Error("Incorrect orientation: #{orientation}")
404
		end
405

  
406
    @fw = @w_pt/@k
407
    @fh = @h_pt/@k
408
    
409
		@cur_orientation = @def_orientation
410
		@w = @w_pt/@k
411
		@h = @h_pt/@k
412
		#Page margins (1 cm)
413
		margin = 28.35/@k
414
		SetMargins(margin, margin)
415
		#Interior cell margin (1 mm)
416
		@c_margin = margin / 10
417
		#Line width (0.2 mm)
418
		@line_width = 0.567 / @k
419
		#Automatic page break
420
		SetAutoPageBreak(true, 2 * margin)
421
		#Full width display mode
422
		SetDisplayMode('fullwidth')
423
		#Compression
424
		SetCompression(true)
425
		#Set default PDF version number
426
		@pdf_version = "1.3"
427
		
428
		@encoding = encoding
429
		@b = 0
430
		@i = 0
431
		@u = 0
432
		@href = ''
433
		@fontlist = ["arial", "times", "courier", "helvetica", "symbol"]
434
		@issetfont = false
435
		@issetcolor = false
436
	
437
		SetFillColor(200, 200, 200, true)
438
		SetTextColor(0, 0, 0, true)
439
	end
440
	
441
	#
442
	# Set the image scale.
443
	# @param float :scale image scale.
444
	# @author Nicola Asuni
445
	# @since 1.5.2
446
	#
447
	def SetImageScale(scale)
448
		@img_scale = scale;
449
	end
450
  alias_method :set_image_scale, :SetImageScale
451
	
452
	#
453
	# Returns the image scale.
454
	# @return float image scale.
455
	# @author Nicola Asuni
456
	# @since 1.5.2
457
	#
458
	def GetImageScale()
459
		return @img_scale;
460
	end
461
  alias_method :get_image_scale, :GetImageScale
462
  
463
	#
464
	# Returns the page width in units.
465
	# @return int page width.
466
	# @author Nicola Asuni
467
	# @since 1.5.2
468
	#
469
	def GetPageWidth()
470
		return @w;
471
	end
472
  alias_method :get_page_width, :GetPageWidth
473
  
474
	#
475
	# Returns the page height in units.
476
	# @return int page height.
477
	# @author Nicola Asuni
478
	# @since 1.5.2
479
	#
480
	def GetPageHeight()
481
		return @h;
482
	end
483
  alias_method :get_page_height, :GetPageHeight
484
  
485
	#
486
	# Returns the page break margin.
487
	# @return int page break margin.
488
	# @author Nicola Asuni
489
	# @since 1.5.2
490
	#
491
	def GetBreakMargin()
492
		return @b_margin;
493
	end
494
  alias_method :get_break_margin, :GetBreakMargin
495

  
496
	#
497
	# Returns the scale factor (number of points in user unit).
498
	# @return int scale factor.
499
	# @author Nicola Asuni
500
	# @since 1.5.2
501
	#
502
	def GetScaleFactor()
503
		return @k;
504
	end
505
  alias_method :get_scale_factor, :GetScaleFactor
506

  
507
	#
508
	# Defines the left, top and right margins. By default, they equal 1 cm. Call this method to change them.
509
	# @param float :left Left margin.
510
	# @param float :top Top margin.
511
	# @param float :right Right margin. Default value is the left one.
512
	# @since 1.0
513
	# @see SetLeftMargin(), SetTopMargin(), SetRightMargin(), SetAutoPageBreak()
514
	#
515
	def SetMargins(left, top, right=-1)
516
		#Set left, top and right margins
517
		@l_margin = left
518
		@t_margin = top
519
		if (right == -1)
520
			right = left
521
		end
522
		@r_margin = right
523
	end
524
  alias_method :set_margins, :SetMargins
525

  
526
	#
527
	# 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.
528
	# @param float :margin The margin.
529
	# @since 1.4
530
	# @see SetTopMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins()
531
	#
532
	def SetLeftMargin(margin)
533
		#Set left margin
534
		@l_margin = margin
535
		if ((@page>0) and (@x < margin))
536
			@x = margin
537
		end
538
	end
539
  alias_method :set_left_margin, :SetLeftMargin
540

  
541
	#
542
	# Defines the top margin. The method can be called before creating the first page.
543
	# @param float :margin The margin.
544
	# @since 1.5
545
	# @see SetLeftMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins()
546
	#
547
	def SetTopMargin(margin)
548
		#Set top margin
549
		@t_margin = margin
550
	end
551
  alias_method :set_top_margin, :SetTopMargin
552

  
553
	#
554
	# Defines the right margin. The method can be called before creating the first page.
555
	# @param float :margin The margin.
556
	# @since 1.5
557
	# @see SetLeftMargin(), SetTopMargin(), SetAutoPageBreak(), SetMargins()
558
	#
559
	def SetRightMargin(margin)
560
		#Set right margin
561
		@r_margin = margin
562
	end
563
  alias_method :set_right_margin, :SetRightMargin
564

  
565
	#
566
	# 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.
567
	# @param boolean :auto Boolean indicating if mode should be on or off.
568
	# @param float :margin Distance from the bottom of the page.
569
	# @since 1.0
570
	# @see Cell(), MultiCell(), AcceptPageBreak()
571
	#
572
	def SetAutoPageBreak(auto, margin=0)
573
		#Set auto page break mode and triggering margin
574
		@auto_page_break = auto
575
		@b_margin = margin
576
		@page_break_trigger = @h - margin
577
	end
578
  alias_method :set_auto_page_break, :SetAutoPageBreak
579

  
580
	#
581
	# Defines the way the document is to be displayed by the viewer. The zoom level can be set: pages can be displayed entirely on screen, occupy the full width of the window, use real size, be scaled by a specific zooming factor or use viewer default (configured in the Preferences menu of Acrobat). The page layout can be specified too: single at once, continuous display, two columns or viewer default. By default, documents use the full width mode with continuous display.
582
	# @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. <ul><li>fullpage: displays the entire page on screen </li><li>fullwidth: uses maximum width of window</li><li>real: uses real size (equivalent to 100% zoom)</li><li>default: uses viewer default mode</li></ul>
583
	# @param string :layout The page layout. Possible values are:<ul><li>single: displays one page at once</li><li>continuous: displays pages continuously (default)</li><li>two: displays two pages on two columns</li><li>default: uses viewer default mode</li></ul>
584
	# @since 1.2
585
	#
586
	def SetDisplayMode(zoom, layout = 'continuous')
587
		#Set display mode in viewer
588
		if (zoom == 'fullpage' or zoom == 'fullwidth' or zoom == 'real' or zoom == 'default' or !zoom.is_a?(String))
589
			@zoom_mode = zoom
590
		else
591
			Error("Incorrect zoom display mode: #{zoom}")
592
		end
593
		if (layout == 'single' or layout == 'continuous' or layout == 'two' or layout == 'default')
594
			@layout_mode = layout
595
		else
596
			Error("Incorrect layout display mode: #{layout}")
597
		end
598
	end
599
  alias_method :set_display_mode, :SetDisplayMode
600

  
601
	#
602
	# 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.
603
	# Note: the Zlib extension is required for this feature. If not present, compression will be turned off.
604
	# @param boolean :compress Boolean indicating if compression must be enabled.
605
	# @since 1.4
606
	#
607
	def SetCompression(compress)
608
		#Set page compression
609
		if (respond_to?('gzcompress'))
610
			@compress = compress
611
		else
612
			@compress = false
613
		end
614
	end
615
  alias_method :set_compression, :SetCompression
616

  
617
	#
618
	# Defines the title of the document.
619
	# @param string :title The title.
620
	# @since 1.2
621
	# @see SetAuthor(), SetCreator(), SetKeywords(), SetSubject()
622
	#
623
	def SetTitle(title)
624
		#Title of document
625
		@title = title
626
	end
627
  alias_method :set_title, :SetTitle
628

  
629
	#
630
	# Defines the subject of the document.
631
	# @param string :subject The subject.
632
	# @since 1.2
633
	# @see SetAuthor(), SetCreator(), SetKeywords(), SetTitle()
634
	#
635
	def SetSubject(subject)
636
		#Subject of document
637
		@subject = subject
638
	end
639
  alias_method :set_subject, :SetSubject
640

  
641
	#
642
	# Defines the author of the document.
643
	# @param string :author The name of the author.
644
	# @since 1.2
645
	# @see SetCreator(), SetKeywords(), SetSubject(), SetTitle()
646
	#
647
	def SetAuthor(author)
648
		#Author of document
649
		@author = author
650
	end
651
  alias_method :set_author, :SetAuthor
652

  
653
	#
654
	# Associates keywords with the document, generally in the form 'keyword1 keyword2 ...'.
655
	# @param string :keywords The list of keywords.
656
	# @since 1.2
657
	# @see SetAuthor(), SetCreator(), SetSubject(), SetTitle()
658
	#
659
	def SetKeywords(keywords)
660
		#Keywords of document
661
		@keywords = keywords
662
	end
663
  alias_method :set_keywords, :SetKeywords
664

  
665
	#
666
	# Defines the creator of the document. This is typically the name of the application that generates the PDF.
667
	# @param string :creator The name of the creator.
668
	# @since 1.2
669
	# @see SetAuthor(), SetKeywords(), SetSubject(), SetTitle()
670
	#
671
	def SetCreator(creator)
672
		#Creator of document
673
		@creator = creator
674
	end
675
  alias_method :set_creator, :SetCreator
676

  
677
	#
678
	# Defines an alias for the total number of pages. It will be substituted as the document is closed.<br />
679
	# <b>Example:</b><br />
680
	# <pre>
681
	# class PDF extends TCPDF {
682
	# 	def Footer()
683
	# 		#Go to 1.5 cm from bottom
684
	# 		SetY(-15);
685
	# 		#Select Arial italic 8
686
	# 		SetFont('Arial','I',8);
687
	# 		#Print current and total page numbers
688
	# 		Cell(0,10,'Page '.PageNo().'/{nb}',0,0,'C');
689
	# 	end
690
	# }
691
	# :pdf=new PDF();
692
	# :pdf->alias_nb_pages();
693
	# </pre>
694
	# @param string :alias The alias. Default valuenb}.
695
	# @since 1.4
696
	# @see PageNo(), Footer()
697
	#
698
	def AliasNbPages(alias_nb ='{nb}')
699
		#Define an alias for total number of pages
700
		@alias_nb_pages = escapetext(alias_nb)
701
	end
702
	alias_method :alias_nb_pages, :AliasNbPages
703

  
704
	#
705
	# 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.
706
	# 2004-06-11 :: Nicola Asuni : changed bold tag with strong
707
	# @param string :msg The error message
708
	# @since 1.0
709
	#
710
	def Error(msg)
711
		#Fatal error
712
		raise ("TCPDF error: #{msg}")
713
	end
714
  alias_method :error, :Error
715

  
716
	#
717
	# This method begins the generation of the PDF document. It is not necessary to call it explicitly because AddPage() does it automatically.
718
	# Note: no page is created by this method
719
	# @since 1.0
720
	# @see AddPage(), Close()
721
	#
722
	def Open()
723
		#Begin document
724
		@state = 1
725
	end
726
  # alias_method :open, :Open
727

  
728
	#
729
	# 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.
730
	# @since 1.0
731
	# @see Open(), Output()
732
	#
733
	def Close()
734
		#Terminate document
735
		if (@state==3)
736
			return;
737
		end
738
		if (@page==0)
739
			AddPage();
740
		end
741
		#Page footer
742
		@in_footer=true;
743
		Footer();
744
		@in_footer=false;
745
		#Close page
746
		endpage();
747
		#Close document
748
		enddoc();
749
	end
750
  # alias_method :close, :Close
751

  
752
	#
753
	# Adds a new page to the document. If a page is already present, the Footer() method is called first to output the footer. Then the page is added, the current position set to the top-left corner according to the left and top margins, and Header() is called to display the header.
754
	# The font which was set before calling is automatically restored. There is no need to call SetFont() again if you want to continue with the same font. The same is true for colors and line width.
755
	# The origin of the coordinate system is at the top-left corner and increasing ordinates go downwards.
756
	# @param string :orientation Page orientation. Possible values are (case insensitive):<ul><li>P or Portrait</li><li>L or Landscape</li></ul> The default value is the one passed to the constructor.
757
	# @since 1.0
758
	# @see TCPDF(), Header(), Footer(), SetMargins()
759
	#
760
	def AddPage(orientation='')
761
		#Start a new page
762
		if (@state==0)
763
			Open();
764
		end
765
		family=@font_family;
766
		style=@font_style + (@underline ? 'U' : '') + (@deleted ? 'D' : '');
767
		size=@font_size_pt;
768
		lw=@line_width;
769
		dc=@draw_color;
770
		fc=@fill_color;
771
		tc=@text_color;
772
		cf=@color_flag;
773
		if (@page>0)
774
			#Page footer
775
			@in_footer=true;
776
			Footer();
777
			@in_footer=false;
778
			#Close page
779
			endpage();
780
		end
781
		#Start new page
782
		beginpage(orientation);
783
		#Set line cap style to square
784
		out('2 J');
785
		#Set line width
786
		@line_width = lw;
787
		out(sprintf('%.2f w', lw*@k));
788
		#Set font
789
		if (family)
790
			SetFont(family, style, size);
791
		end
792
		#Set colors
793
		@draw_color = dc;
794
		if (dc!='0 G')
795
			out(dc);
796
		end
797
		@fill_color = fc;
798
		if (fc!='0 g')
799
			out(fc);
800
		end
801
		@text_color = tc;
802
		@color_flag = cf;
803
		#Page header
804
		Header();
805
		#Restore line width
806
		if (@line_width != lw)
807
			@line_width = lw;
808
			out(sprintf('%.2f w', lw*@k));
809
		end
810
		#Restore font
811
		if (family)
812
			SetFont(family, style, size);
813
		end
814
		#Restore colors
815
		if (@draw_color != dc)
816
			@draw_color = dc;
817
			out(dc);
818
		end
819
		if (@fill_color != fc)
820
			@fill_color = fc;
821
			out(fc);
822
		end
823
		@text_color = tc;
824
		@color_flag = cf;
825
	end
826
	  alias_method :add_page, :AddPage
827
	
828
  #
829
  # Rotate object.
830
  # @param float :angle angle in degrees for counter-clockwise rotation
831
  # @param int :x abscissa of the rotation center. Default is current x position
832
  # @param int :y ordinate of the rotation center. Default is current y position
833
  #
834
  def Rotate(angle, x="", y="")
835

  
836
  	if (x == '')
837
  		x = @x;
838
  	end
839
  	
840
  	if (y == '')
841
  		y = @y;
842
  	end
843
  	
844
  	if (@rtl)
845
  		x = @w - x;
846
  		angle = -@angle;
847
  	end
848
  	
849
  	y = (@h - y) * @k;
850
  	x *= @k;
851

  
852
  	# calculate elements of transformation matrix
853
  	tm = []
854
  	tm[0] = ::Math::cos(deg2rad(angle));
855
  	tm[1] = ::Math::sin(deg2rad(angle));
856
  	tm[2] = -tm[1];
857
  	tm[3] = tm[0];
858
  	tm[4] = x + tm[1] * y - tm[0] * x;
859
  	tm[5] = y - tm[0] * y - tm[1] * x;
860

  
861
  	# generate the transformation matrix
862
  	Transform(tm);
863
  end
864
    alias_method :rotate, :Rotate
865
  
866
  #
867
	# Starts a 2D tranformation saving current graphic state.
868
	# This function must be called before scaling, mirroring, translation, rotation and skewing.
869
	# Use StartTransform() before, and StopTransform() after the transformations to restore the normal behavior.
870
	#
871
	def StartTransform
872
		out('q');
873
	end
874
	  alias_method :start_transform, :StartTransform
875
	
876
	#
877
	# Stops a 2D tranformation restoring previous graphic state.
878
	# This function must be called after scaling, mirroring, translation, rotation and skewing.
879
	# Use StartTransform() before, and StopTransform() after the transformations to restore the normal behavior.
880
	#
881
	def StopTransform
882
		out('Q');
883
	end
884
	  alias_method :stop_transform, :StopTransform
885
	
886
  #
887
	# Apply graphic transformations.
888
	# @since 2.1.000 (2008-01-07)
889
	# @see StartTransform(), StopTransform()
890
	#
891
	def Transform(tm)
892
		x = out(sprintf('%.3f %.3f %.3f %.3f %.3f %.3f cm', tm[0], tm[1], tm[2], tm[3], tm[4], tm[5]));
893
	end
894
	  alias_method :transform, :Transform
895
		
896
	#
897
 	# Set header data.
898
	# @param string :ln header image logo
899
	# @param string :lw header image logo width in mm
900
	# @param string :ht string to print as title on document header
901
	# @param string :hs string to print on document header
902
	#
903
	def SetHeaderData(ln="", lw=0, ht="", hs="")
904
		@header_logo = ln || ""
905
		@header_logo_width = lw || 0
906
		@header_title = ht || ""
907
		@header_string = hs || ""
908
	end
909
	  alias_method :set_header_data, :SetHeaderData
910
	
911
	#
912
 	# Set header margin.
913
	# (minimum distance between header and top page margin)
914
	# @param int :hm distance in millimeters
915
	#
916
	def SetHeaderMargin(hm=10)
917
		@header_margin = hm;
918
	end
919
	  alias_method :set_header_margin, :SetHeaderMargin
920
	
921
	#
922
 	# Set footer margin.
923
	# (minimum distance between footer and bottom page margin)
924
	# @param int :fm distance in millimeters
925
	#
926
	def SetFooterMargin(fm=10)
927
		@footer_margin = fm;
928
	end
929
	  alias_method :set_footer_margin, :SetFooterMargin
930
	
931
	#
932
 	# Set a flag to print page header.
933
	# @param boolean :val set to true to print the page header (default), false otherwise. 
934
	#
935
	def SetPrintHeader(val=true)
936
		@print_header = val;
937
	end
938
	  alias_method :set_print_header, :SetPrintHeader
939
	
940
	#
941
 	# Set a flag to print page footer.
942
	# @param boolean :value set to true to print the page footer (default), false otherwise. 
943
	#
944
	def SetPrintFooter(val=true)
945
		@print_footer = val;
946
	end
947
	  alias_method :set_print_footer, :SetPrintFooter
948
	
949
	#
950
 	# This method is used to render the page header.
951
 	# It is automatically called by AddPage() and could be overwritten in your own inherited class.
952
	#
953
	def Header()
954
		if (@print_header)
955
			if (@original_l_margin.nil?)
956
				@original_l_margin = @l_margin;
957
			end
958
			if (@original_r_margin.nil?)
959
				@original_r_margin = @r_margin;
960
			end
961
			
962
			#set current position
963
			SetXY(@original_l_margin, @header_margin);
964
			
965
			if ((@header_logo) and (@header_logo != @@k_blank_image))
966
				Image(@header_logo, @original_l_margin, @header_margin, @header_logo_width);
967
			else
968
				@img_rb_y = GetY();
969
			end
970
			
971
			cell_height = ((@@k_cell_height_ratio * @header_font[2]) / @k).round(2)
972
			
973
			header_x = @original_l_margin + (@header_logo_width * 1.05); #set left margin for text data cell
974
			
975
			# header title
976
			SetFont(@header_font[0], 'B', @header_font[2] + 1);
977
			SetX(header_x);
978
			Cell(@header_width, cell_height, @header_title, 0, 1, 'L'); 
979
			
980
			# header string
981
			SetFont(@header_font[0], @header_font[1], @header_font[2]);
982
			SetX(header_x);
983
			MultiCell(@header_width, cell_height, @header_string, 0, 'L', 0);
984
			
985
			# print an ending header line
986
			if (@header_width)
987
				#set style for cell border
988
				SetLineWidth(0.3);
989
				SetDrawColor(0, 0, 0);
990
				SetY(1 + (@img_rb_y > GetY() ? @img_rb_y : GetY()));
991
				SetX(@original_l_margin);
992
				Cell(0, 0, '', 'T', 0, 'C'); 
993
			end
994
			
995
			#restore position
996
			SetXY(@original_l_margin, @t_margin);
997
		end
998
	end
999
	  alias_method :header, :Header
1000
	
1001
	#
1002
 	# This method is used to render the page footer. 
1003
 	# It is automatically called by AddPage() and could be overwritten in your own inherited class.
1004
	#
1005
	def Footer()
1006
		if (@print_footer)
1007
			
1008
			if (@original_l_margin.nil?)
1009
				@original_l_margin = @l_margin;
1010
			end
1011
			if (@original_r_margin.nil?)
1012
				@original_r_margin = @r_margin;
1013
			end
1014
			
1015
			#set font
1016
			SetFont(@footer_font[0], @footer_font[1] , @footer_font[2]);
1017
			#set style for cell border
1018
			line_width = 0.3;
1019
			SetLineWidth(line_width);
1020
			SetDrawColor(0, 0, 0);
1021
			
1022
			footer_height = ((@@k_cell_height_ratio * @footer_font[2]) / @k).round; #footer height, was , 2)
1023
			#get footer y position
1024
			footer_y = @h - @footer_margin - footer_height;
1025
			#set current position
1026
			SetXY(@original_l_margin, footer_y); 
1027
			
1028
			#print document barcode
1029
			if (@barcode)
1030
				Ln();
1031
				barcode_width = ((@w - @original_l_margin - @original_r_margin)).round; #max width
1032
				writeBarcode(@original_l_margin, footer_y + line_width, barcode_width, footer_height - line_width, "C128B", false, false, 2, @barcode);
1033
			end
1034
			
1035
			SetXY(@original_l_margin, footer_y); 
1036
			
1037
			#Print page number
1038
			Cell(0, footer_height, @l['w_page'] + " " + PageNo().to_s + ' / {nb}', 'T', 0, 'R'); 
1039
		end
1040
	end
1041
	  alias_method :footer, :Footer
1042
	
1043
	#
1044
	# Returns the current page number.
1045
	# @return int page number
1046
	# @since 1.0
1047
	# @see alias_nb_pages()
1048
	#
1049
	def PageNo()
1050
		#Get current page number
1051
		return @page;
1052
	end
1053
  alias_method :page_no, :PageNo
1054

  
1055
	#
1056
	# 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.
1057
	# @param int :r If g et b are given, red component; if not, indicates the gray level. Value between 0 and 255
1058
	# @param int :g Green component (between 0 and 255)
1059
	# @param int :b Blue component (between 0 and 255)
1060
	# @since 1.3
1061
	# @see SetFillColor(), SetTextColor(), Line(), Rect(), Cell(), MultiCell()
1062
	#
1063
	def SetDrawColor(r, g=-1, b=-1)
1064
		#Set color for all stroking operations
1065
		if ((r==0 and g==0 and b==0) or g==-1)
1066
			@draw_color=sprintf('%.3f G', r/255.0);
1067
		else
1068
			@draw_color=sprintf('%.3f %.3f %.3f RG', r/255.0, g/255.0, b/255.0);
1069
		end
1070
		if (@page>0)
1071
			out(@draw_color);
1072
		end
1073
	end
1074
  alias_method :set_draw_color, :SetDrawColor
1075

  
1076
	#
1077
	# 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.
1078
	# @param int :r If g et b are given, red component; if not, indicates the gray level. Value between 0 and 255
1079
	# @param int :g Green component (between 0 and 255)
1080
	# @param int :b Blue component (between 0 and 255)
1081
	# @param boolean :storeprev if true stores the RGB array on :prevfill_color variable.
1082
	# @since 1.3
1083
	# @see SetDrawColor(), SetTextColor(), Rect(), Cell(), MultiCell()
1084
	#
1085
	def SetFillColor(r, g=-1, b=-1, storeprev=false)
1086
		#Set color for all filling operations
1087
		if ((r==0 and g==0 and b==0) or g==-1)
1088
			@fill_color=sprintf('%.3f g', r/255.0);
1089
		else
1090
			@fill_color=sprintf('%.3f %.3f %.3f rg', r/255.0, g/255.0, b/255.0);
1091
		end
1092
		@color_flag=(@fill_color!=@text_color);
1093
		if (@page>0)
1094
			out(@fill_color);
1095
		end
1096
		if (storeprev)
1097
			# store color as previous value
1098
			@prevfill_color = [r, g, b]
1099
		end
1100
	end
1101
  alias_method :set_fill_color, :SetFillColor
1102

  
1103
  # This hasn't been ported from tcpdf, it's a variation on SetTextColor for setting cmyk colors
1104
	def SetCmykFillColor(c, m, y, k, storeprev=false)
1105
		#Set color for all filling operations
1106
		@fill_color=sprintf('%.3f %.3f %.3f %.3f k', c, m, y, k);
1107
		@color_flag=(@fill_color!=@text_color);
1108
		if (storeprev)
1109
			# store color as previous value
1110
			@prevtext_color = [c, m, y, k]
1111
		end
1112
		if (@page>0)
1113
			out(@fill_color);
1114
		end
1115
	end
1116
  alias_method :set_cmyk_fill_color, :SetCmykFillColor
1117

  
1118
	#
1119
	# 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.
1120
	# @param int :r If g et b are given, red component; if not, indicates the gray level. Value between 0 and 255
1121
	# @param int :g Green component (between 0 and 255)
1122
	# @param int :b Blue component (between 0 and 255)
1123
	# @param boolean :storeprev if true stores the RGB array on :prevtext_color variable.
1124
	# @since 1.3
1125
	# @see SetDrawColor(), SetFillColor(), Text(), Cell(), MultiCell()
1126
	#
1127
	def SetTextColor(r, g=-1, b=-1, storeprev=false)
1128
		#Set color for text
1129
		if ((r==0 and :g==0 and :b==0) or :g==-1)
1130
			@text_color=sprintf('%.3f g', r/255.0);
1131
		else
1132
			@text_color=sprintf('%.3f %.3f %.3f rg', r/255.0, g/255.0, b/255.0);
1133
		end
1134
		@color_flag=(@fill_color!=@text_color);
1135
		if (storeprev)
1136
			# store color as previous value
1137
			@prevtext_color = [r, g, b]
1138
		end
1139
	end
1140
  alias_method :set_text_color, :SetTextColor
1141

  
1142
  # This hasn't been ported from tcpdf, it's a variation on SetTextColor for setting cmyk colors
1143
	def SetCmykTextColor(c, m, y, k, storeprev=false)
1144
		#Set color for text
1145
		@text_color=sprintf('%.3f %.3f %.3f %.3f k', c, m, y, k);
1146
		@color_flag=(@fill_color!=@text_color);
1147
		if (storeprev)
1148
			# store color as previous value
1149
			@prevtext_color = [c, m, y, k]
1150
		end
1151
	end
1152
  alias_method :set_cmyk_text_color, :SetCmykTextColor
1153
  
1154
	#
1155
	# Returns the length of a string in user unit. A font must be selected.<br>
1156
	# Support UTF-8 Unicode [Nicola Asuni, 2005-01-02]
1157
	# @param string :s The string whose length is to be computed
1158
	# @return int
1159
	# @since 1.2
1160
	#
1161
	def GetStringWidth(s)
1162
		#Get width of a string in the current font
1163
		s = s.to_s;
1164
		cw = @current_font['cw']
1165
		w = 0;
1166
		if (@is_unicode)
1167
      unicode = UTF8StringToArray(s);
1168
      unicode.each do |char|
1169
				if (!cw[char].nil?)
1170
					w += cw[char];
1171
				# This should not happen. UTF8StringToArray should guarentee the array is ascii values.
1172
        # elsif (c!cw[char[0]].nil?)
1173
        #   w += cw[char[0]];
1174
        #         elsif (!cw[char.chr].nil?)
1175
        #           w += cw[char.chr];
1176
				elsif (!@current_font['desc']['MissingWidth'].nil?)
1177
					w += @current_font['desc']['MissingWidth']; # set default size
1178
				else
1179
					w += 500;
1180
				end
1181
			end
1182
		else
1183
		  s.each_byte do |c|
1184
				if cw[c.chr]
1185
					w += cw[c.chr];
1186
				elsif cw[?c.chr]
1187
					w += cw[?c.chr]
1188
				end
1189
			end
1190
		end
1191
		return (w * @font_size / 1000.0);
1192
	end
1193
  alias_method :get_string_width, :GetStringWidth
1194

  
1195
	#
1196
	# 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.
1197
	# @param float :width The width.
1198
	# @since 1.0
1199
	# @see Line(), Rect(), Cell(), MultiCell()
1200
	#
1201
	def SetLineWidth(width)
1202
		#Set line width
1203
		@line_width = width;
1204
		if (@page>0)
1205
			out(sprintf('%.2f w', width*@k));
1206
		end
1207
	end
1208
  alias_method :set_line_width, :SetLineWidth
1209

  
1210
	#
1211
	# Draws a line between two points.
1212
	# @param float :x1 Abscissa of first point
1213
	# @param float :y1 Ordinate of first point
1214
	# @param float :x2 Abscissa of second point
1215
	# @param float :y2 Ordinate of second point
1216
	# @since 1.0
1217
	# @see SetLineWidth(), SetDrawColor()
1218
	#
1219
	def Line(x1, y1, x2, y2)
1220
		#Draw a line
1221
		out(sprintf('%.2f %.2f m %.2f %.2f l S', x1 * @k, (@h - y1) * @k, x2 * @k, (@h - y2) * @k));
1222
	end
1223
  alias_method :line, :Line
1224

  
1225
  def Circle(mid_x, mid_y, radius, style='')
1226
    mid_y = (@h-mid_y)*@k
1227
    out(sprintf("q\n")) # postscript content in pdf
1228
    # init line type etc. with /GSD gs G g (grey) RG rg (RGB) w=line witdh etc. 
1229
    out(sprintf("1 j\n")) # line join
1230
    # translate ("move") circle to mid_y, mid_y
1231
    out(sprintf("1 0 0 1 %f %f cm", mid_x, mid_y))
1232
    kappa = 0.5522847498307933984022516322796
1233
    # Quadrant 1 
1234
    x_s = 0.0 # 12 o'clock 
1235
    y_s = 0.0 + radius
1236
    x_e = 0.0 + radius # 3 o'clock 
1237
    y_e = 0.0
1238
    out(sprintf("%f %f m\n", x_s, y_s)) # move to 12 o'clock 
1239
    # cubic bezier control point 1, start height and kappa * radius to the right 
1240
    bx_e1 = x_s + (radius * kappa)
1241
    by_e1 = y_s
1242
    # cubic bezier control point 2, end and kappa * radius above 
1243
    bx_e2 = x_e
1244
    by_e2 = y_e + (radius * kappa)
1245
    # draw cubic bezier from current point to x_e/y_e with bx_e1/by_e1 and bx_e2/by_e2 as bezier control points
1246
    out(sprintf("%f %f %f %f %f %f c\n", bx_e1, by_e1, bx_e2, by_e2, x_e, y_e))
1247
    # Quadrant 2 
1248
    x_s = x_e 
1249
    y_s = y_e # 3 o'clock 
1250
    x_e = 0.0 
1251
    y_e = 0.0 - radius # 6 o'clock 
1252
    bx_e1 = x_s # cubic bezier point 1 
1253
    by_e1 = y_s - (radius * kappa)
1254
    bx_e2 = x_e + (radius * kappa) # cubic bezier point 2 
1255
    by_e2 = y_e
1256
    out(sprintf("%f %f %f %f %f %f c\n", bx_e1, by_e1, bx_e2, by_e2, x_e, y_e))
1257
    # Quadrant 3 
1258
    x_s = x_e 
1259
    y_s = y_e # 6 o'clock 
1260
    x_e = 0.0 - radius
1261
    y_e = 0.0 # 9 o'clock 
1262
    bx_e1 = x_s - (radius * kappa) # cubic bezier point 1 
1263
    by_e1 = y_s
1264
    bx_e2 = x_e # cubic bezier point 2 
1265
    by_e2 = y_e - (radius * kappa)
1266
    out(sprintf("%f %f %f %f %f %f c\n", bx_e1, by_e1, bx_e2, by_e2, x_e, y_e))
1267
    # Quadrant 4 
1268
    x_s = x_e 
1269
    y_s = y_e # 9 o'clock 
1270
    x_e = 0.0 
1271
    y_e = 0.0 + radius # 12 o'clock 
1272
    bx_e1 = x_s # cubic bezier point 1 
1273
    by_e1 = y_s + (radius * kappa)
1274
    bx_e2 = x_e - (radius * kappa) # cubic bezier point 2 
1275
    by_e2 = y_e
1276
    out(sprintf("%f %f %f %f %f %f c\n", bx_e1, by_e1, bx_e2, by_e2, x_e, y_e))
1277
    if style=='F'
1278
        op='f'
1279
    elsif style=='FD' or style=='DF'
1280
        op='b'
1281
    else
1282
        op='s'
1283
    end
1284
    out(sprintf("#{op}\n")) # stroke circle, do not fill and close path 
1285
    # for filling etc. b, b*, f, f*
1286
    out(sprintf("Q\n")) # finish postscript in PDF
1287
  end
1288
  alias_method :circle, :Circle
1289

  
1290
	#
1291
	# Outputs a rectangle. It can be drawn (border only), filled (with no border) or both.
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff