davebenvenuti-prawn 0.11.1.pre
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/COPYING +340 -0
- data/HACKING +50 -0
- data/LICENSE +56 -0
- data/README +141 -0
- data/Rakefile +52 -0
- data/data/encodings/win_ansi.txt +29 -0
- data/data/fonts/Action Man.dfont +0 -0
- data/data/fonts/Activa.ttf +0 -0
- data/data/fonts/Chalkboard.ttf +0 -0
- data/data/fonts/Courier-Bold.afm +342 -0
- data/data/fonts/Courier-BoldOblique.afm +342 -0
- data/data/fonts/Courier-Oblique.afm +342 -0
- data/data/fonts/Courier.afm +342 -0
- data/data/fonts/DejaVuSans.ttf +0 -0
- data/data/fonts/Dustismo_Roman.ttf +0 -0
- data/data/fonts/Helvetica-Bold.afm +2827 -0
- data/data/fonts/Helvetica-BoldOblique.afm +2827 -0
- data/data/fonts/Helvetica-Oblique.afm +3051 -0
- data/data/fonts/Helvetica.afm +3051 -0
- data/data/fonts/MustRead.html +19 -0
- data/data/fonts/Symbol.afm +213 -0
- data/data/fonts/Times-Bold.afm +2588 -0
- data/data/fonts/Times-BoldItalic.afm +2384 -0
- data/data/fonts/Times-Italic.afm +2667 -0
- data/data/fonts/Times-Roman.afm +2419 -0
- data/data/fonts/ZapfDingbats.afm +225 -0
- data/data/fonts/comicsans.ttf +0 -0
- data/data/fonts/gkai00mp.ttf +0 -0
- data/data/images/16bit.alpha +0 -0
- data/data/images/16bit.dat +0 -0
- data/data/images/16bit.png +0 -0
- data/data/images/arrow.png +0 -0
- data/data/images/arrow2.png +0 -0
- data/data/images/barcode_issue.png +0 -0
- data/data/images/dice.alpha +0 -0
- data/data/images/dice.dat +0 -0
- data/data/images/dice.png +0 -0
- data/data/images/dice_interlaced.png +0 -0
- data/data/images/fractal.jpg +0 -0
- data/data/images/letterhead.jpg +0 -0
- data/data/images/page_white_text.alpha +0 -0
- data/data/images/page_white_text.dat +0 -0
- data/data/images/page_white_text.png +0 -0
- data/data/images/pigs.jpg +0 -0
- data/data/images/rails.dat +0 -0
- data/data/images/rails.png +0 -0
- data/data/images/ruport.png +0 -0
- data/data/images/ruport_data.dat +0 -0
- data/data/images/ruport_transparent.png +0 -0
- data/data/images/ruport_type0.png +0 -0
- data/data/images/stef.jpg +0 -0
- data/data/images/tru256.bmp +0 -0
- data/data/images/web-links.dat +1 -0
- data/data/images/web-links.png +0 -0
- data/data/pdfs/complex_template.pdf +0 -0
- data/data/pdfs/contains_ttf_font.pdf +0 -0
- data/data/pdfs/encrypted.pdf +0 -0
- data/data/pdfs/hexagon.pdf +61 -0
- data/data/pdfs/indirect_reference.pdf +86 -0
- data/data/pdfs/nested_pages.pdf +118 -0
- data/data/pdfs/page_without_mediabox.pdf +193 -0
- data/data/pdfs/resources_as_indirect_object.pdf +83 -0
- data/data/pdfs/two_hexagons.pdf +90 -0
- data/data/pdfs/version_1_6.pdf +61 -0
- data/data/shift_jis_text.txt +1 -0
- data/examples/bounding_box/bounding_boxes.rb +44 -0
- data/examples/bounding_box/indentation.rb +35 -0
- data/examples/bounding_box/russian_boxes.rb +37 -0
- data/examples/bounding_box/stretched_nesting.rb +68 -0
- data/examples/example_helper.rb +8 -0
- data/examples/general/background.rb +24 -0
- data/examples/general/canvas.rb +16 -0
- data/examples/general/context_sensitive_headers.rb +38 -0
- data/examples/general/float.rb +12 -0
- data/examples/general/margin.rb +37 -0
- data/examples/general/measurement_units.rb +52 -0
- data/examples/general/metadata-info.rb +17 -0
- data/examples/general/multi_page_layout.rb +19 -0
- data/examples/general/outlines.rb +67 -0
- data/examples/general/page_geometry.rb +32 -0
- data/examples/general/page_numbering.rb +16 -0
- data/examples/general/repeaters.rb +48 -0
- data/examples/general/stamp.rb +42 -0
- data/examples/general/templates.rb +14 -0
- data/examples/graphics/basic_images.rb +24 -0
- data/examples/graphics/cmyk.rb +13 -0
- data/examples/graphics/curves.rb +12 -0
- data/examples/graphics/hexagon.rb +14 -0
- data/examples/graphics/image_fit.rb +16 -0
- data/examples/graphics/image_flow.rb +38 -0
- data/examples/graphics/image_position.rb +18 -0
- data/examples/graphics/line.rb +33 -0
- data/examples/graphics/png_types.rb +23 -0
- data/examples/graphics/polygons.rb +17 -0
- data/examples/graphics/remote_images.rb +13 -0
- data/examples/graphics/rounded_polygons.rb +20 -0
- data/examples/graphics/rounded_rectangle.rb +21 -0
- data/examples/graphics/ruport_style_helpers.rb +20 -0
- data/examples/graphics/stroke_bounds.rb +21 -0
- data/examples/graphics/stroke_cap_and_join.rb +46 -0
- data/examples/graphics/stroke_dash.rb +43 -0
- data/examples/graphics/transformations.rb +53 -0
- data/examples/graphics/transparency.rb +27 -0
- data/examples/grid/bounding_boxes.rb +22 -0
- data/examples/grid/column_gutter_grid.rb +21 -0
- data/examples/grid/multi_boxes.rb +52 -0
- data/examples/grid/show_grid.rb +14 -0
- data/examples/grid/simple_grid.rb +21 -0
- data/examples/m17n/chinese_text_wrapping.rb +18 -0
- data/examples/m17n/euro.rb +16 -0
- data/examples/m17n/sjis.rb +29 -0
- data/examples/m17n/utf8.rb +14 -0
- data/examples/m17n/win_ansi_charset.rb +55 -0
- data/examples/security/hello_foo.rb +9 -0
- data/examples/table/bill.rb +54 -0
- data/examples/table/cell.rb +13 -0
- data/examples/table/checkerboard.rb +23 -0
- data/examples/table/header.rb +15 -0
- data/examples/table/inline_format_table.rb +13 -0
- data/examples/table/multi_page_table.rb +10 -0
- data/examples/table/simple_table.rb +25 -0
- data/examples/table/subtable.rb +13 -0
- data/examples/table/widths.rb +21 -0
- data/examples/text/alignment.rb +19 -0
- data/examples/text/character_spacing.rb +13 -0
- data/examples/text/dfont.rb +49 -0
- data/examples/text/family_based_styling.rb +25 -0
- data/examples/text/font_calculations.rb +92 -0
- data/examples/text/font_size.rb +34 -0
- data/examples/text/hyphenation.rb +46 -0
- data/examples/text/indent_paragraphs.rb +23 -0
- data/examples/text/inline_format.rb +104 -0
- data/examples/text/kerning.rb +31 -0
- data/examples/text/rotated.rb +99 -0
- data/examples/text/shaped_text_box.rb +32 -0
- data/examples/text/simple_text.rb +18 -0
- data/examples/text/simple_text_ttf.rb +18 -0
- data/examples/text/span.rb +30 -0
- data/examples/text/text_box.rb +89 -0
- data/examples/text/text_box_returning_excess.rb +52 -0
- data/examples/text/text_flow.rb +68 -0
- data/lib/prawn.rb +26 -0
- data/lib/prawn/compatibility.rb +51 -0
- data/lib/prawn/core.rb +85 -0
- data/lib/prawn/core/annotations.rb +61 -0
- data/lib/prawn/core/byte_string.rb +9 -0
- data/lib/prawn/core/destinations.rb +90 -0
- data/lib/prawn/core/document_state.rb +78 -0
- data/lib/prawn/core/literal_string.rb +16 -0
- data/lib/prawn/core/name_tree.rb +165 -0
- data/lib/prawn/core/object_store.rb +236 -0
- data/lib/prawn/core/page.rb +199 -0
- data/lib/prawn/core/pdf_object.rb +108 -0
- data/lib/prawn/core/reference.rb +112 -0
- data/lib/prawn/core/text.rb +140 -0
- data/lib/prawn/core/text/formatted/arranger.rb +266 -0
- data/lib/prawn/core/text/formatted/line_wrap.rb +127 -0
- data/lib/prawn/core/text/formatted/wrap.rb +112 -0
- data/lib/prawn/core/text/line_wrap.rb +211 -0
- data/lib/prawn/core/text/wrap.rb +82 -0
- data/lib/prawn/document.rb +575 -0
- data/lib/prawn/document/bounding_box.rb +428 -0
- data/lib/prawn/document/graphics_state.rb +48 -0
- data/lib/prawn/document/internals.rb +170 -0
- data/lib/prawn/document/page_geometry.rb +136 -0
- data/lib/prawn/document/snapshot.rb +87 -0
- data/lib/prawn/document/span.rb +55 -0
- data/lib/prawn/encoding.rb +121 -0
- data/lib/prawn/errors.rb +86 -0
- data/lib/prawn/font.rb +368 -0
- data/lib/prawn/font/afm.rb +225 -0
- data/lib/prawn/font/dfont.rb +42 -0
- data/lib/prawn/font/ttf.rb +350 -0
- data/lib/prawn/graphics.rb +325 -0
- data/lib/prawn/graphics/cap_style.rb +38 -0
- data/lib/prawn/graphics/color.rb +205 -0
- data/lib/prawn/graphics/dash.rb +71 -0
- data/lib/prawn/graphics/join_style.rb +38 -0
- data/lib/prawn/graphics/transformation.rb +156 -0
- data/lib/prawn/graphics/transparency.rb +99 -0
- data/lib/prawn/images.rb +217 -0
- data/lib/prawn/images/jpg.rb +85 -0
- data/lib/prawn/images/png.rb +356 -0
- data/lib/prawn/layout.rb +20 -0
- data/lib/prawn/layout/grid.rb +259 -0
- data/lib/prawn/measurement_extensions.rb +46 -0
- data/lib/prawn/measurements.rb +71 -0
- data/lib/prawn/outline.rb +326 -0
- data/lib/prawn/repeater.rb +129 -0
- data/lib/prawn/security.rb +262 -0
- data/lib/prawn/security/arcfour.rb +51 -0
- data/lib/prawn/stamp.rb +126 -0
- data/lib/prawn/table.rb +451 -0
- data/lib/prawn/table/cell.rb +395 -0
- data/lib/prawn/table/cell/in_table.rb +27 -0
- data/lib/prawn/table/cell/subtable.rb +65 -0
- data/lib/prawn/table/cell/text.rb +135 -0
- data/lib/prawn/table/cells.rb +206 -0
- data/lib/prawn/text.rb +449 -0
- data/lib/prawn/text/box.rb +397 -0
- data/lib/prawn/text/formatted.rb +4 -0
- data/lib/prawn/text/formatted/box.rb +222 -0
- data/lib/prawn/text/formatted/fragment.rb +181 -0
- data/lib/prawn/text/formatted/parser.rb +213 -0
- data/prawn.gemspec +28 -0
- data/spec/annotations_spec.rb +90 -0
- data/spec/bounding_box_spec.rb +190 -0
- data/spec/cell_spec.rb +430 -0
- data/spec/destinations_spec.rb +15 -0
- data/spec/document_spec.rb +476 -0
- data/spec/extensions/mocha.rb +32 -0
- data/spec/font_spec.rb +324 -0
- data/spec/formatted_text_arranger_spec.rb +426 -0
- data/spec/formatted_text_box_spec.rb +756 -0
- data/spec/formatted_text_fragment_spec.rb +211 -0
- data/spec/graphics_spec.rb +446 -0
- data/spec/grid_spec.rb +85 -0
- data/spec/images_spec.rb +119 -0
- data/spec/inline_formatted_text_parser_spec.rb +502 -0
- data/spec/jpg_spec.rb +25 -0
- data/spec/line_wrap_spec.rb +341 -0
- data/spec/measurement_units_spec.rb +23 -0
- data/spec/name_tree_spec.rb +112 -0
- data/spec/object_store_spec.rb +160 -0
- data/spec/outline_spec.rb +404 -0
- data/spec/pdf_object_spec.rb +170 -0
- data/spec/png_spec.rb +237 -0
- data/spec/reference_spec.rb +82 -0
- data/spec/repeater_spec.rb +96 -0
- data/spec/security_spec.rb +120 -0
- data/spec/snapshot_spec.rb +154 -0
- data/spec/span_spec.rb +49 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/stamp_spec.rb +108 -0
- data/spec/stroke_styles_spec.rb +163 -0
- data/spec/table_spec.rb +687 -0
- data/spec/template_spec.rb +165 -0
- data/spec/text_at_spec.rb +125 -0
- data/spec/text_box_spec.rb +777 -0
- data/spec/text_spacing_spec.rb +75 -0
- data/spec/text_spec.rb +349 -0
- data/spec/text_with_inline_formatting_spec.rb +193 -0
- data/spec/transparency_spec.rb +89 -0
- data/vendor/pdf-inspector/README +18 -0
- data/vendor/pdf-inspector/lib/pdf/inspector.rb +26 -0
- data/vendor/pdf-inspector/lib/pdf/inspector/extgstate.rb +18 -0
- data/vendor/pdf-inspector/lib/pdf/inspector/graphics.rb +131 -0
- data/vendor/pdf-inspector/lib/pdf/inspector/page.rb +25 -0
- data/vendor/pdf-inspector/lib/pdf/inspector/text.rb +46 -0
- data/vendor/pdf-inspector/lib/pdf/inspector/xobject.rb +19 -0
- data/vendor/ttfunk/data/fonts/DejaVuSans.ttf +0 -0
- data/vendor/ttfunk/data/fonts/comicsans.ttf +0 -0
- data/vendor/ttfunk/example.rb +45 -0
- data/vendor/ttfunk/lib/ttfunk.rb +102 -0
- data/vendor/ttfunk/lib/ttfunk/directory.rb +17 -0
- data/vendor/ttfunk/lib/ttfunk/encoding/mac_roman.rb +88 -0
- data/vendor/ttfunk/lib/ttfunk/encoding/windows_1252.rb +69 -0
- data/vendor/ttfunk/lib/ttfunk/reader.rb +44 -0
- data/vendor/ttfunk/lib/ttfunk/resource_file.rb +78 -0
- data/vendor/ttfunk/lib/ttfunk/subset.rb +18 -0
- data/vendor/ttfunk/lib/ttfunk/subset/base.rb +141 -0
- data/vendor/ttfunk/lib/ttfunk/subset/mac_roman.rb +50 -0
- data/vendor/ttfunk/lib/ttfunk/subset/unicode.rb +48 -0
- data/vendor/ttfunk/lib/ttfunk/subset/unicode_8bit.rb +63 -0
- data/vendor/ttfunk/lib/ttfunk/subset/windows_1252.rb +55 -0
- data/vendor/ttfunk/lib/ttfunk/subset_collection.rb +72 -0
- data/vendor/ttfunk/lib/ttfunk/table.rb +46 -0
- data/vendor/ttfunk/lib/ttfunk/table/cmap.rb +34 -0
- data/vendor/ttfunk/lib/ttfunk/table/cmap/format00.rb +54 -0
- data/vendor/ttfunk/lib/ttfunk/table/cmap/format04.rb +126 -0
- data/vendor/ttfunk/lib/ttfunk/table/cmap/subtable.rb +79 -0
- data/vendor/ttfunk/lib/ttfunk/table/glyf.rb +64 -0
- data/vendor/ttfunk/lib/ttfunk/table/glyf/compound.rb +81 -0
- data/vendor/ttfunk/lib/ttfunk/table/glyf/simple.rb +37 -0
- data/vendor/ttfunk/lib/ttfunk/table/head.rb +44 -0
- data/vendor/ttfunk/lib/ttfunk/table/hhea.rb +41 -0
- data/vendor/ttfunk/lib/ttfunk/table/hmtx.rb +47 -0
- data/vendor/ttfunk/lib/ttfunk/table/kern.rb +79 -0
- data/vendor/ttfunk/lib/ttfunk/table/kern/format0.rb +62 -0
- data/vendor/ttfunk/lib/ttfunk/table/loca.rb +43 -0
- data/vendor/ttfunk/lib/ttfunk/table/maxp.rb +40 -0
- data/vendor/ttfunk/lib/ttfunk/table/name.rb +125 -0
- data/vendor/ttfunk/lib/ttfunk/table/os2.rb +78 -0
- data/vendor/ttfunk/lib/ttfunk/table/post.rb +91 -0
- data/vendor/ttfunk/lib/ttfunk/table/post/format10.rb +43 -0
- data/vendor/ttfunk/lib/ttfunk/table/post/format20.rb +35 -0
- data/vendor/ttfunk/lib/ttfunk/table/post/format25.rb +23 -0
- data/vendor/ttfunk/lib/ttfunk/table/post/format30.rb +17 -0
- data/vendor/ttfunk/lib/ttfunk/table/post/format40.rb +17 -0
- data/vendor/ttfunk/lib/ttfunk/table/simple.rb +14 -0
- metadata +379 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# dash.rb : Implements stroke dashing
|
4
|
+
#
|
5
|
+
# Contributed by Daniel Nelson. October, 2009
|
6
|
+
#
|
7
|
+
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
+
#
|
9
|
+
module Prawn
|
10
|
+
module Graphics
|
11
|
+
module Dash
|
12
|
+
|
13
|
+
# Sets the dash pattern for stroked lines and curves
|
14
|
+
#
|
15
|
+
# length is the length of the dash. If options is not present,
|
16
|
+
# or options[:space] is nil, then length is also the length of
|
17
|
+
# the space between dashes
|
18
|
+
#
|
19
|
+
# options may contain :space and :phase
|
20
|
+
# :space is the space between the dashes
|
21
|
+
# :phase is where in the cycle to begin dashing. For
|
22
|
+
# example, a phase of 0 starts at the beginning of
|
23
|
+
# the dash; whereas, if the phase is equal to the
|
24
|
+
# length of the dash, then stroking will begin at
|
25
|
+
# the beginning of the space. Default is 0
|
26
|
+
#
|
27
|
+
# integers or floats may be used for length and the options
|
28
|
+
#
|
29
|
+
# dash units are in PDF points ( 1/72 in )
|
30
|
+
#
|
31
|
+
def dash(length=nil, options={})
|
32
|
+
return @dash || undash_hash if length.nil?
|
33
|
+
|
34
|
+
@dash = { :dash => length,
|
35
|
+
:space => options[:space] || length,
|
36
|
+
:phase => options[:phase] || 0 }
|
37
|
+
|
38
|
+
write_stroke_dash
|
39
|
+
end
|
40
|
+
|
41
|
+
alias_method :dash=, :dash
|
42
|
+
|
43
|
+
# Stops dashing, restoring solid stroked lines and curves
|
44
|
+
#
|
45
|
+
def undash
|
46
|
+
@dash = undash_hash
|
47
|
+
write_stroke_dash
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns when stroke is dashed, false otherwise
|
51
|
+
#
|
52
|
+
def dashed?
|
53
|
+
dash != undash_hash
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def undash_hash
|
59
|
+
{ :dash => nil, :space => nil, :phase => 0 }
|
60
|
+
end
|
61
|
+
|
62
|
+
def write_stroke_dash
|
63
|
+
if @dash[:dash].nil?
|
64
|
+
add_content "[] 0 d"
|
65
|
+
return
|
66
|
+
end
|
67
|
+
add_content "[#{@dash[:dash]} #{@dash[:space]}] #{@dash[:phase]} d"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# join_style.rb : Implements stroke join styling
|
4
|
+
#
|
5
|
+
# Contributed by Daniel Nelson. October, 2009
|
6
|
+
#
|
7
|
+
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
+
#
|
9
|
+
module Prawn
|
10
|
+
module Graphics
|
11
|
+
module JoinStyle
|
12
|
+
JOIN_STYLES = { :miter => 0, :round => 1, :bevel => 2 }
|
13
|
+
|
14
|
+
# Sets the join style for stroked lines and curves
|
15
|
+
#
|
16
|
+
# style is one of :miter, :round, or :bevel
|
17
|
+
#
|
18
|
+
# NOTE: if this method is never called, :miter will be used for join style
|
19
|
+
# throughout the document
|
20
|
+
#
|
21
|
+
def join_style(style=nil)
|
22
|
+
return @join_style || :miter if style.nil?
|
23
|
+
|
24
|
+
@join_style = style
|
25
|
+
|
26
|
+
write_stroke_join_style
|
27
|
+
end
|
28
|
+
|
29
|
+
alias_method :join_style=, :join_style
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def write_stroke_join_style
|
34
|
+
add_content "#{JOIN_STYLES[@join_style]} j"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# transformation.rb: Implements rotate, translate, skew, scale and a generic
|
4
|
+
# transformation_matrix
|
5
|
+
#
|
6
|
+
# Copyright January 2010, Michael Witrant. 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 Transformation
|
13
|
+
|
14
|
+
# Rotate the user space. If a block is not provided, then you must save
|
15
|
+
# and restore the graphics state yourself.
|
16
|
+
#
|
17
|
+
# == Options
|
18
|
+
# <tt>:origin</tt>:: <tt>[number, number]</tt>. The point around which to
|
19
|
+
# rotate. A block must be provided if using the :origin
|
20
|
+
#
|
21
|
+
# raises <tt>Prawn::Errors::BlockRequired</tt> if an :origin option is
|
22
|
+
# provided, but no block is given
|
23
|
+
#
|
24
|
+
# Example without a block:
|
25
|
+
#
|
26
|
+
# save_graphics_state
|
27
|
+
# rotate 30
|
28
|
+
# text "rotated text"
|
29
|
+
# restore_graphics_state
|
30
|
+
#
|
31
|
+
# Example with a block: rotating a rectangle around its upper-left corner
|
32
|
+
#
|
33
|
+
# x = 300
|
34
|
+
# y = 300
|
35
|
+
# width = 150
|
36
|
+
# height = 200
|
37
|
+
# angle = 30
|
38
|
+
# pdf.rotate(angle, :origin => [x, y]) do
|
39
|
+
# pdf.stroke_rectangle([x, y], width, height)
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
def rotate(angle, options={}, &block)
|
43
|
+
Prawn.verify_options(:origin, options)
|
44
|
+
rad = degree_to_rad(angle)
|
45
|
+
cos = Math.cos(rad)
|
46
|
+
sin = Math.sin(rad)
|
47
|
+
if options[:origin].nil?
|
48
|
+
transformation_matrix(cos, sin, -sin, cos, 0, 0, &block)
|
49
|
+
else
|
50
|
+
raise Prawn::Errors::BlockRequired unless block_given?
|
51
|
+
x = options[:origin][0] + bounds.absolute_left
|
52
|
+
y = options[:origin][1] + bounds.absolute_bottom
|
53
|
+
x_prime = x * cos - y * sin
|
54
|
+
y_prime = x * sin + y * cos
|
55
|
+
translate(x - x_prime, y - y_prime) do
|
56
|
+
transformation_matrix(cos, sin, -sin, cos, 0, 0, &block)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Translate the user space. If a block is not provided, then you must save
|
62
|
+
# and restore the graphics state yourself.
|
63
|
+
#
|
64
|
+
# Example without a block: move the text up and over 10
|
65
|
+
#
|
66
|
+
# save_graphics_state
|
67
|
+
# translate(10, 10)
|
68
|
+
# text "scaled text"
|
69
|
+
# restore_graphics_state
|
70
|
+
#
|
71
|
+
# Example with a block: draw a rectangle with its upper-left corner at
|
72
|
+
# x + 10, y + 10
|
73
|
+
#
|
74
|
+
# x = 300
|
75
|
+
# y = 300
|
76
|
+
# width = 150
|
77
|
+
# height = 200
|
78
|
+
# pdf.translate(10, 10) do
|
79
|
+
# pdf.stroke_rectangle([x, y], width, height)
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
def translate(x, y, &block)
|
83
|
+
transformation_matrix(1, 0, 0, 1, x, y, &block)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Scale the user space. If a block is not provided, then you must save
|
87
|
+
# and restore the graphics state yourself.
|
88
|
+
#
|
89
|
+
# == Options
|
90
|
+
# <tt>:origin</tt>:: <tt>[number, number]</tt>. The point from which to
|
91
|
+
# scale. A block must be provided if using the :origin
|
92
|
+
#
|
93
|
+
# raises <tt>Prawn::Errors::BlockRequired</tt> if an :origin option is
|
94
|
+
# provided, but no block is given
|
95
|
+
#
|
96
|
+
# Example without a block:
|
97
|
+
#
|
98
|
+
# save_graphics_state
|
99
|
+
# scale 1.5
|
100
|
+
# text "scaled text"
|
101
|
+
# restore_graphics_state
|
102
|
+
#
|
103
|
+
# Example with a block: scale a rectangle from its upper-left corner
|
104
|
+
#
|
105
|
+
# x = 300
|
106
|
+
# y = 300
|
107
|
+
# width = 150
|
108
|
+
# height = 200
|
109
|
+
# factor = 1.5
|
110
|
+
# pdf.scale(angle, :origin => [x, y]) do
|
111
|
+
# pdf.stroke_rectangle([x, y], width, height)
|
112
|
+
# end
|
113
|
+
#
|
114
|
+
def scale(factor, options={}, &block)
|
115
|
+
Prawn.verify_options(:origin, options)
|
116
|
+
if options[:origin].nil?
|
117
|
+
transformation_matrix(factor, 0, 0, factor, 0, 0, &block)
|
118
|
+
else
|
119
|
+
raise Prawn::Errors::BlockRequired unless block_given?
|
120
|
+
x = options[:origin][0] + bounds.absolute_left
|
121
|
+
y = options[:origin][1] + bounds.absolute_bottom
|
122
|
+
x_prime = factor * x
|
123
|
+
y_prime = factor * y
|
124
|
+
translate(x - x_prime, y - y_prime) do
|
125
|
+
transformation_matrix(factor, 0, 0, factor, 0, 0, &block)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# The following definition of skew would only work in a clearly
|
131
|
+
# predicatable manner when if the document had no margin. don't provide
|
132
|
+
# this shortcut until it behaves in a clearly understood manner
|
133
|
+
#
|
134
|
+
# def skew(a, b, &block)
|
135
|
+
# transformation_matrix(1,
|
136
|
+
# Math.tan(degree_to_rad(a)),
|
137
|
+
# Math.tan(degree_to_rad(b)),
|
138
|
+
# 1, 0, 0, &block)
|
139
|
+
# end
|
140
|
+
|
141
|
+
# Transform the user space (see notes for rotate regarding graphics state)
|
142
|
+
# Generally, one would use the rotate, scale, translate, and skew
|
143
|
+
# convenience methods instead of calling transformation_matrix directly
|
144
|
+
def transformation_matrix(a, b, c, d, e, f)
|
145
|
+
values = [a, b, c, d, e, f].map { |x| "%.5f" % x }.join(" ")
|
146
|
+
save_graphics_state if block_given?
|
147
|
+
add_content "#{values} cm"
|
148
|
+
if block_given?
|
149
|
+
yield
|
150
|
+
restore_graphics_state
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# transparency.rb : Implements transparency
|
4
|
+
#
|
5
|
+
# Copyright October 2009, Daniel Nelson. All Rights Reserved.
|
6
|
+
#
|
7
|
+
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
+
#
|
9
|
+
|
10
|
+
module Prawn
|
11
|
+
module Graphics
|
12
|
+
|
13
|
+
# The Prawn::Transparency module is used to place transparent
|
14
|
+
# content on the page. It has the capacity for separate
|
15
|
+
# transparency values for stroked content and all other content.
|
16
|
+
#
|
17
|
+
# Example:
|
18
|
+
# # both the fill and stroke will be at 50% opacity
|
19
|
+
# pdf.transparent(0.5) do
|
20
|
+
# pdf.text("hello world")
|
21
|
+
# pdf.fill_and_stroke_circle_at([x, y], :radius => 25)
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# # the fill will be at 50% opacity, but the stroke will
|
25
|
+
# # be at 75% opacity
|
26
|
+
# pdf.transparent(0.5, 0.75) do
|
27
|
+
# pdf.text("hello world")
|
28
|
+
# pdf.fill_and_stroke_circle_at([x, y], :radius => 25)
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
module Transparency
|
32
|
+
|
33
|
+
# Sets the <tt>opacity</tt> and <tt>stroke_opacity</tt> for all
|
34
|
+
# the content within the <tt>block</tt>
|
35
|
+
# If <tt>stroke_opacity</tt> is not provided, then it takes on
|
36
|
+
# the same value as <tt>opacity</tt>
|
37
|
+
#
|
38
|
+
# Valid ranges for both paramters are 0.0 to 1.0
|
39
|
+
#
|
40
|
+
# Example:
|
41
|
+
# # both the fill and stroke will be at 50% opacity
|
42
|
+
# pdf.transparent(0.5) do
|
43
|
+
# pdf.text("hello world")
|
44
|
+
# pdf.fill_and_stroke_circle_at([x, y], :radius => 25)
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# # the fill will be at 50% opacity, but the stroke will
|
48
|
+
# # be at 75% opacity
|
49
|
+
# pdf.transparent(0.5, 0.75) do
|
50
|
+
# pdf.text("hello world")
|
51
|
+
# pdf.fill_and_stroke_circle_at([x, y], :radius => 25)
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
def transparent(opacity, stroke_opacity=opacity, &block)
|
55
|
+
min_version(1.4)
|
56
|
+
|
57
|
+
opacity = [[opacity, 0.0].max, 1.0].min
|
58
|
+
stroke_opacity = [[stroke_opacity, 0.0].max, 1.0].min
|
59
|
+
|
60
|
+
save_graphics_state
|
61
|
+
add_content "/#{opacity_dictionary_name(opacity, stroke_opacity)} gs"
|
62
|
+
yield
|
63
|
+
restore_graphics_state
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def opacity_dictionary_registry
|
69
|
+
@opacity_dictionary_registry ||= {}
|
70
|
+
end
|
71
|
+
|
72
|
+
def next_opacity_dictionary_id
|
73
|
+
opacity_dictionary_registry.length + 1
|
74
|
+
end
|
75
|
+
|
76
|
+
def opacity_dictionary_name(opacity, stroke_opacity)
|
77
|
+
key = "#{opacity}_#{stroke_opacity}"
|
78
|
+
|
79
|
+
if opacity_dictionary_registry[key]
|
80
|
+
dictionary = opacity_dictionary_registry[key][:obj]
|
81
|
+
dictionary_name = opacity_dictionary_registry[key][:name]
|
82
|
+
else
|
83
|
+
dictionary = ref!(:Type => :ExtGState,
|
84
|
+
:CA => stroke_opacity,
|
85
|
+
:ca => opacity
|
86
|
+
)
|
87
|
+
|
88
|
+
dictionary_name = "Tr#{next_opacity_dictionary_id}"
|
89
|
+
opacity_dictionary_registry[key] = { :name => dictionary_name,
|
90
|
+
:obj => dictionary }
|
91
|
+
end
|
92
|
+
|
93
|
+
page.ext_gstates.merge!(dictionary_name => dictionary)
|
94
|
+
dictionary_name
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/prawn/images.rb
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
2
|
+
# images.rb : Implements PDF image embedding
|
3
|
+
#
|
4
|
+
# Copyright April 2008, James Healy, Gregory Brown. All Rights Reserved.
|
5
|
+
#
|
6
|
+
# This is free software. Please see the LICENSE and COPYING files for details.
|
7
|
+
|
8
|
+
require 'digest/sha1'
|
9
|
+
|
10
|
+
module Prawn
|
11
|
+
|
12
|
+
module Images
|
13
|
+
|
14
|
+
# Add the image at filename to the current page. Currently only
|
15
|
+
# JPG and PNG files are supported.
|
16
|
+
#
|
17
|
+
# NOTE: Prawn is very slow at rendering PNGs with alpha channels. The
|
18
|
+
# workaround for those who don't mind installing RMagick is to use:
|
19
|
+
#
|
20
|
+
# http://github.com/amberbit/prawn-fast-png
|
21
|
+
#
|
22
|
+
# Arguments:
|
23
|
+
# <tt>file</tt>:: path to file or an object that responds to #read
|
24
|
+
#
|
25
|
+
# Options:
|
26
|
+
# <tt>:at</tt>:: an array [x,y] with the location of the top left corner of the image.
|
27
|
+
# <tt>:position</tt>:: One of (:left, :center, :right) or an x-offset
|
28
|
+
# <tt>:vposition</tt>:: One of (:top, :center, :center) or an y-offset
|
29
|
+
# <tt>:height</tt>:: the height of the image [actual height of the image]
|
30
|
+
# <tt>:width</tt>:: the width of the image [actual width of the image]
|
31
|
+
# <tt>:scale</tt>:: scale the dimensions of the image proportionally
|
32
|
+
# <tt>:fit</tt>:: scale the dimensions of the image proportionally to fit inside [width,height]
|
33
|
+
#
|
34
|
+
# Prawn::Document.generate("image2.pdf", :page_layout => :landscape) do
|
35
|
+
# pigs = "#{Prawn::BASEDIR}/data/images/pigs.jpg"
|
36
|
+
# image pigs, :at => [50,450], :width => 450
|
37
|
+
#
|
38
|
+
# dice = "#{Prawn::BASEDIR}/data/images/dice.png"
|
39
|
+
# image dice, :at => [50, 450], :scale => 0.75
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# If only one of :width / :height are provided, the image will be scaled
|
43
|
+
# proportionally. When both are provided, the image will be stretched to
|
44
|
+
# fit the dimensions without maintaining the aspect ratio.
|
45
|
+
#
|
46
|
+
#
|
47
|
+
# If :at is provided, the image will be place in the current page but
|
48
|
+
# the text position will not be changed.
|
49
|
+
#
|
50
|
+
#
|
51
|
+
# If instead of an explicit filename, an object with a read method is
|
52
|
+
# passed as +file+, you can embed images from IO objects and things
|
53
|
+
# that act like them (including Tempfiles and open-uri objects).
|
54
|
+
#
|
55
|
+
# require "open-uri"
|
56
|
+
#
|
57
|
+
# Prawn::Document.generate("remote_images.pdf") do
|
58
|
+
# image open("http://prawn.majesticseacreature.com/media/prawn_logo.png")
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# This method returns an image info object which can be used to check the
|
62
|
+
# dimensions of an image object if needed.
|
63
|
+
# (See also: Prawn::Images::PNG , Prawn::Images::JPG)
|
64
|
+
#
|
65
|
+
def image(file, options={})
|
66
|
+
Prawn.verify_options [:at, :position, :vposition, :height,
|
67
|
+
:width, :scale, :fit], options
|
68
|
+
|
69
|
+
if file.respond_to?(:read)
|
70
|
+
image_content = file.read
|
71
|
+
else
|
72
|
+
raise ArgumentError, "#{file} not found" unless File.file?(file)
|
73
|
+
image_content = File.binread(file)
|
74
|
+
end
|
75
|
+
|
76
|
+
image_sha1 = Digest::SHA1.hexdigest(image_content)
|
77
|
+
|
78
|
+
# if this image has already been embedded, just reuse it
|
79
|
+
if image_registry[image_sha1]
|
80
|
+
info = image_registry[image_sha1][:info]
|
81
|
+
image_obj = image_registry[image_sha1][:obj]
|
82
|
+
else
|
83
|
+
# Build the image object
|
84
|
+
klass = case detect_image_format(image_content)
|
85
|
+
when :jpg then Prawn::Images::JPG
|
86
|
+
when :png then Prawn::Images::PNG
|
87
|
+
end
|
88
|
+
info = klass.new(image_content)
|
89
|
+
|
90
|
+
# Bump PDF version if the image requires it
|
91
|
+
min_version(info.min_pdf_version) if info.respond_to?(:min_pdf_version)
|
92
|
+
|
93
|
+
# Add the image to the PDF and register it in case we see it again.
|
94
|
+
image_obj = info.build_pdf_object(self)
|
95
|
+
image_registry[image_sha1] = {:obj => image_obj, :info => info}
|
96
|
+
end
|
97
|
+
|
98
|
+
# find where the image will be placed and how big it will be
|
99
|
+
w,h = calc_image_dimensions(info, options)
|
100
|
+
|
101
|
+
if options[:at]
|
102
|
+
x,y = map_to_absolute(options[:at])
|
103
|
+
else
|
104
|
+
x,y = image_position(w,h,options)
|
105
|
+
move_text_position h
|
106
|
+
end
|
107
|
+
|
108
|
+
# add a reference to the image object to the current page
|
109
|
+
# resource list and give it a label
|
110
|
+
label = "I#{next_image_id}"
|
111
|
+
state.page.xobjects.merge!( label => image_obj )
|
112
|
+
|
113
|
+
# add the image to the current page
|
114
|
+
instruct = "\nq\n%.3f 0 0 %.3f %.3f %.3f cm\n/%s Do\nQ"
|
115
|
+
add_content instruct % [ w, h, x, y - h, label ]
|
116
|
+
|
117
|
+
return info
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def image_position(w,h,options)
|
123
|
+
options[:position] ||= :left
|
124
|
+
|
125
|
+
x = case options[:position]
|
126
|
+
when :left
|
127
|
+
bounds.absolute_left
|
128
|
+
when :center
|
129
|
+
bounds.absolute_left + (bounds.width - w) / 2.0
|
130
|
+
when :right
|
131
|
+
bounds.absolute_right - w
|
132
|
+
when Numeric
|
133
|
+
options[:position] + bounds.absolute_left
|
134
|
+
end
|
135
|
+
|
136
|
+
y = case options[:vposition]
|
137
|
+
when :top
|
138
|
+
bounds.absolute_top
|
139
|
+
when :center
|
140
|
+
bounds.absolute_top - (bounds.height - h) / 2.0
|
141
|
+
when :bottom
|
142
|
+
bounds.absolute_bottom + h
|
143
|
+
when Numeric
|
144
|
+
bounds.absolute_top - options[:vposition]
|
145
|
+
else
|
146
|
+
determine_y_with_page_flow(h)
|
147
|
+
end
|
148
|
+
return [x,y]
|
149
|
+
end
|
150
|
+
|
151
|
+
def determine_y_with_page_flow(h)
|
152
|
+
if overruns_page?(h)
|
153
|
+
start_new_page
|
154
|
+
bounds.absolute_top
|
155
|
+
else
|
156
|
+
self.y
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def overruns_page?(h)
|
161
|
+
(self.y - h) < bounds.absolute_bottom
|
162
|
+
end
|
163
|
+
|
164
|
+
def calc_image_dimensions(info, options)
|
165
|
+
w = options[:width] || info.width
|
166
|
+
h = options[:height] || info.height
|
167
|
+
|
168
|
+
if options[:width] && !options[:height]
|
169
|
+
wp = w / info.width.to_f
|
170
|
+
w = info.width * wp
|
171
|
+
h = info.height * wp
|
172
|
+
elsif options[:height] && !options[:width]
|
173
|
+
hp = h / info.height.to_f
|
174
|
+
w = info.width * hp
|
175
|
+
h = info.height * hp
|
176
|
+
elsif options[:scale]
|
177
|
+
w = info.width * options[:scale]
|
178
|
+
h = info.height * options[:scale]
|
179
|
+
elsif options[:fit]
|
180
|
+
bw, bh = options[:fit]
|
181
|
+
bp = bw / bh.to_f
|
182
|
+
ip = info.width / info.height.to_f
|
183
|
+
if ip > bp
|
184
|
+
w = bw
|
185
|
+
h = bw / ip
|
186
|
+
else
|
187
|
+
h = bh
|
188
|
+
w = bh * ip
|
189
|
+
end
|
190
|
+
end
|
191
|
+
info.scaled_width = w
|
192
|
+
info.scaled_height = h
|
193
|
+
[w,h]
|
194
|
+
end
|
195
|
+
|
196
|
+
def detect_image_format(content)
|
197
|
+
top = content[0,128]
|
198
|
+
|
199
|
+
if top[0, 3] == "\xff\xd8\xff"
|
200
|
+
return :jpg
|
201
|
+
elsif top[0, 8] == "\x89PNG\x0d\x0a\x1a\x0a"
|
202
|
+
return :png
|
203
|
+
else
|
204
|
+
raise Errors::UnsupportedImageType, "image file is an unrecognised format"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def image_registry
|
209
|
+
@image_registry ||= {}
|
210
|
+
end
|
211
|
+
|
212
|
+
def next_image_id
|
213
|
+
@image_counter ||= 0
|
214
|
+
@image_counter += 1
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|