prawn 1.0.0.rc1 → 1.0.0.rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +18 -0
- data/README.md +5 -3
- data/Rakefile +8 -14
- data/data/pdfs/nested_pages.pdf +13 -13
- data/lib/prawn.rb +3 -1
- data/lib/prawn/compatibility.rb +46 -10
- data/lib/prawn/core.rb +3 -1
- data/lib/prawn/core/document_state.rb +2 -1
- data/lib/prawn/core/object_store.rb +61 -5
- data/lib/prawn/core/page.rb +3 -6
- data/lib/prawn/core/pdf_object.rb +21 -4
- data/lib/prawn/core/reference.rb +6 -2
- data/lib/prawn/core/text.rb +4 -4
- data/lib/prawn/core/text/formatted/line_wrap.rb +23 -8
- data/lib/prawn/document.rb +21 -15
- data/lib/prawn/document/bounding_box.rb +3 -3
- data/lib/prawn/document/column_box.rb +22 -4
- data/lib/prawn/document/snapshot.rb +1 -1
- data/lib/prawn/encoding.rb +1 -1
- data/lib/prawn/errors.rb +4 -0
- data/lib/prawn/font.rb +1 -1
- data/lib/prawn/font/afm.rb +30 -72
- data/lib/prawn/font/ttf.rb +6 -33
- data/lib/prawn/graphics.rb +148 -23
- data/lib/prawn/graphics/color.rb +8 -1
- data/lib/prawn/graphics/patterns.rb +137 -0
- data/lib/prawn/images.rb +25 -19
- data/lib/prawn/images/jpg.rb +4 -4
- data/lib/prawn/images/png.rb +18 -12
- data/lib/prawn/security.rb +6 -4
- data/lib/prawn/soft_mask.rb +94 -0
- data/lib/prawn/table.rb +136 -31
- data/lib/prawn/table/cell.rb +260 -29
- data/lib/prawn/table/cell/span_dummy.rb +88 -0
- data/lib/prawn/table/cell/text.rb +36 -14
- data/lib/prawn/table/cells.rb +91 -41
- data/lib/prawn/text.rb +3 -2
- data/lib/prawn/text/formatted/box.rb +14 -5
- data/lib/prawn/text/formatted/fragment.rb +33 -22
- data/lib/prawn/text/formatted/parser.rb +5 -2
- data/lib/prawn/utilities.rb +44 -0
- data/manual/basic_concepts/adding_pages.rb +27 -0
- data/manual/basic_concepts/basic_concepts.rb +34 -0
- data/manual/basic_concepts/creation.rb +39 -0
- data/manual/basic_concepts/cursor.rb +33 -0
- data/manual/basic_concepts/measurement.rb +25 -0
- data/manual/basic_concepts/origin.rb +38 -0
- data/manual/basic_concepts/other_cursor_helpers.rb +40 -0
- data/manual/bounding_box/bounding_box.rb +39 -0
- data/manual/bounding_box/bounds.rb +49 -0
- data/manual/bounding_box/canvas.rb +24 -0
- data/manual/bounding_box/creation.rb +23 -0
- data/manual/bounding_box/indentation.rb +46 -0
- data/manual/bounding_box/nesting.rb +45 -0
- data/manual/bounding_box/russian_boxes.rb +40 -0
- data/manual/bounding_box/stretchy.rb +31 -0
- data/manual/document_and_page_options/background.rb +27 -0
- data/manual/document_and_page_options/document_and_page_options.rb +31 -0
- data/manual/document_and_page_options/metadata.rb +23 -0
- data/manual/document_and_page_options/page_margins.rb +38 -0
- data/manual/document_and_page_options/page_size.rb +34 -0
- data/manual/example_file.rb +116 -0
- data/manual/example_helper.rb +430 -0
- data/manual/example_package.rb +53 -0
- data/manual/example_section.rb +46 -0
- data/manual/graphics/circle_and_ellipse.rb +22 -0
- data/manual/graphics/color.rb +24 -0
- data/manual/graphics/common_lines.rb +28 -0
- data/manual/graphics/fill_and_stroke.rb +42 -0
- data/manual/graphics/fill_rules.rb +37 -0
- data/manual/graphics/gradients.rb +37 -0
- data/manual/graphics/graphics.rb +58 -0
- data/manual/graphics/helper.rb +17 -0
- data/manual/graphics/line_width.rb +35 -0
- data/manual/graphics/lines_and_curves.rb +41 -0
- data/manual/graphics/polygon.rb +29 -0
- data/manual/graphics/rectangle.rb +21 -0
- data/manual/graphics/rotate.rb +28 -0
- data/manual/graphics/scale.rb +41 -0
- data/manual/graphics/soft_masks.rb +46 -0
- data/manual/graphics/stroke_cap.rb +31 -0
- data/manual/graphics/stroke_dash.rb +43 -0
- data/manual/graphics/stroke_join.rb +30 -0
- data/manual/graphics/translate.rb +29 -0
- data/manual/graphics/transparency.rb +35 -0
- data/manual/images/absolute_position.rb +23 -0
- data/manual/images/fit.rb +21 -0
- data/manual/images/horizontal.rb +25 -0
- data/manual/images/images.rb +40 -0
- data/manual/images/plain_image.rb +18 -0
- data/manual/images/scale.rb +22 -0
- data/manual/images/vertical.rb +28 -0
- data/manual/images/width_and_height.rb +25 -0
- data/manual/layout/boxes.rb +27 -0
- data/manual/layout/content.rb +25 -0
- data/manual/layout/layout.rb +28 -0
- data/manual/layout/simple_grid.rb +23 -0
- data/manual/manual/cover.rb +26 -0
- data/manual/manual/foreword.rb +13 -0
- data/manual/manual/how_to_read_this_manual.rb +41 -0
- data/manual/manual/manual.rb +36 -0
- data/manual/outline/add_subsection_to.rb +61 -0
- data/manual/outline/insert_section_after.rb +47 -0
- data/manual/outline/outline.rb +32 -0
- data/manual/outline/sections_and_pages.rb +67 -0
- data/manual/repeatable_content/page_numbering.rb +54 -0
- data/manual/repeatable_content/repeatable_content.rb +31 -0
- data/manual/repeatable_content/repeater.rb +55 -0
- data/manual/repeatable_content/stamp.rb +41 -0
- data/manual/security/encryption.rb +31 -0
- data/manual/security/permissions.rb +38 -0
- data/manual/security/security.rb +28 -0
- data/manual/syntax_highlight.rb +52 -0
- data/manual/table/basic_block.rb +53 -0
- data/manual/table/before_rendering_page.rb +26 -0
- data/manual/table/cell_border_lines.rb +24 -0
- data/manual/table/cell_borders_and_bg.rb +31 -0
- data/manual/table/cell_dimensions.rb +30 -0
- data/manual/table/cell_text.rb +38 -0
- data/manual/table/column_widths.rb +30 -0
- data/manual/table/content_and_subtables.rb +39 -0
- data/manual/table/creation.rb +27 -0
- data/manual/table/filtering.rb +36 -0
- data/manual/table/flow_and_header.rb +17 -0
- data/manual/table/image_cells.rb +33 -0
- data/manual/table/position.rb +29 -0
- data/manual/table/row_colors.rb +20 -0
- data/manual/table/span.rb +30 -0
- data/manual/table/style.rb +22 -0
- data/manual/table/table.rb +52 -0
- data/manual/table/width.rb +27 -0
- data/manual/templates/full_template.rb +23 -0
- data/manual/templates/page_template.rb +47 -0
- data/manual/templates/templates.rb +26 -0
- data/manual/text/alignment.rb +44 -0
- data/manual/text/color.rb +24 -0
- data/manual/text/column_box.rb +32 -0
- data/manual/text/fallback_fonts.rb +37 -0
- data/manual/text/font.rb +41 -0
- data/manual/text/font_size.rb +45 -0
- data/manual/text/font_style.rb +23 -0
- data/manual/text/formatted_callbacks.rb +60 -0
- data/manual/text/formatted_text.rb +50 -0
- data/manual/text/free_flowing_text.rb +51 -0
- data/manual/text/group.rb +29 -0
- data/manual/text/inline.rb +43 -0
- data/manual/text/kerning_and_character_spacing.rb +39 -0
- data/manual/text/leading.rb +25 -0
- data/manual/text/line_wrapping.rb +41 -0
- data/manual/text/paragraph_indentation.rb +26 -0
- data/manual/text/positioned_text.rb +38 -0
- data/manual/text/registering_families.rb +48 -0
- data/manual/text/rendering_and_color.rb +37 -0
- data/manual/text/right_to_left_text.rb +43 -0
- data/manual/text/rotation.rb +43 -0
- data/manual/text/single_usage.rb +37 -0
- data/manual/text/text.rb +75 -0
- data/manual/text/text_box_excess.rb +32 -0
- data/manual/text/text_box_extensions.rb +45 -0
- data/manual/text/text_box_overflow.rb +44 -0
- data/manual/text/utf8.rb +28 -0
- data/manual/text/win_ansi_charset.rb +59 -0
- data/prawn.gemspec +10 -7
- data/spec/bounding_box_spec.rb +107 -17
- data/spec/cell_spec.rb +66 -40
- data/spec/column_box_spec.rb +33 -0
- data/spec/document_spec.rb +45 -24
- data/spec/extensions/encoding_helpers.rb +6 -0
- data/spec/extensions/mocha.rb +1 -0
- data/spec/font_spec.rb +71 -53
- data/spec/formatted_text_arranger_spec.rb +19 -19
- data/spec/formatted_text_box_spec.rb +16 -16
- data/spec/formatted_text_fragment_spec.rb +6 -6
- data/spec/graphics_spec.rb +96 -31
- data/spec/grid_spec.rb +2 -2
- data/spec/images_spec.rb +18 -10
- data/spec/jpg_spec.rb +1 -1
- data/spec/line_wrap_spec.rb +14 -14
- data/spec/measurement_units_spec.rb +2 -2
- data/spec/name_tree_spec.rb +6 -6
- data/spec/object_store_spec.rb +17 -17
- data/spec/outline_spec.rb +35 -17
- data/spec/pdf_object_spec.rb +3 -1
- data/spec/png_spec.rb +22 -19
- data/spec/reference_spec.rb +24 -1
- data/spec/repeater_spec.rb +9 -9
- data/spec/security_spec.rb +3 -3
- data/spec/snapshot_spec.rb +3 -3
- data/spec/soft_mask_spec.rb +117 -0
- data/spec/span_spec.rb +4 -4
- data/spec/spec_helper.rb +12 -6
- data/spec/stamp_spec.rb +12 -12
- data/spec/stroke_styles_spec.rb +5 -5
- data/spec/table_spec.rb +458 -88
- data/spec/template_spec.rb +108 -54
- data/spec/text_at_spec.rb +17 -17
- data/spec/text_box_spec.rb +76 -45
- data/spec/text_rendering_mode_spec.rb +5 -5
- data/spec/text_spacing_spec.rb +4 -4
- data/spec/text_spec.rb +44 -40
- metadata +419 -250
- data/lib/prawn/graphics/gradient.rb +0 -84
- data/lib/prawn/security/arcfour.rb +0 -51
data/lib/prawn/font/ttf.rb
CHANGED
@@ -47,7 +47,7 @@ module Prawn
|
|
47
47
|
end
|
48
48
|
end * scale
|
49
49
|
else
|
50
|
-
string.
|
50
|
+
string.codepoints.inject(0) do |s,r|
|
51
51
|
s + character_width_by_code(r)
|
52
52
|
end * scale
|
53
53
|
end
|
@@ -160,44 +160,18 @@ module Prawn
|
|
160
160
|
end
|
161
161
|
|
162
162
|
def normalize_encoding(text)
|
163
|
-
|
164
|
-
# if we're running under a M17n aware VM, ensure the string provided is
|
165
|
-
# UTF-8 (by converting it if necessary)
|
166
|
-
begin
|
167
|
-
text.encode("UTF-8")
|
168
|
-
rescue
|
169
|
-
raise Prawn::Errors::IncompatibleStringEncoding, "Encoding " +
|
170
|
-
"#{text.encoding} can not be transparently converted to UTF-8. " +
|
171
|
-
"Please ensure the encoding of the string you are attempting " +
|
172
|
-
"to use is set correctly"
|
173
|
-
end
|
174
|
-
else
|
175
|
-
# on a non M17N aware VM, use unpack as a hackish way to verify the
|
176
|
-
# string is valid utf-8. I thought it was better than loading iconv
|
177
|
-
# though.
|
178
|
-
begin
|
179
|
-
text.unpack("U*")
|
180
|
-
return text.dup
|
181
|
-
rescue
|
182
|
-
raise Prawn::Errors::IncompatibleStringEncoding, "The string you " +
|
183
|
-
"are attempting to render is not encoded in valid UTF-8."
|
184
|
-
end
|
185
|
-
end
|
163
|
+
text.normalize_to_utf8
|
186
164
|
end
|
187
165
|
|
188
166
|
def glyph_present?(char)
|
189
|
-
code = char.
|
167
|
+
code = char.codepoints.first
|
190
168
|
cmap[code] > 0
|
191
169
|
end
|
192
170
|
|
193
171
|
# Returns the number of characters in +str+ (a UTF-8-encoded string).
|
194
172
|
#
|
195
173
|
def character_count(str)
|
196
|
-
|
197
|
-
str.length
|
198
|
-
else
|
199
|
-
str.unpack("U*").length
|
200
|
-
end
|
174
|
+
str.unicode_length
|
201
175
|
end
|
202
176
|
|
203
177
|
private
|
@@ -214,7 +188,7 @@ module Prawn
|
|
214
188
|
def kern(string)
|
215
189
|
a = []
|
216
190
|
|
217
|
-
string.
|
191
|
+
string.codepoints do |r|
|
218
192
|
if a.empty?
|
219
193
|
a << [r]
|
220
194
|
elsif (kern = kern_pairs_table[[cmap[a.last.last], cmap[r]]])
|
@@ -282,8 +256,7 @@ module Prawn
|
|
282
256
|
|
283
257
|
compressed_font = Zlib::Deflate.deflate(font_content)
|
284
258
|
|
285
|
-
fontfile = @document.ref!(:
|
286
|
-
:Length1 => font_content.size,
|
259
|
+
fontfile = @document.ref!(:Length1 => font_content.size,
|
287
260
|
:Filter => :FlateDecode )
|
288
261
|
fontfile << compressed_font
|
289
262
|
|
data/lib/prawn/graphics.rb
CHANGED
@@ -12,7 +12,7 @@ require "prawn/graphics/cap_style"
|
|
12
12
|
require "prawn/graphics/join_style"
|
13
13
|
require "prawn/graphics/transparency"
|
14
14
|
require "prawn/graphics/transformation"
|
15
|
-
require "prawn/graphics/
|
15
|
+
require "prawn/graphics/patterns"
|
16
16
|
|
17
17
|
module Prawn
|
18
18
|
|
@@ -30,7 +30,7 @@ module Prawn
|
|
30
30
|
include JoinStyle
|
31
31
|
include Transparency
|
32
32
|
include Transformation
|
33
|
-
include
|
33
|
+
include Patterns
|
34
34
|
|
35
35
|
#######################################################################
|
36
36
|
# Low level drawing operations must map the point to absolute coords! #
|
@@ -222,19 +222,19 @@ module Prawn
|
|
222
222
|
|
223
223
|
# Upper right hand corner
|
224
224
|
curve_to [x, y + r2],
|
225
|
-
:bounds => [[x + r1, y +
|
225
|
+
:bounds => [[x + r1, y + l2], [x + l1, y + r2]]
|
226
226
|
|
227
227
|
# Upper left hand corner
|
228
228
|
curve_to [x - r1, y],
|
229
|
-
:bounds => [[x -
|
229
|
+
:bounds => [[x - l1, y + r2], [x - r1, y + l2]]
|
230
230
|
|
231
231
|
# Lower left hand corner
|
232
232
|
curve_to [x, y - r2],
|
233
|
-
:bounds => [[x - r1, y -
|
233
|
+
:bounds => [[x - r1, y - l2], [x - l1, y - r2]]
|
234
234
|
|
235
235
|
# Lower right hand corner
|
236
236
|
curve_to [x + r1, y],
|
237
|
-
:bounds => [[x +
|
237
|
+
:bounds => [[x + l1, y - r2], [x + r1, y - l2]]
|
238
238
|
|
239
239
|
move_to(x, y)
|
240
240
|
end
|
@@ -337,23 +337,148 @@ module Prawn
|
|
337
337
|
add_content "h"
|
338
338
|
end
|
339
339
|
|
340
|
-
|
341
|
-
#
|
342
|
-
#
|
343
|
-
#
|
344
|
-
#
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
340
|
+
##
|
341
|
+
# :method: stroke_rectangle
|
342
|
+
# Draws and strokes a rectangle given +point+, +width+ and +height+. The rectangle is bounded by its upper-left corner.
|
343
|
+
# :call-seq:
|
344
|
+
# stroke_rectangle(point,width,height)
|
345
|
+
|
346
|
+
##
|
347
|
+
# :method: fill_rectangle
|
348
|
+
# Draws and fills ills a rectangle given +point+, +width+ and +height+. The rectangle is bounded by its upper-left corner.
|
349
|
+
# :call-seq:
|
350
|
+
# fill_rectangle(point,width,height)
|
351
|
+
|
352
|
+
##
|
353
|
+
# :method: fill_and_stroke_rectangle
|
354
|
+
# Draws, fills, and strokes a rectangle given +point+, +width+ and +height+. The rectangle is bounded by its upper-left corner.
|
355
|
+
# :call-seq:
|
356
|
+
# fill_and_stroke_rectangle(point,width,height)
|
357
|
+
|
358
|
+
##
|
359
|
+
# :method: stroke_rounded_rectangle
|
360
|
+
# Draws and strokes a rounded rectangle given +point+, +width+ and +height+ and +radius+ for the rounded corner. The rectangle is bounded by its upper-left corner.
|
361
|
+
# :call-seq:
|
362
|
+
# stroke_rounded_rectangle(point,width,height,radius)
|
363
|
+
|
364
|
+
##
|
365
|
+
# :method: fill_rounded_rectangle
|
366
|
+
# Draws and fills a rounded rectangle given +point+, +width+ and +height+ and +radius+ for the rounded corner. The rectangle is bounded by its upper-left corner.
|
367
|
+
# :call-seq:
|
368
|
+
# fill_rounded_rectangle(point,width,height,radius)
|
369
|
+
|
370
|
+
##
|
371
|
+
# :method: stroke_and_fill_rounded_rectangle
|
372
|
+
# Draws, fills, and strokes a rounded rectangle given +point+, +width+ and +height+ and +radius+ for the rounded corner. The rectangle is bounded by its upper-left corner.
|
373
|
+
# :call-seq:
|
374
|
+
# stroke_and_fill_rounded_rectangle(point,width,height,radius)
|
375
|
+
|
376
|
+
##
|
377
|
+
# :method: stroke_line
|
378
|
+
# Strokes a line from one point to another. Points may be specified as tuples or flattened argument list.
|
379
|
+
# :call-seq:
|
380
|
+
# stroke_line(*points)
|
381
|
+
|
382
|
+
##
|
383
|
+
# :method: stroke_horizontal_line
|
384
|
+
# Strokes a horizontal line from +x1+ to +x2+ at the current y position, or the position specified by the :at option.
|
385
|
+
# :call-seq:
|
386
|
+
# stroke_horizontal_line(x1,x2,options={})
|
387
|
+
|
388
|
+
##
|
389
|
+
# :method: stroke_horizontal_rule
|
390
|
+
# Strokes a horizontal line from the left border to the right border of the bounding box at the current y position.
|
391
|
+
|
392
|
+
##
|
393
|
+
# :method: stroke_vertical_line
|
394
|
+
# Strokes a vertical line at the x coordinate given by :at from y1 to y2.
|
395
|
+
# :call-seq:
|
396
|
+
# stroke_vertical_line(y1,y2,params)
|
397
|
+
|
398
|
+
##
|
399
|
+
# :method: stroke_curve
|
400
|
+
# Strokes a Bezier curve between two points, bounded by two additional points.
|
401
|
+
# :call-seq:
|
402
|
+
# stroke_curve(origin,dest,options={})
|
403
|
+
|
404
|
+
##
|
405
|
+
# :method: stroke_circle
|
406
|
+
# Draws and strokes a circle of radius +radius+ with the centre-point at +point+.
|
407
|
+
# :call-seq:
|
408
|
+
# stroke_circle(center,radius)
|
409
|
+
|
410
|
+
##
|
411
|
+
# :method: fill_circle
|
412
|
+
# Draws and fills a circle of radius +radius+ with the centre-point at +point+.
|
413
|
+
# :call-seq:
|
414
|
+
# fill_circle(center,radius)
|
415
|
+
|
416
|
+
##
|
417
|
+
# :method: fill_and_stroke_circle
|
418
|
+
# Draws, strokes, and fills a circle of radius +radius+ with the centre-point at +point+.
|
419
|
+
# :call-seq:
|
420
|
+
# fill_and_stroke_circle(center,radius)
|
421
|
+
|
422
|
+
##
|
423
|
+
# :method: stroke_ellipse
|
424
|
+
# Draws and strokes an ellipse of x radius +r1+ and y radius +r2+ with the centre-point at +point+.
|
425
|
+
# :call-seq:
|
426
|
+
# stroke_ellipse(point, r1, r2 = r1)
|
427
|
+
|
428
|
+
##
|
429
|
+
# :method: fill_ellipse
|
430
|
+
# Draws and fills an ellipse of x radius +r1+ and y radius +r2+ with the centre-point at +point+.
|
431
|
+
# :call-seq:
|
432
|
+
# fill_ellipse(point, r1, r2 = r1)
|
433
|
+
|
434
|
+
##
|
435
|
+
# :method: fill_and_stroke_ellipse
|
436
|
+
# Draws, strokes, and fills an ellipse of x radius +r1+ and y radius +r2+ with the centre-point at +point+.
|
437
|
+
# :call-seq:
|
438
|
+
# fill_and_stroke_ellipse(point, r1, r2 = r1)
|
439
|
+
|
440
|
+
##
|
441
|
+
# :method: stroke_polygon
|
442
|
+
# Draws and strokes a polygon from the specified points.
|
443
|
+
# :call-seq:
|
444
|
+
# stroke_polygon(*points)
|
445
|
+
|
446
|
+
##
|
447
|
+
# :method: fill_polygon
|
448
|
+
# Draws and fills a polygon from the specified points.
|
449
|
+
# :call-seq:
|
450
|
+
# fill_polygon(*points)
|
451
|
+
|
452
|
+
##
|
453
|
+
# :method: fill_and_stroke_polygon
|
454
|
+
# Draws, strokes, and fills a polygon from the specified points.
|
455
|
+
# :call-seq:
|
456
|
+
# fill_and_stroke_polygon(*points)
|
457
|
+
|
458
|
+
##
|
459
|
+
# :method: stroke_rounded_polygon
|
460
|
+
# Draws and strokes a rounded polygon from specified points, using +radius+ to define Bezier curves.
|
461
|
+
# :call-seq:
|
462
|
+
# stroke_rounded_polygon(radius, *points)
|
463
|
+
|
464
|
+
##
|
465
|
+
# :method: fill_rounded_polygon
|
466
|
+
# Draws and fills a rounded polygon from specified points, using +radius+ to define Bezier curves.
|
467
|
+
# :call-seq:
|
468
|
+
# fill_rounded_polygon(radius, *points)
|
469
|
+
|
470
|
+
##
|
471
|
+
# :method: fill_and_stroke_rounded_polygon
|
472
|
+
# Draws, strokes, and fills a rounded polygon from specified points, using +radius+ to define Bezier curves.
|
473
|
+
# :call-seq:
|
474
|
+
# fill_and_stroke_rounded_polygon(radius, *points)
|
475
|
+
|
476
|
+
ops = %w{fill stroke fill_and_stroke}
|
477
|
+
shapes = %w{line_to curve_to rectangle rounded_rectangle line horizontal_line horizontal_rule vertical_line
|
478
|
+
curve circle_at circle ellipse_at ellipse polygon rounded_polygon rounded_vertex}
|
479
|
+
|
480
|
+
ops.product(shapes).each do |operation,shape|
|
481
|
+
class_eval "def #{operation}_#{shape}(*args); #{shape}(*args); #{operation}; end"
|
357
482
|
end
|
358
483
|
|
359
484
|
private
|
data/lib/prawn/graphics/color.rb
CHANGED
@@ -0,0 +1,137 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# patterns.rb : Implements axial & radial gradients
|
4
|
+
#
|
5
|
+
# Originally implemented by Wojciech Piekutowski. November, 2009
|
6
|
+
# Copyright September 2012, Alexander Mankuta. All Rights Reserved.
|
7
|
+
#
|
8
|
+
# This is free software. Please see the LICENSE and COPYING files for details.
|
9
|
+
#
|
10
|
+
module Prawn
|
11
|
+
module Graphics
|
12
|
+
module Patterns
|
13
|
+
|
14
|
+
# Sets the fill gradient from color1 to color2.
|
15
|
+
# old arguments: point, width, height, color1, color2, options = {}
|
16
|
+
# new arguments: from, to, color1, color1
|
17
|
+
# or from, r1, to, r2, color1, color2
|
18
|
+
def fill_gradient(*args)
|
19
|
+
if args[1].is_a?(Array) || args[2].is_a?(Array)
|
20
|
+
set_gradient(:fill, *args)
|
21
|
+
else
|
22
|
+
warn "[DEPRECATION] 'fill_gradient(point, width, height,...)' is deprecated in favor of 'fill_gradient(from, to,...)'. " +
|
23
|
+
"Old arguments will be removed in release 1.1"
|
24
|
+
set_gradient :fill, args[0], [args[0].first, args[0].last - args[2]], args[3], args[4]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Sets the stroke gradient from color1 to color2.
|
29
|
+
# old arguments: point, width, height, color1, color2, options = {}
|
30
|
+
# new arguments: from, to, color1, color2
|
31
|
+
# or from, r1, to, r2, color1, color2
|
32
|
+
def stroke_gradient(*args)
|
33
|
+
if args[1].is_a?(Array) || args[2].is_a?(Array)
|
34
|
+
set_gradient(:stroke, *args)
|
35
|
+
else
|
36
|
+
warn "[DEPRECATION] 'stroke_gradient(point, width, height,...)' is deprecated in favor of 'stroke_gradient(from, to,...)'. " +
|
37
|
+
"Old arguments will be removed in release 1.1"
|
38
|
+
set_gradient :stroke, args[0], [args[0].first, args[0].last - args[2]], args[3], args[4]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def set_gradient(type, *grad)
|
45
|
+
patterns = page.resources[:Pattern] ||= {}
|
46
|
+
|
47
|
+
registry_key = gradient_registry_key grad
|
48
|
+
|
49
|
+
if patterns["SP#{registry_key}"]
|
50
|
+
shading = patterns["SP#{registry_key}"]
|
51
|
+
else
|
52
|
+
unless shading = gradient_registry[registry_key]
|
53
|
+
shading = gradient(*grad)
|
54
|
+
gradient_registry[registry_key] = shading
|
55
|
+
end
|
56
|
+
|
57
|
+
patterns["SP#{registry_key}"] = shading
|
58
|
+
end
|
59
|
+
|
60
|
+
operator = case type
|
61
|
+
when :fill
|
62
|
+
'scn'
|
63
|
+
when :stroke
|
64
|
+
'SCN'
|
65
|
+
else
|
66
|
+
raise ArgumentError, "unknown type '#{type}'"
|
67
|
+
end
|
68
|
+
|
69
|
+
set_color_space type, :Pattern
|
70
|
+
add_content "/SP#{registry_key} #{operator}"
|
71
|
+
end
|
72
|
+
|
73
|
+
def gradient_registry_key(gradient)
|
74
|
+
if gradient[1].is_a?(Array) # axial
|
75
|
+
[
|
76
|
+
map_to_absolute(gradient[0]),
|
77
|
+
map_to_absolute(gradient[1]),
|
78
|
+
gradient[2], gradient[3]
|
79
|
+
]
|
80
|
+
else # radial
|
81
|
+
[
|
82
|
+
map_to_absolute(gradient[0]),
|
83
|
+
gradient[1],
|
84
|
+
map_to_absolute(gradient[2]),
|
85
|
+
gradient[3],
|
86
|
+
gradient[4], gradient[5]
|
87
|
+
]
|
88
|
+
end.hash
|
89
|
+
end
|
90
|
+
|
91
|
+
def gradient_registry
|
92
|
+
@gradient_registry ||= {}
|
93
|
+
end
|
94
|
+
|
95
|
+
def gradient(*args)
|
96
|
+
if args.length != 4 && args.length != 6
|
97
|
+
raise ArgumentError, "Unknown type of gradient: #{args.inspect}"
|
98
|
+
end
|
99
|
+
|
100
|
+
color1 = normalize_color(args[-2]).dup.freeze
|
101
|
+
color2 = normalize_color(args[-1]).dup.freeze
|
102
|
+
|
103
|
+
if color_type(color1) != color_type(color2)
|
104
|
+
raise ArgumentError, "Both colors must be of the same color space: #{color1.inspect} and #{color2.inspect}"
|
105
|
+
end
|
106
|
+
|
107
|
+
process_color color1
|
108
|
+
process_color color2
|
109
|
+
|
110
|
+
shader = ref!({
|
111
|
+
:FunctionType => 2,
|
112
|
+
:Domain => [0.0, 1.0],
|
113
|
+
:C0 => color1,
|
114
|
+
:C1 => color2,
|
115
|
+
:N => 1.0,
|
116
|
+
})
|
117
|
+
|
118
|
+
shading = ref!({
|
119
|
+
:ShadingType => args.length == 4 ? 2 : 3, # axial : radial shading
|
120
|
+
:ColorSpace => color_space(color1),
|
121
|
+
:Coords => args.length == 4 ?
|
122
|
+
[0, 0, args[1].first - args[0].first, args[1].last - args[0].last] :
|
123
|
+
[0, 0, args[1], args[2].first - args[0].first, args[2].last - args[0].last, args[3]],
|
124
|
+
:Function => shader,
|
125
|
+
:Extend => [true, true],
|
126
|
+
})
|
127
|
+
|
128
|
+
shading_pattern = ref!({
|
129
|
+
:PatternType => 2, # shading pattern
|
130
|
+
:Shading => shading,
|
131
|
+
:Matrix => [1, 0,
|
132
|
+
0, 1] + map_to_absolute(args[0]),
|
133
|
+
})
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
data/lib/prawn/images.rb
CHANGED
@@ -14,8 +14,9 @@ module Prawn
|
|
14
14
|
# Add the image at filename to the current page. Currently only
|
15
15
|
# JPG and PNG files are supported.
|
16
16
|
#
|
17
|
-
# NOTE: Prawn is very slow at rendering PNGs with alpha channels
|
18
|
-
# workaround for those who don't mind installing
|
17
|
+
# NOTE: Prawn is very slow at rendering PNGs with alpha channels, and this
|
18
|
+
# uses a lot of RAM. The workaround for those who don't mind installing
|
19
|
+
# RMagick is to use:
|
19
20
|
#
|
20
21
|
# http://github.com/amberbit/prawn-fast-png
|
21
22
|
#
|
@@ -32,10 +33,10 @@ module Prawn
|
|
32
33
|
# <tt>:fit</tt>:: scale the dimensions of the image proportionally to fit inside [width,height]
|
33
34
|
#
|
34
35
|
# Prawn::Document.generate("image2.pdf", :page_layout => :landscape) do
|
35
|
-
# pigs = "#{Prawn::
|
36
|
+
# pigs = "#{Prawn::DATADIR}/images/pigs.jpg"
|
36
37
|
# image pigs, :at => [50,450], :width => 450
|
37
38
|
#
|
38
|
-
# dice = "#{Prawn::
|
39
|
+
# dice = "#{Prawn::DATADIR}/images/dice.png"
|
39
40
|
# image dice, :at => [50, 450], :scale => 0.75
|
40
41
|
# end
|
41
42
|
#
|
@@ -76,6 +77,12 @@ module Prawn
|
|
76
77
|
# the given image. Return a pair: [pdf_obj, info].
|
77
78
|
#
|
78
79
|
def build_image_object(file)
|
80
|
+
# Rewind if the object we're passed is an IO, so that multiple embeds of
|
81
|
+
# the same IO object will work
|
82
|
+
file.rewind if file.respond_to?(:rewind)
|
83
|
+
# read the file as binary so the size is calculated correctly
|
84
|
+
file.binmode if file.respond_to?(:binmode)
|
85
|
+
|
79
86
|
if file.respond_to?(:read)
|
80
87
|
image_content = file.read
|
81
88
|
else
|
@@ -139,17 +146,6 @@ module Prawn
|
|
139
146
|
def image_position(w,h,options)
|
140
147
|
options[:position] ||= :left
|
141
148
|
|
142
|
-
x = case options[:position]
|
143
|
-
when :left
|
144
|
-
bounds.absolute_left
|
145
|
-
when :center
|
146
|
-
bounds.absolute_left + (bounds.width - w) / 2.0
|
147
|
-
when :right
|
148
|
-
bounds.absolute_right - w
|
149
|
-
when Numeric
|
150
|
-
options[:position] + bounds.absolute_left
|
151
|
-
end
|
152
|
-
|
153
149
|
y = case options[:vposition]
|
154
150
|
when :top
|
155
151
|
bounds.absolute_top
|
@@ -162,16 +158,26 @@ module Prawn
|
|
162
158
|
else
|
163
159
|
determine_y_with_page_flow(h)
|
164
160
|
end
|
161
|
+
|
162
|
+
x = case options[:position]
|
163
|
+
when :left
|
164
|
+
bounds.left_side
|
165
|
+
when :center
|
166
|
+
bounds.left_side + (bounds.width - w) / 2.0
|
167
|
+
when :right
|
168
|
+
bounds.right_side - w
|
169
|
+
when Numeric
|
170
|
+
options[:position] + bounds.left_side
|
171
|
+
end
|
172
|
+
|
165
173
|
return [x,y]
|
166
174
|
end
|
167
175
|
|
168
176
|
def determine_y_with_page_flow(h)
|
169
177
|
if overruns_page?(h)
|
170
|
-
|
171
|
-
bounds.absolute_top
|
172
|
-
else
|
173
|
-
self.y
|
178
|
+
bounds.move_past_bottom
|
174
179
|
end
|
180
|
+
self.y
|
175
181
|
end
|
176
182
|
|
177
183
|
def overruns_page?(h)
|