prawn-core 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- data/HACKING +1 -1
- data/README +4 -8
- data/Rakefile +1 -1
- data/lib/prawn/compatibility.rb +13 -0
- data/lib/prawn/core.rb +1 -1
- data/lib/prawn/document.rb +1 -1
- data/lib/prawn/document/snapshot.rb +3 -0
- data/lib/prawn/errors.rb +4 -0
- data/lib/prawn/font.rb +29 -6
- data/lib/prawn/font/afm.rb +16 -4
- data/lib/prawn/font/ttf.rb +4 -0
- data/lib/prawn/graphics/color.rb +6 -2
- data/lib/prawn/text/box.rb +10 -10
- data/spec/font_spec.rb +6 -0
- data/spec/snapshot_spec.rb +11 -0
- data/spec/text_box_spec.rb +54 -26
- data/spec/text_spec.rb +6 -0
- metadata +2 -2
data/HACKING
CHANGED
@@ -22,7 +22,7 @@ If you are running on Ruby 1.9.1, you will need Test::Unit 1.2.3
|
|
22
22
|
|
23
23
|
http://github.com/sandal/prawn/issues
|
24
24
|
http://github.com/sandal/prawn-layout/issues
|
25
|
-
http://github.com/sandal/prawn-
|
25
|
+
http://github.com/sandal/prawn-security/issues
|
26
26
|
|
27
27
|
2. Fork any necessary repositories on Github, make your changes
|
28
28
|
3. Submit pull request so Gregory is notified
|
data/README
CHANGED
@@ -8,7 +8,7 @@ the many people who donated to the Ruby Mendicant project:
|
|
8
8
|
http://rubymendicant.wikidot.com
|
9
9
|
|
10
10
|
The project is currently maintained by Gregory Brown, with lots of help from
|
11
|
-
the community.
|
11
|
+
Prawn's core developers and the community.
|
12
12
|
|
13
13
|
== Quick Start
|
14
14
|
|
@@ -103,28 +103,22 @@ For tables and grid based layout:
|
|
103
103
|
|
104
104
|
http://github.com/sandal/prawn-layout/tree/stable/examples
|
105
105
|
|
106
|
-
For inline styling and advanced formatting:
|
107
|
-
|
108
|
-
http://github.com/sandal/prawn-format/tree/stable/examples
|
109
|
-
|
110
106
|
For encryption, password protection, and permissions:
|
111
107
|
|
112
108
|
http://github.com/madriska/prawn-security/tree/stable/examples
|
113
109
|
|
114
|
-
(or gem unpack prawn-core, prawn-
|
110
|
+
(or gem unpack prawn-core, prawn-security and prawn-layout if you want to run them locally)
|
115
111
|
|
116
112
|
=== Bug Tracker / Wiki:
|
117
113
|
|
118
114
|
http://github.com/sandal/prawn/issues
|
119
115
|
http://github.com/sandal/prawn-layout/issues
|
120
|
-
http://github.com/sandal/prawn-format/issues
|
121
116
|
http://github.com/madriska/prawn-security/issues
|
122
117
|
|
123
118
|
=== Source Code:
|
124
119
|
|
125
120
|
http://github.com/sandal/prawn
|
126
121
|
http://github.com/sandal/prawn-layout
|
127
|
-
http://github.com/sandal/prawn-format
|
128
122
|
http://github.com/madriska/prawn-security
|
129
123
|
|
130
124
|
=== Mailing List:
|
@@ -136,6 +130,8 @@ http://groups.google.com/group/prawn-ruby
|
|
136
130
|
Find us in #prawn on irc.freenode.net
|
137
131
|
Gregory Brown: <sandal>
|
138
132
|
James Healy: <yob>
|
133
|
+
Brad Ediger: <bradediger>
|
134
|
+
Daniel Nelson: <bluejade>
|
139
135
|
|
140
136
|
== Notes to Developers:
|
141
137
|
|
data/Rakefile
CHANGED
data/lib/prawn/compatibility.rb
CHANGED
@@ -4,9 +4,22 @@
|
|
4
4
|
# as simple as this?
|
5
5
|
#
|
6
6
|
class String #:nodoc:
|
7
|
+
def first_line
|
8
|
+
self.each_line { |line| return line }
|
9
|
+
end
|
7
10
|
unless "".respond_to?(:lines)
|
8
11
|
alias_method :lines, :to_a
|
9
12
|
end
|
13
|
+
unless "".respond_to?(:each_char)
|
14
|
+
def each_char
|
15
|
+
# copied from jcode
|
16
|
+
if block_given?
|
17
|
+
scan(/./m) { |x| yield x }
|
18
|
+
else
|
19
|
+
scan(/./m)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
10
23
|
end
|
11
24
|
|
12
25
|
unless File.respond_to?(:binread)
|
data/lib/prawn/core.rb
CHANGED
data/lib/prawn/document.rb
CHANGED
@@ -395,7 +395,7 @@ module Prawn
|
|
395
395
|
# Sets Document#bounds to the BoundingBox provided. See above for a brief
|
396
396
|
# description of what a bounding box is. This function is useful if you
|
397
397
|
# really need to change the bounding box manually, but usually, just entering
|
398
|
-
# and
|
398
|
+
# and exiting bounding box code blocks is good enough.
|
399
399
|
#
|
400
400
|
def bounds=(bounding_box)
|
401
401
|
@bounding_box = bounding_box
|
@@ -46,6 +46,7 @@ module Prawn
|
|
46
46
|
def take_snapshot
|
47
47
|
{:page_content => Marshal.load(Marshal.dump(page_content)),
|
48
48
|
:current_page => Marshal.load(Marshal.dump(current_page)),
|
49
|
+
:page_number => @page_number,
|
49
50
|
:page_kids => @store.pages.data[:Kids].map{|kid| kid.identifier},
|
50
51
|
:dests => names? &&
|
51
52
|
Marshal.load(Marshal.dump(names.data[:Dests]))}
|
@@ -64,6 +65,8 @@ module Prawn
|
|
64
65
|
current_page.replace shot[:current_page]
|
65
66
|
current_page.data[:Contents] = page_content
|
66
67
|
|
68
|
+
@page_number = shot[:page_number]
|
69
|
+
|
67
70
|
@store.pages.data[:Kids] = shot[:page_kids].map{|id| @store[id]}
|
68
71
|
@store.pages.data[:Count] = shot[:page_kids].size
|
69
72
|
|
data/lib/prawn/errors.rb
CHANGED
@@ -28,6 +28,10 @@ module Prawn
|
|
28
28
|
#
|
29
29
|
UnknownFont = Class.new(StandardError)
|
30
30
|
|
31
|
+
# Raised when Prawn is asked to draw something into a too-small box
|
32
|
+
#
|
33
|
+
CannotFit = Class.new(StandardError)
|
34
|
+
|
31
35
|
# This error is raised when Prawn is being used on a M17N aware VM,
|
32
36
|
# and the user attempts to add text that isn't compatible with UTF-8
|
33
37
|
# to their document
|
data/lib/prawn/font.rb
CHANGED
@@ -13,20 +13,37 @@ module Prawn
|
|
13
13
|
|
14
14
|
class Document
|
15
15
|
# Without arguments, this returns the currently selected font. Otherwise,
|
16
|
-
# it sets the current font.
|
16
|
+
# it sets the current font. When a block is used, the font is applied
|
17
|
+
# transactionally and is rolled back when the block exits.
|
17
18
|
#
|
18
|
-
#
|
19
|
+
# Prawn::Document.generate("font.pdf") do
|
20
|
+
# text "Default font is Helvetica"
|
21
|
+
#
|
22
|
+
# font "Times-Roman"
|
23
|
+
# text "Now using Times-Roman"
|
24
|
+
#
|
25
|
+
# font("Chalkboard.ttf") do
|
26
|
+
# text "Using TTF font from file Chalkboard.ttf"
|
27
|
+
# font "Courier", :style => :bold
|
28
|
+
# text "You see this in bold Courier"
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# text "Times-Roman, again"
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# The :name parameter must be a string. It can be one of the 14 built-in
|
19
35
|
# fonts supported by PDF, or the location of a TTF file. The Font::AFM::BUILT_INS
|
20
36
|
# array specifies the valid built in font values.
|
21
37
|
#
|
22
|
-
# pdf.font "Times-Roman"
|
23
|
-
# pdf.font "Chalkboard.ttf"
|
24
|
-
#
|
25
38
|
# If a ttf font is specified, the glyphs necessary to render your document
|
26
39
|
# will be embedded in the rendered PDF. This should be your preferred option
|
27
40
|
# in most cases. It will increase the size of the resulting file, but also
|
28
41
|
# make it more portable.
|
29
42
|
#
|
43
|
+
# The options parameter is an optional hash providing size and style. To use
|
44
|
+
# the :style option you need to map those font styles to their respective font files.
|
45
|
+
# See font_families for more information.
|
46
|
+
#
|
30
47
|
def font(name=nil, options={})
|
31
48
|
return((defined?(@font) && @font) || font("Helvetica")) if name.nil?
|
32
49
|
|
@@ -131,7 +148,7 @@ module Prawn
|
|
131
148
|
@font_registry ||= {}
|
132
149
|
end
|
133
150
|
|
134
|
-
# Hash that maps font family names to their styled individual font names
|
151
|
+
# Hash that maps font family names to their styled individual font names.
|
135
152
|
#
|
136
153
|
# To add support for another font family, append to this hash, e.g:
|
137
154
|
#
|
@@ -151,6 +168,12 @@ module Prawn
|
|
151
168
|
# This assumes that you have appropriate TTF fonts for each style you
|
152
169
|
# wish to support.
|
153
170
|
#
|
171
|
+
# By default the styles :bold, :italic, :bold_italic, and :normal are
|
172
|
+
# defined for fonts "Courier", "Times-Roman" and "Helvetica".
|
173
|
+
#
|
174
|
+
# You probably want to provide those four styles, but are free to define
|
175
|
+
# custom ones, like :thin, and use them in font calls.
|
176
|
+
#
|
154
177
|
def font_families
|
155
178
|
@font_families ||= Hash.new { |h,k| h[k] = {} }.merge!(
|
156
179
|
{ "Courier" => { :bold => "Courier-Bold",
|
data/lib/prawn/font/afm.rb
CHANGED
@@ -8,6 +8,10 @@ module Prawn
|
|
8
8
|
Times-Bold Times-Italic Times-BoldItalic
|
9
9
|
Helvetica-Bold Helvetica-Oblique Helvetica-BoldOblique ]
|
10
10
|
|
11
|
+
def unicode?
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
11
15
|
def self.metrics_path
|
12
16
|
if m = ENV['METRICS']
|
13
17
|
@metrics_path ||= m.split(':')
|
@@ -98,10 +102,18 @@ module Prawn
|
|
98
102
|
private
|
99
103
|
|
100
104
|
def register(subset)
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
+
font_dict = {:Type => :Font,
|
106
|
+
:Subtype => :Type1,
|
107
|
+
:BaseFont => name.to_sym}
|
108
|
+
|
109
|
+
# Symbolic AFM fonts (Symbol, ZapfDingbats) have their own encodings
|
110
|
+
font_dict.merge!(:Encoding => :WinAnsiEncoding) unless symbolic?
|
111
|
+
|
112
|
+
@document.ref!(font_dict)
|
113
|
+
end
|
114
|
+
|
115
|
+
def symbolic?
|
116
|
+
attributes["characterset"] == "Special"
|
105
117
|
end
|
106
118
|
|
107
119
|
def find_font(file)
|
data/lib/prawn/font/ttf.rb
CHANGED
data/lib/prawn/graphics/color.rb
CHANGED
@@ -10,7 +10,9 @@ module Prawn
|
|
10
10
|
module Graphics
|
11
11
|
module Color
|
12
12
|
|
13
|
-
# Sets the fill color.
|
13
|
+
# Sets or returns the fill color.
|
14
|
+
#
|
15
|
+
# When called with no argument, it returns the current fill color.
|
14
16
|
#
|
15
17
|
# If a single argument is provided, it should be a 6 digit HTML color
|
16
18
|
# code.
|
@@ -30,7 +32,9 @@ module Prawn
|
|
30
32
|
|
31
33
|
alias_method :fill_color=, :fill_color
|
32
34
|
|
33
|
-
# Sets the line stroking color.
|
35
|
+
# Sets or returns the line stroking color.
|
36
|
+
#
|
37
|
+
# When called with no argument, it returns the current stroking color.
|
34
38
|
#
|
35
39
|
# If a single argument is provided, it should be a 6 digit HTML color
|
36
40
|
# code.
|
data/lib/prawn/text/box.rb
CHANGED
@@ -234,6 +234,11 @@ module Prawn
|
|
234
234
|
:kerning => @kerning,
|
235
235
|
:size => @font_size,
|
236
236
|
:width => @width)
|
237
|
+
|
238
|
+
if line_to_print.empty? && remaining_text.length > 0
|
239
|
+
raise Errors::CannotFit
|
240
|
+
end
|
241
|
+
|
237
242
|
remaining_text = remaining_text.slice(line_to_print.length..
|
238
243
|
remaining_text.length)
|
239
244
|
print_ellipses = (@overflow == :ellipses && last_line? &&
|
@@ -290,7 +295,8 @@ module Prawn
|
|
290
295
|
|
291
296
|
def default_wrap_block
|
292
297
|
lambda do |line, options|
|
293
|
-
scan_pattern = /\S+|\s+/
|
298
|
+
scan_pattern = options[:document].font.unicode? ? /\S+|\s+/ : /\S+|\s+/n
|
299
|
+
space_scan_pattern = options[:document].font.unicode? ? /\s/ : /\s/n
|
294
300
|
output = ""
|
295
301
|
accumulated_width = 0
|
296
302
|
line.scan(scan_pattern).each do |segment|
|
@@ -304,9 +310,9 @@ module Prawn
|
|
304
310
|
else
|
305
311
|
# if the line contains white space, don't split the
|
306
312
|
# final word that doesn't fit, just return what fits nicely
|
307
|
-
break if output =~
|
313
|
+
break if output =~ space_scan_pattern
|
308
314
|
|
309
|
-
# if there is no white space on the
|
315
|
+
# if there is no white space on the current line, then just
|
310
316
|
# print whatever part of the last segment that will fit on the
|
311
317
|
# line
|
312
318
|
begin
|
@@ -319,6 +325,7 @@ module Prawn
|
|
319
325
|
output << char
|
320
326
|
end
|
321
327
|
rescue
|
328
|
+
# not valid unicode
|
322
329
|
segment.each_char do |char|
|
323
330
|
accumulated_width += options[:document].width_of(char,
|
324
331
|
:size => options[:size],
|
@@ -335,10 +342,3 @@ module Prawn
|
|
335
342
|
end
|
336
343
|
end
|
337
344
|
end
|
338
|
-
|
339
|
-
|
340
|
-
class String
|
341
|
-
def first_line
|
342
|
-
self.each_line { |line| return line }
|
343
|
-
end
|
344
|
-
end
|
data/spec/font_spec.rb
CHANGED
@@ -179,6 +179,12 @@ describe "AFM fonts" do
|
|
179
179
|
end
|
180
180
|
|
181
181
|
end
|
182
|
+
|
183
|
+
it "should omit /Encoding for symbolic fonts" do
|
184
|
+
zapf = @pdf.find_font "ZapfDingbats"
|
185
|
+
font_dict = zapf.send(:register, nil)
|
186
|
+
font_dict.data[:Encoding].should == nil
|
187
|
+
end
|
182
188
|
|
183
189
|
end
|
184
190
|
|
data/spec/snapshot_spec.rb
CHANGED
@@ -123,5 +123,16 @@ describe "Prawn::Document#transaction" do
|
|
123
123
|
|
124
124
|
end
|
125
125
|
|
126
|
+
it "should restore page_number on rollback" do
|
127
|
+
Prawn::Document.new do
|
128
|
+
transaction do
|
129
|
+
5.times { start_new_page }
|
130
|
+
rollback
|
131
|
+
end
|
132
|
+
|
133
|
+
page_number.should == 1
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
126
137
|
end
|
127
138
|
|
data/spec/text_box_spec.rb
CHANGED
@@ -233,90 +233,118 @@ end
|
|
233
233
|
|
234
234
|
|
235
235
|
describe 'Text::Box wrapping' do
|
236
|
-
|
236
|
+
before(:each) do
|
237
|
+
create_pdf
|
238
|
+
end
|
237
239
|
|
238
240
|
it "should wrap text" do
|
239
241
|
text = "Please wrap this text about HERE. More text that should be wrapped"
|
240
242
|
expect = "Please wrap this text about\nHERE. More text that should be\nwrapped"
|
241
243
|
|
242
|
-
@pdf = Prawn::Document.new
|
243
244
|
@pdf.font "Courier"
|
244
|
-
|
245
|
+
text_box = Prawn::Text::Box.new(text,
|
245
246
|
:width => 220,
|
246
247
|
:overflow => :expand,
|
247
248
|
:document => @pdf)
|
248
|
-
|
249
|
-
|
249
|
+
text_box.render
|
250
|
+
text_box.text.should == expect
|
250
251
|
end
|
251
252
|
|
252
253
|
it "should respect end of line when wrapping text" do
|
253
254
|
text = "Please wrap only before\nTHIS word. Don't wrap this"
|
254
255
|
expect = text
|
255
256
|
|
256
|
-
@pdf = Prawn::Document.new
|
257
257
|
@pdf.font "Courier"
|
258
|
-
|
258
|
+
text_box = Prawn::Text::Box.new(text,
|
259
259
|
:width => 220,
|
260
260
|
:overflow => :expand,
|
261
261
|
:document => @pdf)
|
262
|
-
|
263
|
-
|
262
|
+
text_box.render
|
263
|
+
text_box.text.should == expect
|
264
264
|
end
|
265
265
|
|
266
266
|
it "should respect multiple newlines when wrapping text" do
|
267
267
|
text = "Please wrap only before THIS\n\nword. Don't wrap this"
|
268
268
|
expect= "Please wrap only before\nTHIS\n\nword. Don't wrap this"
|
269
269
|
|
270
|
-
@pdf = Prawn::Document.new
|
271
270
|
@pdf.font "Courier"
|
272
|
-
|
271
|
+
text_box = Prawn::Text::Box.new(text,
|
273
272
|
:width => 200,
|
274
273
|
:overflow => :expand,
|
275
274
|
:document => @pdf)
|
276
|
-
|
277
|
-
|
275
|
+
text_box.render
|
276
|
+
text_box.text.should == expect
|
278
277
|
end
|
279
278
|
|
280
279
|
it "should respect multiple newlines when wrapping text when those newlines coincide with a line break" do
|
281
280
|
text = "Please wrap only before\n\nTHIS word. Don't wrap this"
|
282
281
|
expect = text
|
283
282
|
|
284
|
-
@pdf = Prawn::Document.new
|
285
283
|
@pdf.font "Courier"
|
286
|
-
|
284
|
+
text_box = Prawn::Text::Box.new(text,
|
287
285
|
:width => 220,
|
288
286
|
:overflow => :expand,
|
289
287
|
:document => @pdf)
|
290
|
-
|
291
|
-
|
288
|
+
text_box.render
|
289
|
+
text_box.text.should == expect
|
292
290
|
end
|
293
291
|
|
294
292
|
it "should respect initial newlines" do
|
295
293
|
text = "\nThis should be on line 2"
|
296
294
|
expect = text
|
297
295
|
|
298
|
-
@pdf = Prawn::Document.new
|
299
296
|
@pdf.font "Courier"
|
300
|
-
|
297
|
+
text_box = Prawn::Text::Box.new(text,
|
301
298
|
:width => 220,
|
302
299
|
:overflow => :expand,
|
303
300
|
:document => @pdf)
|
304
|
-
|
305
|
-
|
301
|
+
text_box.render
|
302
|
+
text_box.text.should == expect
|
306
303
|
end
|
307
304
|
|
308
305
|
it "should wrap lines comprised of a single word of the bounds when wrapping text" do
|
309
306
|
text = "You_can_wrap_this_text_HERE"
|
310
307
|
expect = "You_can_wrap_this_text_HE\nRE"
|
311
308
|
|
312
|
-
@pdf = Prawn::Document.new
|
313
309
|
@pdf.font "Courier"
|
314
|
-
|
310
|
+
text_box = Prawn::Text::Box.new(text,
|
315
311
|
:width => 180,
|
316
312
|
:overflow => :expand,
|
317
313
|
:document => @pdf)
|
318
|
-
|
319
|
-
|
320
|
-
end
|
314
|
+
text_box.render
|
315
|
+
text_box.text.should == expect
|
316
|
+
end
|
317
|
+
|
318
|
+
it "should wrap lines comprised of a single word of the bounds when wrapping text" do
|
319
|
+
text = '©' * 30
|
320
|
+
|
321
|
+
@pdf.font "Courier"
|
322
|
+
text_box = Prawn::Text::Box.new(text, :width => 180,
|
323
|
+
:overflow => :expand,
|
324
|
+
:document => @pdf)
|
325
|
+
|
326
|
+
text_box.render
|
327
|
+
|
328
|
+
expected = '©'*25 + "\n" + '©' * 5
|
329
|
+
@pdf.font.normalize_encoding!(expected)
|
330
|
+
|
331
|
+
text_box.text.should == expected
|
332
|
+
end
|
333
|
+
|
334
|
+
it "should wrap non-unicode strings using single-byte word-wrapping" do
|
335
|
+
text = "continúa esforzandote " * 5
|
336
|
+
text_box = Prawn::Text::Box.new(text, :width => 180,
|
337
|
+
:document => @pdf)
|
338
|
+
text_box.render
|
339
|
+
results_with_accent = text_box.text
|
340
|
+
|
341
|
+
text = "continua esforzandote " * 5
|
342
|
+
text_box = Prawn::Text::Box.new(text, :width => 180,
|
343
|
+
:document => @pdf)
|
344
|
+
text_box.render
|
345
|
+
results_without_accent = text_box.text
|
346
|
+
|
347
|
+
results_with_accent.first_line.length.should == results_without_accent.first_line.length
|
348
|
+
end
|
321
349
|
|
322
350
|
end
|
data/spec/text_spec.rb
CHANGED
@@ -12,6 +12,12 @@ describe "#height_of" do
|
|
12
12
|
new_y = @pdf.y
|
13
13
|
@pdf.height_of("Foo", :width => 300).should.be.close(original_y - new_y, 0.0001)
|
14
14
|
end
|
15
|
+
|
16
|
+
it "should raise CannotFit if a too-small width is given" do
|
17
|
+
lambda do
|
18
|
+
@pdf.height_of("text", :width => 1)
|
19
|
+
end.should.raise(Prawn::Errors::CannotFit)
|
20
|
+
end
|
15
21
|
end
|
16
22
|
|
17
23
|
describe "when drawing text" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prawn-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gregory Brown
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-31 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|