prawn 1.0.0.rc1 → 1.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|