prawn 2.1.0 → 2.2.0
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +0 -0
- data/Gemfile +1 -9
- data/Rakefile +12 -22
- data/lib/prawn.rb +29 -48
- data/lib/prawn/document.rb +148 -123
- data/lib/prawn/document/bounding_box.rb +33 -26
- data/lib/prawn/document/column_box.rb +5 -7
- data/lib/prawn/document/internals.rb +6 -6
- data/lib/prawn/document/span.rb +20 -17
- data/lib/prawn/encoding.rb +65 -67
- data/lib/prawn/errors.rb +10 -7
- data/lib/prawn/font.rb +78 -62
- data/lib/prawn/font/afm.rb +93 -66
- data/lib/prawn/font/dfont.rb +2 -10
- data/lib/prawn/font/ttc.rb +34 -0
- data/lib/prawn/font/ttf.rb +73 -65
- data/lib/prawn/font_metric_cache.rb +9 -8
- data/lib/prawn/graphics.rb +110 -70
- data/lib/prawn/graphics/blend_mode.rb +7 -8
- data/lib/prawn/graphics/cap_style.rb +2 -4
- data/lib/prawn/graphics/color.rb +23 -26
- data/lib/prawn/graphics/dash.rb +22 -12
- data/lib/prawn/graphics/join_style.rb +8 -4
- data/lib/prawn/graphics/patterns.rb +185 -96
- data/lib/prawn/graphics/transformation.rb +11 -9
- data/lib/prawn/graphics/transparency.rb +15 -13
- data/lib/prawn/grid.rb +20 -20
- data/lib/prawn/image_handler.rb +4 -6
- data/lib/prawn/images.rb +22 -15
- data/lib/prawn/images/image.rb +0 -1
- data/lib/prawn/images/jpg.rb +26 -22
- data/lib/prawn/images/png.rb +60 -57
- data/lib/prawn/measurement_extensions.rb +8 -9
- data/lib/prawn/measurements.rb +14 -15
- data/lib/prawn/outline.rb +96 -78
- data/lib/prawn/repeater.rb +12 -10
- data/lib/prawn/security.rb +66 -48
- data/lib/prawn/security/arcfour.rb +1 -3
- data/lib/prawn/soft_mask.rb +23 -25
- data/lib/prawn/stamp.rb +16 -12
- data/lib/prawn/text.rb +59 -45
- data/lib/prawn/text/box.rb +9 -8
- data/lib/prawn/text/formatted.rb +4 -6
- data/lib/prawn/text/formatted/arranger.rb +51 -30
- data/lib/prawn/text/formatted/box.rb +112 -88
- data/lib/prawn/text/formatted/fragment.rb +10 -15
- data/lib/prawn/text/formatted/line_wrap.rb +118 -61
- data/lib/prawn/text/formatted/parser.rb +134 -110
- data/lib/prawn/text/formatted/wrap.rb +42 -32
- data/lib/prawn/transformation_stack.rb +3 -4
- data/lib/prawn/utilities.rb +6 -21
- data/lib/prawn/version.rb +1 -3
- data/lib/prawn/view.rb +4 -2
- data/manual/basic_concepts/adding_pages.rb +4 -7
- data/manual/basic_concepts/basic_concepts.rb +29 -22
- data/manual/basic_concepts/creation.rb +8 -11
- data/manual/basic_concepts/cursor.rb +2 -5
- data/manual/basic_concepts/measurement.rb +3 -6
- data/manual/basic_concepts/origin.rb +3 -6
- data/manual/basic_concepts/other_cursor_helpers.rb +9 -12
- data/manual/basic_concepts/view.rb +20 -16
- data/manual/bounding_box/bounding_box.rb +27 -24
- data/manual/bounding_box/bounds.rb +9 -12
- data/manual/bounding_box/canvas.rb +2 -5
- data/manual/bounding_box/creation.rb +4 -7
- data/manual/bounding_box/indentation.rb +12 -15
- data/manual/bounding_box/nesting.rb +22 -17
- data/manual/bounding_box/russian_boxes.rb +8 -9
- data/manual/bounding_box/stretchy.rb +10 -13
- data/manual/contents.rb +26 -22
- data/manual/cover.rb +22 -20
- data/manual/document_and_page_options/background.rb +9 -13
- data/manual/document_and_page_options/document_and_page_options.rb +23 -20
- data/manual/document_and_page_options/metadata.rb +16 -16
- data/manual/document_and_page_options/page_margins.rb +16 -20
- data/manual/document_and_page_options/page_size.rb +11 -12
- data/manual/document_and_page_options/print_scaling.rb +15 -15
- data/manual/example_helper.rb +2 -4
- data/manual/graphics/blend_mode.rb +10 -9
- data/manual/graphics/circle_and_ellipse.rb +2 -5
- data/manual/graphics/color.rb +5 -9
- data/manual/graphics/common_lines.rb +5 -8
- data/manual/graphics/fill_and_stroke.rb +2 -5
- data/manual/graphics/fill_rules.rb +7 -10
- data/manual/graphics/gradients.rb +25 -21
- data/manual/graphics/graphics.rb +49 -43
- data/manual/graphics/helper.rb +10 -9
- data/manual/graphics/line_width.rb +5 -7
- data/manual/graphics/lines_and_curves.rb +5 -8
- data/manual/graphics/polygon.rb +4 -8
- data/manual/graphics/rectangle.rb +2 -5
- data/manual/graphics/rotate.rb +4 -7
- data/manual/graphics/scale.rb +12 -15
- data/manual/graphics/soft_masks.rb +1 -4
- data/manual/graphics/stroke_cap.rb +3 -6
- data/manual/graphics/stroke_dash.rb +9 -12
- data/manual/graphics/stroke_join.rb +2 -5
- data/manual/graphics/translate.rb +7 -10
- data/manual/graphics/transparency.rb +5 -8
- data/manual/how_to_read_this_manual.rb +4 -6
- data/manual/images/absolute_position.rb +4 -7
- data/manual/images/fit.rb +5 -8
- data/manual/images/horizontal.rb +6 -9
- data/manual/images/images.rb +25 -23
- data/manual/images/plain_image.rb +3 -6
- data/manual/images/scale.rb +7 -10
- data/manual/images/vertical.rb +10 -13
- data/manual/images/width_and_height.rb +8 -11
- data/manual/layout/boxes.rb +3 -6
- data/manual/layout/content.rb +5 -8
- data/manual/layout/layout.rb +16 -16
- data/manual/layout/simple_grid.rb +4 -7
- data/manual/outline/add_subsection_to.rb +18 -21
- data/manual/outline/insert_section_after.rb +13 -16
- data/manual/outline/outline.rb +19 -17
- data/manual/outline/sections_and_pages.rb +15 -18
- data/manual/repeatable_content/alternate_page_numbering.rb +19 -17
- data/manual/repeatable_content/page_numbering.rb +15 -16
- data/manual/repeatable_content/repeatable_content.rb +23 -19
- data/manual/repeatable_content/repeater.rb +12 -15
- data/manual/repeatable_content/stamp.rb +12 -15
- data/manual/security/encryption.rb +7 -10
- data/manual/security/permissions.rb +17 -14
- data/manual/security/security.rb +17 -16
- data/manual/table.rb +2 -4
- data/manual/text/alignment.rb +14 -17
- data/manual/text/color.rb +10 -11
- data/manual/text/column_box.rb +5 -8
- data/manual/text/fallback_fonts.rb +23 -21
- data/manual/text/font.rb +9 -12
- data/manual/text/font_size.rb +11 -14
- data/manual/text/font_style.rb +4 -7
- data/manual/text/formatted_callbacks.rb +23 -21
- data/manual/text/formatted_text.rb +31 -25
- data/manual/text/free_flowing_text.rb +18 -21
- data/manual/text/inline.rb +16 -19
- data/manual/text/kerning_and_character_spacing.rb +12 -15
- data/manual/text/leading.rb +5 -8
- data/manual/text/line_wrapping.rb +33 -17
- data/manual/text/paragraph_indentation.rb +11 -14
- data/manual/text/positioned_text.rb +13 -16
- data/manual/text/registering_families.rb +16 -19
- data/manual/text/rendering_and_color.rb +7 -10
- data/manual/text/right_to_left_text.rb +24 -19
- data/manual/text/rotation.rb +26 -23
- data/manual/text/single_usage.rb +6 -9
- data/manual/text/text.rb +56 -52
- data/manual/text/text_box_excess.rb +18 -17
- data/manual/text/text_box_extensions.rb +16 -15
- data/manual/text/text_box_overflow.rb +15 -18
- data/manual/text/utf8.rb +9 -12
- data/manual/text/win_ansi_charset.rb +18 -19
- data/prawn.gemspec +37 -27
- data/spec/extensions/encoding_helpers.rb +0 -2
- data/spec/manual_spec.rb +33 -0
- data/spec/prawn/document/bounding_box_spec.rb +546 -0
- data/spec/prawn/document/column_box_spec.rb +73 -0
- data/spec/prawn/document/security_spec.rb +173 -0
- data/spec/prawn/document_annotations_spec.rb +74 -0
- data/spec/prawn/document_destinations_spec.rb +13 -0
- data/spec/prawn/document_grid_spec.rb +96 -0
- data/spec/prawn/document_reference_spec.rb +25 -0
- data/spec/prawn/document_span_spec.rb +34 -0
- data/spec/prawn/document_spec.rb +751 -0
- data/spec/prawn/font_metric_cache_spec.rb +52 -0
- data/spec/prawn/font_spec.rb +513 -0
- data/spec/prawn/graphics/blend_mode_spec.rb +61 -0
- data/spec/prawn/graphics/transparency_spec.rb +79 -0
- data/spec/prawn/graphics_spec.rb +817 -0
- data/spec/prawn/graphics_stroke_styles_spec.rb +227 -0
- data/spec/{image_handler_spec.rb → prawn/image_handler_spec.rb} +13 -15
- data/spec/prawn/images/jpg_spec.rb +18 -0
- data/spec/prawn/images/png_spec.rb +281 -0
- data/spec/prawn/images_spec.rb +170 -0
- data/spec/prawn/measurements_extensions_spec.rb +22 -0
- data/spec/prawn/outline_spec.rb +408 -0
- data/spec/prawn/repeater_spec.rb +163 -0
- data/spec/prawn/soft_mask_spec.rb +72 -0
- data/spec/prawn/stamp_spec.rb +168 -0
- data/spec/prawn/text/box_spec.rb +1113 -0
- data/spec/prawn/text/formatted/arranger_spec.rb +464 -0
- data/spec/prawn/text/formatted/box_spec.rb +825 -0
- data/spec/prawn/text/formatted/fragment_spec.rb +341 -0
- data/spec/prawn/text/formatted/line_wrap_spec.rb +491 -0
- data/spec/prawn/text/formatted/parser_spec.rb +667 -0
- data/spec/prawn/text_draw_text_spec.rb +147 -0
- data/spec/prawn/text_rendering_mode_spec.rb +42 -0
- data/spec/prawn/text_spacing_spec.rb +93 -0
- data/spec/prawn/text_spec.rb +601 -0
- data/spec/prawn/text_with_inline_formatting_spec.rb +33 -0
- data/spec/{transformation_stack_spec.rb → prawn/transformation_stack_spec.rb} +21 -20
- data/spec/prawn/view_spec.rb +45 -0
- data/spec/spec_helper.rb +16 -16
- metadata +96 -151
- metadata.gz.sig +1 -0
- data/data/images/16bit.alpha +0 -0
- data/data/images/16bit.color +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/blend_modes_bottom_layer.jpg +0 -0
- data/data/images/blend_modes_top_layer.jpg +0 -0
- data/data/images/dice.alpha +0 -0
- data/data/images/dice.color +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/indexed_color.dat +0 -0
- data/data/images/indexed_color.png +0 -0
- data/data/images/indexed_transparency.png +0 -0
- data/data/images/indexed_transparency_alpha.dat +0 -0
- data/data/images/indexed_transparency_color.dat +0 -0
- data/data/images/letterhead.jpg +0 -0
- data/data/images/license.md +0 -8
- data/data/images/page_white_text.alpha +0 -0
- data/data/images/page_white_text.color +0 -0
- data/data/images/page_white_text.png +0 -0
- data/data/images/pigs.jpg +0 -0
- data/data/images/prawn.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 +0 -1
- 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/form.pdf +1 -819
- data/data/pdfs/hexagon.pdf +0 -61
- data/data/pdfs/indirect_reference.pdf +0 -86
- data/data/pdfs/multipage_template.pdf +0 -127
- data/data/pdfs/nested_pages.pdf +0 -118
- data/data/pdfs/page_without_mediabox.pdf +0 -193
- data/data/pdfs/resources_as_indirect_object.pdf +0 -83
- data/data/pdfs/two_hexagons.pdf +0 -90
- data/data/pdfs/version_1_6.pdf +0 -61
- data/data/shift_jis_text.txt +0 -1
- data/spec/acceptance/png_spec.rb +0 -35
- data/spec/annotations_spec.rb +0 -67
- data/spec/blend_mode_spec.rb +0 -71
- data/spec/bounding_box_spec.rb +0 -501
- data/spec/column_box_spec.rb +0 -59
- data/spec/destinations_spec.rb +0 -13
- data/spec/document_spec.rb +0 -738
- data/spec/font_metric_cache_spec.rb +0 -52
- data/spec/font_spec.rb +0 -475
- data/spec/formatted_text_arranger_spec.rb +0 -452
- data/spec/formatted_text_box_spec.rb +0 -716
- data/spec/formatted_text_fragment_spec.rb +0 -299
- data/spec/graphics_spec.rb +0 -705
- data/spec/grid_spec.rb +0 -95
- data/spec/images_spec.rb +0 -167
- data/spec/inline_formatted_text_parser_spec.rb +0 -568
- data/spec/jpg_spec.rb +0 -23
- data/spec/line_wrap_spec.rb +0 -366
- data/spec/measurement_units_spec.rb +0 -22
- data/spec/outline_spec.rb +0 -409
- data/spec/png_spec.rb +0 -257
- data/spec/reference_spec.rb +0 -25
- data/spec/repeater_spec.rb +0 -154
- data/spec/security_spec.rb +0 -151
- data/spec/soft_mask_spec.rb +0 -78
- data/spec/span_spec.rb +0 -43
- data/spec/stamp_spec.rb +0 -179
- data/spec/stroke_styles_spec.rb +0 -208
- data/spec/text_at_spec.rb +0 -142
- data/spec/text_box_spec.rb +0 -1042
- data/spec/text_rendering_mode_spec.rb +0 -45
- data/spec/text_spacing_spec.rb +0 -93
- data/spec/text_spec.rb +0 -543
- data/spec/text_with_inline_formatting_spec.rb +0 -35
- data/spec/transparency_spec.rb +0 -91
- data/spec/view_spec.rb +0 -42
data/lib/prawn/font/dfont.rb
CHANGED
@@ -1,11 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
#
|
3
|
-
# font.rb : The Prawn font class
|
4
|
-
#
|
5
|
-
# Copyright November 2008, Jamis Buck. All Rights Reserved.
|
6
|
-
#
|
7
|
-
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
-
#
|
9
1
|
require_relative 'ttf'
|
10
2
|
|
11
3
|
module Prawn
|
@@ -20,7 +12,7 @@ module Prawn
|
|
20
12
|
#
|
21
13
|
def self.named_fonts(file)
|
22
14
|
TTFunk::ResourceFile.open(file) do |f|
|
23
|
-
return f.resources_for(
|
15
|
+
return f.resources_for('sfnt')
|
24
16
|
end
|
25
17
|
end
|
26
18
|
|
@@ -28,7 +20,7 @@ module Prawn
|
|
28
20
|
#
|
29
21
|
def self.font_count(file)
|
30
22
|
TTFunk::ResourceFile.open(file) do |f|
|
31
|
-
return f.map[
|
23
|
+
return f.map['sfnt'][:list].length
|
32
24
|
end
|
33
25
|
end
|
34
26
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative 'ttf'
|
2
|
+
|
3
|
+
module Prawn
|
4
|
+
class Font
|
5
|
+
# @private
|
6
|
+
class TTC < TTF
|
7
|
+
# Returns a list of the names of all named fonts in the given ttc file.
|
8
|
+
# They are returned in order of their appearance in the file.
|
9
|
+
#
|
10
|
+
def self.font_names(file)
|
11
|
+
TTFunk::Collection.open(file) do |ttc|
|
12
|
+
ttc.map { |font| font.name.font_name.first }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def read_ttf_file
|
19
|
+
TTFunk::File.from_ttc(
|
20
|
+
@name,
|
21
|
+
font_option_to_index(@name, @options[:font])
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def font_option_to_index(file, option)
|
26
|
+
if option.is_a?(Numeric)
|
27
|
+
option
|
28
|
+
else
|
29
|
+
self.class.font_names(file).index { |n| n == option } || 0
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/prawn/font/ttf.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
# prawn/font/ttf.rb : Implements AFM font support for Prawn
|
4
2
|
#
|
5
3
|
# Copyright May 2008, Gregory Brown / James Healy / Jamis Buck
|
@@ -23,17 +21,17 @@ module Prawn
|
|
23
21
|
def initialize(document, name, options = {})
|
24
22
|
super
|
25
23
|
|
26
|
-
@ttf
|
27
|
-
@subsets
|
24
|
+
@ttf = read_ttf_file
|
25
|
+
@subsets = TTFunk::SubsetCollection.new(@ttf)
|
28
26
|
|
29
|
-
@attributes
|
30
|
-
@bounding_boxes
|
31
|
-
@char_widths
|
27
|
+
@attributes = {}
|
28
|
+
@bounding_boxes = {}
|
29
|
+
@char_widths = {}
|
32
30
|
@has_kerning_data = @ttf.kerning.exists? && @ttf.kerning.tables.any?
|
33
31
|
|
34
|
-
@ascender
|
35
|
-
@descender
|
36
|
-
@line_gap
|
32
|
+
@ascender = Integer(@ttf.ascent * scale_factor)
|
33
|
+
@descender = Integer(@ttf.descent * scale_factor)
|
34
|
+
@line_gap = Integer(@ttf.line_gap * scale_factor)
|
37
35
|
end
|
38
36
|
|
39
37
|
# NOTE: +string+ must be UTF8-encoded.
|
@@ -44,7 +42,7 @@ module Prawn
|
|
44
42
|
if r.is_a?(Numeric)
|
45
43
|
s - r
|
46
44
|
else
|
47
|
-
r.inject(s) { |
|
45
|
+
r.inject(s) { |a, e| a + character_width_by_code(e) }
|
48
46
|
end
|
49
47
|
end * scale
|
50
48
|
else
|
@@ -80,7 +78,9 @@ module Prawn
|
|
80
78
|
last_subset = nil
|
81
79
|
kern(text).inject([]) do |result, element|
|
82
80
|
if element.is_a?(Numeric)
|
83
|
-
|
81
|
+
unless result.last[1].is_a?(Array)
|
82
|
+
result.last[1] = [result.last[1]]
|
83
|
+
end
|
84
84
|
result.last[1] << element
|
85
85
|
result
|
86
86
|
else
|
@@ -100,7 +100,7 @@ module Prawn
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
else
|
103
|
-
@subsets.encode(text.unpack(
|
103
|
+
@subsets.encode(text.unpack('U*'))
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -109,7 +109,7 @@ module Prawn
|
|
109
109
|
end
|
110
110
|
|
111
111
|
# not sure how to compute this for true-type fonts...
|
112
|
-
def stemV
|
112
|
+
def stemV # rubocop: disable Style/MethodName
|
113
113
|
0
|
114
114
|
end
|
115
115
|
|
@@ -118,7 +118,8 @@ module Prawn
|
|
118
118
|
|
119
119
|
if @ttf.postscript.exists?
|
120
120
|
raw = @ttf.postscript.italic_angle
|
121
|
-
hi
|
121
|
+
hi = raw >> 16
|
122
|
+
low = raw & 0xFF
|
122
123
|
hi = -((hi ^ 0xFFFF) + 1) if hi & 0x8000 != 0
|
123
124
|
@italic_angle = "#{hi}.#{low}".to_f
|
124
125
|
else
|
@@ -131,7 +132,7 @@ module Prawn
|
|
131
132
|
def cap_height
|
132
133
|
@cap_height ||= begin
|
133
134
|
height = @ttf.os2.exists? && @ttf.os2.cap_height || 0
|
134
|
-
height
|
135
|
+
height.zero? ? @ascender : height
|
135
136
|
end
|
136
137
|
end
|
137
138
|
|
@@ -160,24 +161,23 @@ module Prawn
|
|
160
161
|
flags |= 0x0002 if serif?
|
161
162
|
flags |= 0x0008 if script?
|
162
163
|
flags |= 0x0040 if italic_angle != 0
|
163
|
-
|
164
|
+
# Assume the font contains at least some non-latin characters
|
165
|
+
flags | 0x0004
|
164
166
|
end
|
165
167
|
end
|
166
168
|
|
167
169
|
def normalize_encoding(text)
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
"to use is set correctly"
|
176
|
-
end
|
170
|
+
text.encode(::Encoding::UTF_8)
|
171
|
+
rescue => e
|
172
|
+
puts e
|
173
|
+
raise Prawn::Errors::IncompatibleStringEncoding, 'Encoding ' \
|
174
|
+
"#{text.encoding} can not be transparently converted to UTF-8. " \
|
175
|
+
'Please ensure the encoding of the string you are attempting ' \
|
176
|
+
'to use is set correctly'
|
177
177
|
end
|
178
178
|
|
179
179
|
def to_utf8(text)
|
180
|
-
text.encode(
|
180
|
+
text.encode('UTF-8')
|
181
181
|
end
|
182
182
|
|
183
183
|
def glyph_present?(char)
|
@@ -194,7 +194,7 @@ module Prawn
|
|
194
194
|
private
|
195
195
|
|
196
196
|
def cmap
|
197
|
-
@cmap ||= @ttf.cmap.unicode.first
|
197
|
+
(@cmap ||= @ttf.cmap.unicode.first) || raise('no unicode cmap for font')
|
198
198
|
end
|
199
199
|
|
200
200
|
# +string+ must be UTF8-encoded.
|
@@ -220,12 +220,12 @@ module Prawn
|
|
220
220
|
end
|
221
221
|
|
222
222
|
def kern_pairs_table
|
223
|
-
@kerning_data ||=
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
223
|
+
@kerning_data ||=
|
224
|
+
if has_kerning_data?
|
225
|
+
@ttf.kerning.tables.first.pairs
|
226
|
+
else
|
227
|
+
{}
|
228
|
+
end
|
229
229
|
end
|
230
230
|
|
231
231
|
def hmtx
|
@@ -247,12 +247,12 @@ module Prawn
|
|
247
247
|
end
|
248
248
|
|
249
249
|
def register(subset)
|
250
|
-
temp_name = @ttf.name.postscript_name.
|
251
|
-
ref = @document.ref!(:
|
250
|
+
temp_name = @ttf.name.postscript_name.delete("\0").to_sym
|
251
|
+
ref = @document.ref!(Type: :Font, BaseFont: temp_name)
|
252
252
|
|
253
253
|
# Embed the font metrics in the document after everything has been
|
254
254
|
# drawn, just before the document is emitted.
|
255
|
-
@document.renderer.before_render { |
|
255
|
+
@document.renderer.before_render { |_doc| embed(ref, subset) }
|
256
256
|
|
257
257
|
ref
|
258
258
|
end
|
@@ -267,29 +267,32 @@ module Prawn
|
|
267
267
|
|
268
268
|
# empirically, it looks like Adobe Reader will not display fonts
|
269
269
|
# if their font name is more than 33 bytes long. Strange. But true.
|
270
|
-
basename = font.name.postscript_name[0, 33].
|
270
|
+
basename = font.name.postscript_name[0, 33].delete("\0")
|
271
271
|
|
272
|
-
|
272
|
+
raise "Can't detect a postscript name for #{file}" if basename.nil?
|
273
273
|
|
274
|
-
fontfile = @document.ref!(:
|
274
|
+
fontfile = @document.ref!(Length1: font_content.size)
|
275
275
|
fontfile.stream << font_content
|
276
276
|
fontfile.stream.compress!
|
277
277
|
|
278
|
-
descriptor = @document.ref!(
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
278
|
+
descriptor = @document.ref!(
|
279
|
+
Type: :FontDescriptor,
|
280
|
+
FontName: basename.to_sym,
|
281
|
+
FontFile2: fontfile,
|
282
|
+
FontBBox: bbox,
|
283
|
+
Flags: pdf_flags,
|
284
|
+
StemV: stemV,
|
285
|
+
ItalicAngle: italic_angle,
|
286
|
+
Ascent: @ascender,
|
287
|
+
Descent: @descender,
|
288
|
+
CapHeight: cap_height,
|
289
|
+
XHeight: x_height
|
290
|
+
)
|
289
291
|
|
290
292
|
hmtx = font.horizontal_metrics
|
291
|
-
widths = font.cmap.tables.first.code_map.map
|
292
|
-
Integer(hmtx.widths[gid] * scale_factor)
|
293
|
+
widths = font.cmap.tables.first.code_map.map do |gid|
|
294
|
+
Integer(hmtx.widths[gid] * scale_factor)
|
295
|
+
end[32..-1]
|
293
296
|
|
294
297
|
# It would be nice to have Encoding set for the macroman subsets,
|
295
298
|
# and only do a ToUnicode cmap for non-encoded unicode subsets.
|
@@ -304,14 +307,17 @@ module Prawn
|
|
304
307
|
map = @subsets[subset].to_unicode_map
|
305
308
|
|
306
309
|
ranges = [[]]
|
307
|
-
map.keys.sort.inject(
|
310
|
+
map.keys.sort.inject('') do |_s, code|
|
308
311
|
ranges << [] if ranges.last.length >= 100
|
309
312
|
unicode = map[code]
|
310
|
-
ranges.last <<
|
313
|
+
ranges.last << format('<%02x><%04x>', code, unicode)
|
311
314
|
end
|
312
315
|
|
313
|
-
range_blocks = ranges.inject(
|
314
|
-
s <<
|
316
|
+
range_blocks = ranges.inject('') do |s, list|
|
317
|
+
s << format(
|
318
|
+
"%d beginbfchar\n%s\nendbfchar\n",
|
319
|
+
list.length, list.join("\n")
|
320
|
+
)
|
315
321
|
end
|
316
322
|
|
317
323
|
to_unicode_cmap = UNICODE_CMAP_TEMPLATE % range_blocks.strip
|
@@ -320,16 +326,18 @@ module Prawn
|
|
320
326
|
cmap << to_unicode_cmap
|
321
327
|
cmap.stream.compress!
|
322
328
|
|
323
|
-
reference.data.update(
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
329
|
+
reference.data.update(
|
330
|
+
Subtype: :TrueType,
|
331
|
+
BaseFont: basename.to_sym,
|
332
|
+
FontDescriptor: descriptor,
|
333
|
+
FirstChar: 32,
|
334
|
+
LastChar: 255,
|
335
|
+
Widths: @document.ref!(widths),
|
336
|
+
ToUnicode: cmap
|
337
|
+
)
|
330
338
|
end
|
331
339
|
|
332
|
-
UNICODE_CMAP_TEMPLATE = <<-STR.strip.gsub(/^\s*/,
|
340
|
+
UNICODE_CMAP_TEMPLATE = <<-STR.strip.gsub(/^\s*/, '')
|
333
341
|
/CIDInit /ProcSet findresource begin
|
334
342
|
12 dict begin
|
335
343
|
begincmap
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
#
|
3
1
|
# font_metric_cache.rb : The Prawn font class
|
4
2
|
#
|
5
3
|
# Copyright Dec 2012, Kenneth Kalmer. All Rights Reserved.
|
@@ -24,19 +22,22 @@ module Prawn
|
|
24
22
|
def width_of(string, options)
|
25
23
|
f = if options[:style]
|
26
24
|
# override style with :style => :bold
|
27
|
-
@document.find_font(@document.font.family, :
|
25
|
+
@document.find_font(@document.font.family, style: options[:style])
|
28
26
|
else
|
29
27
|
@document.font
|
30
28
|
end
|
31
29
|
|
32
|
-
|
30
|
+
encoded_string = f.normalize_encoding(string)
|
31
|
+
|
32
|
+
key = CacheEntry.new(f, options, encoded_string)
|
33
|
+
|
34
|
+
@cache[key] ||= f.compute_width_of(encoded_string, options)
|
33
35
|
|
34
|
-
|
35
|
-
length = @cache[ key ] = f.compute_width_of(string, options)
|
36
|
-
end
|
36
|
+
length = @cache[key]
|
37
37
|
|
38
38
|
length +
|
39
|
-
(@document.character_spacing *
|
39
|
+
(@document.character_spacing *
|
40
|
+
@document.font.character_count(encoded_string))
|
40
41
|
end
|
41
42
|
end
|
42
43
|
end
|
data/lib/prawn/graphics.rb
CHANGED
@@ -1,19 +1,17 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
# graphics.rb : Implements PDF drawing primitives
|
4
2
|
#
|
5
3
|
# Copyright April 2008, Gregory Brown. All Rights Reserved.
|
6
4
|
#
|
7
5
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
6
|
|
9
|
-
require_relative
|
10
|
-
require_relative
|
11
|
-
require_relative
|
12
|
-
require_relative
|
13
|
-
require_relative
|
14
|
-
require_relative
|
15
|
-
require_relative
|
16
|
-
require_relative
|
7
|
+
require_relative 'graphics/blend_mode'
|
8
|
+
require_relative 'graphics/color'
|
9
|
+
require_relative 'graphics/dash'
|
10
|
+
require_relative 'graphics/cap_style'
|
11
|
+
require_relative 'graphics/join_style'
|
12
|
+
require_relative 'graphics/transparency'
|
13
|
+
require_relative 'graphics/transformation'
|
14
|
+
require_relative 'graphics/patterns'
|
17
15
|
|
18
16
|
module Prawn
|
19
17
|
# Implements the drawing facilities for Prawn::Document.
|
@@ -66,9 +64,11 @@ module Prawn
|
|
66
64
|
# pdf.curve_to [100,100], :bounds => [[90,90],[75,75]]
|
67
65
|
#
|
68
66
|
def curve_to(dest, options = {})
|
69
|
-
options[:bounds]
|
70
|
-
|
71
|
-
|
67
|
+
options[:bounds] || raise(
|
68
|
+
Prawn::Errors::InvalidGraphicsPath,
|
69
|
+
'Bounding points for bezier curve must be specified ' \
|
70
|
+
'as :bounds => [[x1,y1],[x2,y2]]'
|
71
|
+
)
|
72
72
|
|
73
73
|
curve_points = PDF::Core.real_params(
|
74
74
|
(options[:bounds] << dest).flat_map { |e| map_to_absolute(e) }
|
@@ -97,7 +97,9 @@ module Prawn
|
|
97
97
|
#
|
98
98
|
def rounded_rectangle(point, width, height, radius)
|
99
99
|
x, y = point
|
100
|
-
rounded_polygon(
|
100
|
+
rounded_polygon(
|
101
|
+
radius, point, [x + width, y], [x + width, y - height], [x, y - height]
|
102
|
+
)
|
101
103
|
end
|
102
104
|
|
103
105
|
###########################################################
|
@@ -146,11 +148,11 @@ module Prawn
|
|
146
148
|
# horizontal_line 25, 100, :at => 75
|
147
149
|
#
|
148
150
|
def horizontal_line(x1, x2, options = {})
|
149
|
-
if options[:at]
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
151
|
+
y1 = if options[:at]
|
152
|
+
options[:at]
|
153
|
+
else
|
154
|
+
y - bounds.absolute_bottom
|
155
|
+
end
|
154
156
|
|
155
157
|
line(x1, y1, x2, y1)
|
156
158
|
end
|
@@ -186,9 +188,9 @@ module Prawn
|
|
186
188
|
#
|
187
189
|
KAPPA = 4.0 * ((Math.sqrt(2) - 1.0) / 3.0)
|
188
190
|
|
189
|
-
# Draws a circle of radius <tt>radius</tt> with the centre-point at
|
190
|
-
# as a complete subpath. The drawing point will be moved to
|
191
|
-
# centre-point upon completion of the drawing the circle.
|
191
|
+
# Draws a circle of radius <tt>radius</tt> with the centre-point at
|
192
|
+
# <tt>point</tt> as a complete subpath. The drawing point will be moved to
|
193
|
+
# the centre-point upon completion of the drawing the circle.
|
192
194
|
#
|
193
195
|
# pdf.circle [100,100], 25
|
194
196
|
#
|
@@ -213,19 +215,19 @@ module Prawn
|
|
213
215
|
|
214
216
|
# Upper right hand corner
|
215
217
|
curve_to [x, y + r2],
|
216
|
-
|
218
|
+
bounds: [[x + r1, y + l2], [x + l1, y + r2]]
|
217
219
|
|
218
220
|
# Upper left hand corner
|
219
221
|
curve_to [x - r1, y],
|
220
|
-
|
222
|
+
bounds: [[x - l1, y + r2], [x - r1, y + l2]]
|
221
223
|
|
222
224
|
# Lower left hand corner
|
223
225
|
curve_to [x, y - r2],
|
224
|
-
|
226
|
+
bounds: [[x - r1, y - l2], [x - l1, y - r2]]
|
225
227
|
|
226
228
|
# Lower right hand corner
|
227
229
|
curve_to [x + r1, y],
|
228
|
-
|
230
|
+
bounds: [[x + l1, y - r2], [x + r1, y - l2]]
|
229
231
|
|
230
232
|
move_to(x, y)
|
231
233
|
end
|
@@ -241,35 +243,47 @@ module Prawn
|
|
241
243
|
line_to(*point)
|
242
244
|
end
|
243
245
|
# close the path
|
244
|
-
renderer.add_content
|
246
|
+
renderer.add_content 'h'
|
245
247
|
end
|
246
248
|
|
247
|
-
# Draws a rounded polygon from specified points using the radius to define
|
249
|
+
# Draws a rounded polygon from specified points using the radius to define
|
250
|
+
# bezier curves
|
248
251
|
#
|
249
|
-
#
|
250
|
-
# pdf.fill_and_stroke_rounded_polygon(
|
251
|
-
#
|
252
|
+
# # draws a rounded filled in polygon
|
253
|
+
# pdf.fill_and_stroke_rounded_polygon(
|
254
|
+
# 10, [100, 250], [200, 300], [300, 250], [300, 150], [200, 100],
|
255
|
+
# [100, 150]
|
256
|
+
# )
|
252
257
|
def rounded_polygon(radius, *points)
|
253
258
|
move_to point_on_line(radius, points[1], points[0])
|
254
259
|
sides = points.size
|
255
260
|
points << points[0] << points[1]
|
256
|
-
|
261
|
+
sides.times do |i|
|
257
262
|
rounded_vertex(radius, points[i], points[i + 1], points[i + 2])
|
258
263
|
end
|
259
264
|
# close the path
|
260
|
-
renderer.add_content
|
265
|
+
renderer.add_content 'h'
|
261
266
|
end
|
262
267
|
|
263
|
-
# Creates a rounded vertex for a line segment used for building a rounded
|
264
|
-
# requires a radius to define bezier curve and three points. The
|
265
|
-
# the line segment and the third point helps define
|
268
|
+
# Creates a rounded vertex for a line segment used for building a rounded
|
269
|
+
# polygon requires a radius to define bezier curve and three points. The
|
270
|
+
# first two points define the line segment and the third point helps define
|
271
|
+
# the curve for the vertex.
|
266
272
|
def rounded_vertex(radius, *points)
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
+
radial_point1 = point_on_line(radius, points[0], points[1])
|
274
|
+
bezier_point1 = point_on_line(
|
275
|
+
(radius - radius * KAPPA),
|
276
|
+
points[0],
|
277
|
+
points[1]
|
278
|
+
)
|
279
|
+
radial_point2 = point_on_line(radius, points[2], points[1])
|
280
|
+
bezier_point2 = point_on_line(
|
281
|
+
(radius - radius * KAPPA),
|
282
|
+
points[2],
|
283
|
+
points[1]
|
284
|
+
)
|
285
|
+
line_to(radial_point1)
|
286
|
+
curve_to(radial_point2, bounds: [bezier_point1, bezier_point2])
|
273
287
|
end
|
274
288
|
|
275
289
|
# Strokes the current path. If a block is provided, yields to the block
|
@@ -277,7 +291,7 @@ module Prawn
|
|
277
291
|
#
|
278
292
|
def stroke
|
279
293
|
yield if block_given?
|
280
|
-
renderer.add_content
|
294
|
+
renderer.add_content 'S'
|
281
295
|
end
|
282
296
|
|
283
297
|
# Closes and strokes the current path. If a block is provided, yields to
|
@@ -285,7 +299,7 @@ module Prawn
|
|
285
299
|
#
|
286
300
|
def close_and_stroke
|
287
301
|
yield if block_given?
|
288
|
-
renderer.add_content
|
302
|
+
renderer.add_content 's'
|
289
303
|
end
|
290
304
|
|
291
305
|
# Draws and strokes a rectangle represented by the current bounding box
|
@@ -320,38 +334,56 @@ module Prawn
|
|
320
334
|
#
|
321
335
|
def stroke_axis(options = {})
|
322
336
|
options = {
|
323
|
-
:
|
324
|
-
:
|
325
|
-
:
|
326
|
-
:
|
327
|
-
:
|
328
|
-
:
|
337
|
+
at: [0, 0],
|
338
|
+
height: bounds.height.to_i - (options[:at] || [0, 0])[1],
|
339
|
+
width: bounds.width.to_i - (options[:at] || [0, 0])[0],
|
340
|
+
step_length: 100,
|
341
|
+
negative_axes_length: 20,
|
342
|
+
color: '000000'
|
329
343
|
}.merge(options)
|
330
344
|
|
331
|
-
Prawn.verify_options(
|
332
|
-
|
345
|
+
Prawn.verify_options(
|
346
|
+
[
|
347
|
+
:at, :width, :height, :step_length,
|
348
|
+
:negative_axes_length, :color
|
349
|
+
], options
|
350
|
+
)
|
333
351
|
|
334
352
|
save_graphics_state do
|
335
353
|
fill_color(options[:color])
|
336
354
|
stroke_color(options[:color])
|
337
355
|
|
338
|
-
dash(1, :
|
339
|
-
stroke_horizontal_line(
|
340
|
-
|
341
|
-
|
342
|
-
|
356
|
+
dash(1, space: 4)
|
357
|
+
stroke_horizontal_line(
|
358
|
+
options[:at][0] - options[:negative_axes_length],
|
359
|
+
options[:at][0] + options[:width], at: options[:at][1]
|
360
|
+
)
|
361
|
+
stroke_vertical_line(
|
362
|
+
options[:at][1] - options[:negative_axes_length],
|
363
|
+
options[:at][1] + options[:height], at: options[:at][0]
|
364
|
+
)
|
343
365
|
undash
|
344
366
|
|
345
367
|
fill_circle(options[:at], 1)
|
346
368
|
|
347
|
-
(options[:step_length]..options[:width])
|
369
|
+
(options[:step_length]..options[:width])
|
370
|
+
.step(options[:step_length]) do |point|
|
348
371
|
fill_circle([options[:at][0] + point, options[:at][1]], 1)
|
349
|
-
draw_text(
|
372
|
+
draw_text(
|
373
|
+
point,
|
374
|
+
at: [options[:at][0] + point - 5, options[:at][1] - 10],
|
375
|
+
size: 7
|
376
|
+
)
|
350
377
|
end
|
351
378
|
|
352
|
-
(options[:step_length]..options[:height])
|
379
|
+
(options[:step_length]..options[:height])
|
380
|
+
.step(options[:step_length]) do |point|
|
353
381
|
fill_circle([options[:at][0], options[:at][1] + point], 1)
|
354
|
-
draw_text(
|
382
|
+
draw_text(
|
383
|
+
point,
|
384
|
+
at: [options[:at][0] - 17, options[:at][1] + point - 2],
|
385
|
+
size: 7
|
386
|
+
)
|
355
387
|
end
|
356
388
|
end
|
357
389
|
end
|
@@ -365,7 +397,7 @@ module Prawn
|
|
365
397
|
#
|
366
398
|
def fill(options = {})
|
367
399
|
yield if block_given?
|
368
|
-
renderer.add_content(options[:fill_rule] == :even_odd ?
|
400
|
+
renderer.add_content(options[:fill_rule] == :even_odd ? 'f*' : 'f')
|
369
401
|
end
|
370
402
|
|
371
403
|
# Closes, fills, and strokes the current path. If a block is provided,
|
@@ -379,13 +411,13 @@ module Prawn
|
|
379
411
|
#
|
380
412
|
def fill_and_stroke(options = {})
|
381
413
|
yield if block_given?
|
382
|
-
renderer.add_content(options[:fill_rule] == :even_odd ?
|
414
|
+
renderer.add_content(options[:fill_rule] == :even_odd ? 'b*' : 'b')
|
383
415
|
end
|
384
416
|
|
385
417
|
# Closes the current path.
|
386
418
|
#
|
387
419
|
def close_path
|
388
|
-
renderer.add_content
|
420
|
+
renderer.add_content 'h'
|
389
421
|
end
|
390
422
|
|
391
423
|
##
|
@@ -594,12 +626,20 @@ module Prawn
|
|
594
626
|
# :call-seq:
|
595
627
|
# fill_and_stroke_rounded_polygon(radius, *points)
|
596
628
|
|
597
|
-
ops
|
598
|
-
shapes = %w
|
599
|
-
|
629
|
+
ops = %w[fill stroke fill_and_stroke]
|
630
|
+
shapes = %w[
|
631
|
+
line_to curve_to rectangle rounded_rectangle line horizontal_line
|
632
|
+
horizontal_rule vertical_line curve circle_at circle ellipse_at ellipse
|
633
|
+
polygon rounded_polygon rounded_vertex
|
634
|
+
]
|
600
635
|
|
601
636
|
ops.product(shapes).each do |operation, shape|
|
602
|
-
class_eval
|
637
|
+
class_eval <<-END
|
638
|
+
def #{operation}_#{shape}(*args)
|
639
|
+
#{shape}(*args)
|
640
|
+
#{operation}
|
641
|
+
end
|
642
|
+
END
|
603
643
|
end
|
604
644
|
|
605
645
|
private
|
@@ -629,8 +669,8 @@ module Prawn
|
|
629
669
|
angle * Math::PI / 180
|
630
670
|
end
|
631
671
|
|
632
|
-
# Returns the coordinates for a point on a line that is a given distance
|
633
|
-
# point defining the line segement
|
672
|
+
# Returns the coordinates for a point on a line that is a given distance
|
673
|
+
# away from the second point defining the line segement
|
634
674
|
def point_on_line(distance_from_end, *points)
|
635
675
|
x0, y0, x1, y1 = points.flatten
|
636
676
|
length = Math.sqrt((x1 - x0)**2 + (y1 - y0)**2)
|