hexapdf 0.17.2 → 0.19.1
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
- data/CHANGELOG.md +67 -0
- data/lib/hexapdf/cli/command.rb +7 -1
- data/lib/hexapdf/content/canvas.rb +2 -2
- data/lib/hexapdf/content/color_space.rb +19 -0
- data/lib/hexapdf/content/graphic_object/arc.rb +2 -2
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +4 -4
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +111 -10
- data/lib/hexapdf/content/graphics_state.rb +167 -25
- data/lib/hexapdf/dictionary.rb +1 -1
- data/lib/hexapdf/dictionary_fields.rb +1 -1
- data/lib/hexapdf/document/signatures.rb +221 -0
- data/lib/hexapdf/encryption/security_handler.rb +3 -1
- data/lib/hexapdf/layout/style.rb +2 -1
- data/lib/hexapdf/object.rb +18 -0
- data/lib/hexapdf/parser.rb +3 -0
- data/lib/hexapdf/serializer.rb +2 -0
- data/lib/hexapdf/task/optimize.rb +46 -3
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +4 -4
- data/lib/hexapdf/type/acro_form/form.rb +39 -28
- data/lib/hexapdf/type/acro_form/variable_text_field.rb +56 -18
- data/lib/hexapdf/type/annotations/widget.rb +3 -15
- data/lib/hexapdf/type/font.rb +5 -0
- data/lib/hexapdf/type/font_type3.rb +20 -0
- data/lib/hexapdf/type/signature/adbe_pkcs7_detached.rb +125 -0
- data/lib/hexapdf/version.rb +1 -1
- data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +16 -8
- data/test/hexapdf/content/test_color_space.rb +26 -0
- data/test/hexapdf/content/test_graphics_state.rb +9 -1
- data/test/hexapdf/content/test_operator.rb +8 -3
- data/test/hexapdf/encryption/test_security_handler.rb +3 -1
- data/test/hexapdf/layout/test_style.rb +11 -0
- data/test/hexapdf/task/test_optimize.rb +26 -0
- data/test/hexapdf/test_dictionary.rb +1 -0
- data/test/hexapdf/test_dictionary_fields.rb +3 -2
- data/test/hexapdf/test_object.rb +28 -0
- data/test/hexapdf/test_parser.rb +11 -0
- data/test/hexapdf/test_writer.rb +2 -2
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +8 -1
- data/test/hexapdf/type/acro_form/test_form.rb +15 -8
- data/test/hexapdf/type/acro_form/test_variable_text_field.rb +18 -8
- data/test/hexapdf/type/test_font.rb +4 -0
- data/test/hexapdf/type/test_font_type3.rb +16 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 496c87d6cffcfde7b155fbfcdd78673fb34931d4d0fd997bcee934decfba175d
|
4
|
+
data.tar.gz: ce72598c9d33735c6ea4738c072b1f00202dc7bac24577c9c27a062add38ea8e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cee5a6f86084490ba5602c40ec48945b9a3c0bdecb22fe03e2d7b8b6ad02c791900f9fd7354557a9ac3dfdebb4a8d95c7335fc329c0054156082853f33717144
|
7
|
+
data.tar.gz: eaed67cce68e703eddbbb357e790a9f0bc62083ff8ba0b0856aa360d499f75e0e022b1ccd41ebcdd53e2fe269a93b5f587c47db41311c3f6a0beb9ed293e02cd
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,70 @@
|
|
1
|
+
## 0.19.1 - 2021-12-12
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
* [HexaPDF::Type::FontType3#bounding_box] to fix content stream processing error
|
6
|
+
|
7
|
+
### Fixed
|
8
|
+
|
9
|
+
* Calculation of scaled font size for [HexaPDF::Content::GraphicsState] and
|
10
|
+
[HexaPDF::Layout::Style] when Type3 fonts are used
|
11
|
+
|
12
|
+
|
13
|
+
## 0.19.0 - 2021-11-24
|
14
|
+
|
15
|
+
### Added
|
16
|
+
|
17
|
+
* Page resource pruning to the optimization task
|
18
|
+
* An option for page resources pruning to the optimization options of the
|
19
|
+
`hexapdf` command
|
20
|
+
|
21
|
+
### Fixed
|
22
|
+
|
23
|
+
* Handling of invalid date strings with a minute time zone offset greater than
|
24
|
+
59
|
25
|
+
|
26
|
+
|
27
|
+
## 0.18.0 - 2021-11-04
|
28
|
+
|
29
|
+
### Added
|
30
|
+
|
31
|
+
* [HexaPDF::Content::ColorSpace::serialize_device_color] for serialization of
|
32
|
+
device colors in parts other than the canvas
|
33
|
+
* [HexaPDF::Type::AcroForm::VariableTextField::create_appearance_string] for
|
34
|
+
centralized creation of appearance strings
|
35
|
+
* [HexaPDF::Object::make_direct] for making objects and all parts of them direct
|
36
|
+
instead of indirect
|
37
|
+
|
38
|
+
### Changed
|
39
|
+
|
40
|
+
* [HexaPDF::Type::AcroForm::VariableTextField::parse_appearance_string] to also
|
41
|
+
return the font color
|
42
|
+
* [HexaPDF::Type::AcroForm::VariableTextField#set_default_appearance_string] to
|
43
|
+
allow specifying the font color
|
44
|
+
* [HexaPDF::Type::AcroForm::Form] methods to support new variable text field
|
45
|
+
methods
|
46
|
+
* [HexaPDF::Type::AcroForm::AppearanceGenerator] to support the set font color
|
47
|
+
when creating text field appearances
|
48
|
+
|
49
|
+
### Fixed
|
50
|
+
|
51
|
+
* Writing of existing, encrypted PDF files where parts of the encryption
|
52
|
+
dictionary are indirect objects
|
53
|
+
* [HexaPDF::Content::GraphicObject::EndpointArc] to correctly determine the
|
54
|
+
start and end points
|
55
|
+
* HexaPDF::Dictionary#perform_validation to correctly handle objects that
|
56
|
+
should not be indirect objects
|
57
|
+
|
58
|
+
|
59
|
+
## 0.17.3 - 2021-10-31
|
60
|
+
|
61
|
+
### Fixed
|
62
|
+
|
63
|
+
* Reconstruction of invalid PDF files where the PDF header is not at the start
|
64
|
+
of the file
|
65
|
+
* Reconstruction of invalid PDF files where the first object is invalid
|
66
|
+
|
67
|
+
|
1
68
|
## 0.17.2 - 2021-10-26
|
2
69
|
|
3
70
|
### Fixed
|
data/lib/hexapdf/cli/command.rb
CHANGED
@@ -66,6 +66,7 @@ module HexaPDF
|
|
66
66
|
@out_options.xref_streams = :preserve
|
67
67
|
@out_options.streams = :preserve
|
68
68
|
@out_options.optimize_fonts = false
|
69
|
+
@out_options.prune_page_resources = false
|
69
70
|
|
70
71
|
@out_options.encryption = :preserve
|
71
72
|
@out_options.enc_user_pwd = @out_options.enc_owner_pwd = nil
|
@@ -169,6 +170,10 @@ module HexaPDF
|
|
169
170
|
"time; default: #{@out_options.compress_pages})") do |c|
|
170
171
|
@out_options.compress_pages = c
|
171
172
|
end
|
173
|
+
options.on("--[no-]prune-page-resources", "Prunes unused objects from the page resources " \
|
174
|
+
"(may take a long time; default: #{@out_options.prune_page_resources})") do |c|
|
175
|
+
@out_options.prune_page_resources = c
|
176
|
+
end
|
172
177
|
options.on("--[no-]optimize-fonts", "Optimize embedded font files; " \
|
173
178
|
"default: #{@out_options.optimize_fonts})") do |o|
|
174
179
|
@out_options.optimize_fonts = o
|
@@ -236,7 +241,8 @@ module HexaPDF
|
|
236
241
|
doc.task(:optimize, compact: @out_options.compact,
|
237
242
|
object_streams: @out_options.object_streams,
|
238
243
|
xref_streams: @out_options.xref_streams,
|
239
|
-
compress_pages: @out_options.compress_pages
|
244
|
+
compress_pages: @out_options.compress_pages,
|
245
|
+
prune_page_resources: @out_options.prune_page_resources)
|
240
246
|
if @out_options.streams != :preserve || @out_options.optimize_fonts
|
241
247
|
doc.each(only_current: false) do |obj|
|
242
248
|
optimize_stream(obj)
|
@@ -589,7 +589,7 @@ module HexaPDF
|
|
589
589
|
#
|
590
590
|
# The line cap style specifies how the ends of stroked open paths should look like.
|
591
591
|
#
|
592
|
-
# The +style+ parameter can be one of:
|
592
|
+
# The +style+ parameter can be one of (also see LineCapStyle):
|
593
593
|
#
|
594
594
|
# :butt or 0::
|
595
595
|
# Stroke is squared off at the endpoint of a path.
|
@@ -641,7 +641,7 @@ module HexaPDF
|
|
641
641
|
#
|
642
642
|
# The line join style specifies the shape that is used at the corners of stroked paths.
|
643
643
|
#
|
644
|
-
# The +style+ parameter can be one of:
|
644
|
+
# The +style+ parameter can be one of (also see LineJoinStyle):
|
645
645
|
#
|
646
646
|
# :miter or 0::
|
647
647
|
# The outer lines of the two segments continue until the meet at an angle.
|
@@ -35,7 +35,9 @@
|
|
35
35
|
#++
|
36
36
|
|
37
37
|
require 'hexapdf/error'
|
38
|
+
require 'hexapdf/content'
|
38
39
|
require 'hexapdf/configuration'
|
40
|
+
require 'hexapdf/serializer'
|
39
41
|
|
40
42
|
module HexaPDF
|
41
43
|
module Content
|
@@ -304,6 +306,23 @@ module HexaPDF
|
|
304
306
|
GlobalConfiguration.constantize('color_space.map', for_components(spec)).new.color(*spec)
|
305
307
|
end
|
306
308
|
|
309
|
+
# Serializes the given device color into the form expected by PDF content streams.
|
310
|
+
#
|
311
|
+
# The +type+ argument can either be :stroke to serialize as stroke color operator or :fill as
|
312
|
+
# fill color operator.
|
313
|
+
def self.serialize_device_color(color, type: :fill)
|
314
|
+
operator = case color.color_space.family
|
315
|
+
when :DeviceRGB then :rg
|
316
|
+
when :DeviceGray then :g
|
317
|
+
when :DeviceCMYK then :k
|
318
|
+
else
|
319
|
+
raise ArgumentError, "Device color object expected, got #{color.class}"
|
320
|
+
end
|
321
|
+
operator = operator.upcase if type == :stroke
|
322
|
+
Content::Operator::DEFAULT_OPERATORS[operator].
|
323
|
+
serialize(HexaPDF::Serializer.new, *color.components)
|
324
|
+
end
|
325
|
+
|
307
326
|
# Returns a device color object for the given components array without applying value
|
308
327
|
# normalization.
|
309
328
|
def self.prenormalized_device_color(components)
|
@@ -51,8 +51,8 @@ module HexaPDF
|
|
51
51
|
# Examples:
|
52
52
|
#
|
53
53
|
# #>pdf-center
|
54
|
-
# arc = canvas.graphic_object(:arc, a: 100, b: 50)
|
55
|
-
#
|
54
|
+
# arc = canvas.graphic_object(:arc, a: 100, b: 50, end_angle: 150)
|
55
|
+
# canvas.draw(arc).stroke
|
56
56
|
#
|
57
57
|
# See: ELL - https://spaceroots.org/documents/ellipse/elliptical-arc.pdf
|
58
58
|
class Arc
|
@@ -49,8 +49,8 @@ module HexaPDF
|
|
49
49
|
# Examples:
|
50
50
|
#
|
51
51
|
# #>pdf-center
|
52
|
-
# arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 10)
|
53
|
-
#
|
52
|
+
# arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 10)
|
53
|
+
# canvas.move_to(0, 0).draw(arc).stroke
|
54
54
|
#
|
55
55
|
# See: GraphicObject::Arc, ARC - https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
|
56
56
|
class EndpointArc
|
@@ -251,10 +251,10 @@ module HexaPDF
|
|
251
251
|
cy = sin_theta * cxp + cos_theta * cyp + (y1 + y2) / 2.0
|
252
252
|
|
253
253
|
# F.6.5.5
|
254
|
-
start_angle = compute_angle_to_x_axis((x1p - cxp)
|
254
|
+
start_angle = compute_angle_to_x_axis((x1p - cxp), (y1p - cyp)) % 360
|
255
255
|
|
256
256
|
# F.6.5.6 (modified bc we just need the end angle)
|
257
|
-
end_angle = compute_angle_to_x_axis((-x1p - cxp)
|
257
|
+
end_angle = compute_angle_to_x_axis((-x1p - cxp), (-y1p - cyp)) % 360
|
258
258
|
|
259
259
|
{cx: cx, cy: cy, a: rx, b: ry, start_angle: start_angle, end_angle: end_angle,
|
260
260
|
inclination: @inclination, clockwise: @clockwise}
|
@@ -41,20 +41,45 @@ module HexaPDF
|
|
41
41
|
# This graphic object represents a solid elliptical arc, i.e. an arc that has an inner and
|
42
42
|
# an outer set of a/b values.
|
43
43
|
#
|
44
|
+
# This graphic object is registered under the :solid_arc key for use with the
|
45
|
+
# HexaPDF::Content::Canvas class.
|
46
|
+
#
|
44
47
|
# Thus it can be used to create
|
45
48
|
#
|
46
|
-
# * an (elliptical) disk (when the inner a/b are zero and the difference between start and
|
49
|
+
# * an (*elliptical*) *disk* (when the inner a/b are zero and the difference between start and
|
47
50
|
# end angles is greater than or equal to 360),
|
48
51
|
#
|
49
|
-
#
|
52
|
+
# #>pdf-center
|
53
|
+
# canvas.fill_color("red").
|
54
|
+
# draw(:solid_arc, outer_a: 80, outer_b: 50, end_angle: 360).
|
55
|
+
# fill_stroke
|
56
|
+
#
|
57
|
+
# * an (*elliptical*) *sector* (when the inner a/b are zero and the difference between start
|
50
58
|
# and end angles is less than 360),
|
51
59
|
#
|
52
|
-
#
|
60
|
+
# #>pdf-center
|
61
|
+
# canvas.fill_color("red").
|
62
|
+
# draw(:solid_arc, outer_a: 80, outer_b: 50, start_angle: 20, end_angle: 230).
|
63
|
+
# fill_stroke
|
64
|
+
#
|
65
|
+
# * an (*elliptical*) *annulus* (when the inner a/b are nonzero and the difference between
|
53
66
|
# start and end angles is greater than or equal to 360), and
|
54
67
|
#
|
55
|
-
#
|
68
|
+
# #>pdf-center
|
69
|
+
# canvas.fill_color("red").
|
70
|
+
# draw(:solid_arc, outer_a: 80, outer_b: 50, inner_a: 70, inner_b: 30,
|
71
|
+
# end_angle: 360).
|
72
|
+
# fill_stroke
|
73
|
+
#
|
74
|
+
# * an (*elliptical*) *annular sector* (when the inner a/b are nonzero and the difference
|
56
75
|
# between start and end angles is less than 360)
|
57
76
|
#
|
77
|
+
# #>pdf-center
|
78
|
+
# canvas.fill_color("red").
|
79
|
+
# draw(:solid_arc, outer_a: 80, outer_b: 50, inner_a: 70, inner_b: 30,
|
80
|
+
# start_angle: 20, end_angle: 230).
|
81
|
+
# fill_stroke
|
82
|
+
#
|
58
83
|
# See: Arc
|
59
84
|
class SolidArc
|
60
85
|
|
@@ -66,30 +91,106 @@ module HexaPDF
|
|
66
91
|
end
|
67
92
|
|
68
93
|
# x-coordinate of center point
|
94
|
+
#
|
95
|
+
# Examples:
|
96
|
+
#
|
97
|
+
# #>pdf-center
|
98
|
+
# solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
|
99
|
+
# inner_a: 20, inner_b: 10)
|
100
|
+
# canvas.draw(solid_arc).stroke
|
101
|
+
# canvas.stroke_color("red").draw(solid_arc, cx: 50).stroke
|
69
102
|
attr_reader :cx
|
70
103
|
|
71
104
|
# y-coordinate of center point
|
105
|
+
#
|
106
|
+
# Examples:
|
107
|
+
#
|
108
|
+
# #>pdf-center
|
109
|
+
# solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
|
110
|
+
# inner_a: 20, inner_b: 10)
|
111
|
+
# canvas.draw(solid_arc).stroke
|
112
|
+
# canvas.stroke_color("red").draw(solid_arc, cy: 50).stroke
|
72
113
|
attr_reader :cy
|
73
114
|
|
74
|
-
# Length of inner semi-major axis
|
115
|
+
# Length of inner semi-major axis which (without altering the #inclination) is parallel to
|
116
|
+
# the x-axis
|
117
|
+
#
|
118
|
+
# Examples:
|
119
|
+
#
|
120
|
+
# #>pdf-center
|
121
|
+
# solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
|
122
|
+
# inner_a: 20, inner_b: 10)
|
123
|
+
# canvas.draw(solid_arc).stroke
|
124
|
+
# canvas.stroke_color("red").draw(solid_arc, inner_a: 5).stroke
|
75
125
|
attr_reader :inner_a
|
76
126
|
|
77
|
-
# Length of inner semi-minor axis
|
127
|
+
# Length of inner semi-minor axis which (without altering the #inclination) is parallel to the
|
128
|
+
# y-axis
|
129
|
+
#
|
130
|
+
# Examples:
|
131
|
+
#
|
132
|
+
# #>pdf-center
|
133
|
+
# solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
|
134
|
+
# inner_a: 20, inner_b: 10)
|
135
|
+
# canvas.draw(solid_arc).stroke
|
136
|
+
# canvas.stroke_color("red").draw(solid_arc, inner_b: 20).stroke
|
78
137
|
attr_reader :inner_b
|
79
138
|
|
80
|
-
# Length of outer semi-major axis
|
139
|
+
# Length of outer semi-major axis which (without altering the #inclination) is parallel to
|
140
|
+
# the x-axis
|
141
|
+
#
|
142
|
+
# Examples:
|
143
|
+
#
|
144
|
+
# #>pdf-center
|
145
|
+
# solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
|
146
|
+
# inner_a: 20, inner_b: 10)
|
147
|
+
# canvas.draw(solid_arc).stroke
|
148
|
+
# canvas.stroke_color("red").draw(solid_arc, outer_a: 45).stroke
|
81
149
|
attr_reader :outer_a
|
82
150
|
|
83
|
-
# Length of outer semi-minor axis
|
151
|
+
# Length of outer semi-minor axis which (without altering the #inclination) is parallel to the
|
152
|
+
# y-axis
|
153
|
+
#
|
154
|
+
# Examples:
|
155
|
+
#
|
156
|
+
# #>pdf-center
|
157
|
+
# solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
|
158
|
+
# inner_a: 20, inner_b: 10)
|
159
|
+
# canvas.draw(solid_arc).stroke
|
160
|
+
# canvas.stroke_color("red").draw(solid_arc, outer_b: 40).stroke
|
84
161
|
attr_reader :outer_b
|
85
162
|
|
86
|
-
# Start angle in degrees
|
163
|
+
# Start angle of the solid arc in degrees
|
164
|
+
#
|
165
|
+
# Examples:
|
166
|
+
#
|
167
|
+
# #>pdf-center
|
168
|
+
# solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
|
169
|
+
# inner_a: 20, inner_b: 10)
|
170
|
+
# canvas.draw(solid_arc).stroke
|
171
|
+
# canvas.stroke_color("red").draw(solid_arc, start_angle: 60).stroke
|
87
172
|
attr_reader :start_angle
|
88
173
|
|
89
|
-
# End angle in degrees
|
174
|
+
# End angle of the solid arc in degrees
|
175
|
+
#
|
176
|
+
# Examples:
|
177
|
+
#
|
178
|
+
# #>pdf-center
|
179
|
+
# solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
|
180
|
+
# inner_a: 20, inner_b: 10)
|
181
|
+
# canvas.draw(solid_arc).stroke
|
182
|
+
# canvas.stroke_color("red").draw(solid_arc, end_angle: 120).stroke
|
90
183
|
attr_reader :end_angle
|
91
184
|
|
92
185
|
# Inclination in degrees of semi-major axis in respect to x-axis
|
186
|
+
#
|
187
|
+
# Examples:
|
188
|
+
#
|
189
|
+
# #>pdf-center
|
190
|
+
# solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
|
191
|
+
# inner_a: 20, inner_b: 10)
|
192
|
+
# canvas.draw(solid_arc).stroke
|
193
|
+
# canvas.stroke_color("red").draw(solid_arc, inclination: 40).stroke
|
93
194
|
attr_reader :inclination
|
94
195
|
|
95
196
|
# Creates a solid arc with default values (a unit disk at the origin).
|
@@ -73,7 +73,7 @@ module HexaPDF
|
|
73
73
|
end
|
74
74
|
|
75
75
|
# Defines all available line cap styles as constants. Each line cap style is an instance of
|
76
|
-
# NamedValue. For use with Content::
|
76
|
+
# NamedValue, see ::normalize. For use with e.g. Content::Canvas#line_cap_style.
|
77
77
|
#
|
78
78
|
# See: PDF1.7 s8.4.3.3
|
79
79
|
module LineCapStyle
|
@@ -95,18 +95,39 @@ module HexaPDF
|
|
95
95
|
end
|
96
96
|
|
97
97
|
# Stroke is squared off at the endpoint of a path.
|
98
|
+
#
|
99
|
+
# Specify as 0 or :butt.
|
100
|
+
#
|
101
|
+
# #>pdf-small-hide
|
102
|
+
# canvas.line_cap_style(:butt)
|
103
|
+
# canvas.line_width(10).line(50, 20, 50, 80).stroke
|
104
|
+
# canvas.stroke_color("white").line_width(1).line(50, 20, 50, 80).stroke
|
98
105
|
BUTT_CAP = NamedValue.new(:butt, 0)
|
99
106
|
|
100
107
|
# A semicircular arc is drawn at the endpoint of a path.
|
108
|
+
#
|
109
|
+
# Specify as 1 or :round.
|
110
|
+
#
|
111
|
+
# #>pdf-small-hide
|
112
|
+
# canvas.line_cap_style(:round)
|
113
|
+
# canvas.line_width(10).line(50, 20, 50, 80).stroke
|
114
|
+
# canvas.stroke_color("white").line_width(1).line(50, 20, 50, 80).stroke
|
101
115
|
ROUND_CAP = NamedValue.new(:round, 1)
|
102
116
|
|
103
117
|
# The stroke continues half the line width beyond the endpoint of a path.
|
118
|
+
#
|
119
|
+
# Specify as 2 or :projecting_square.
|
120
|
+
#
|
121
|
+
# #>pdf-small-hide
|
122
|
+
# canvas.line_cap_style(:projecting_square)
|
123
|
+
# canvas.line_width(10).line(50, 20, 50, 80).stroke
|
124
|
+
# canvas.stroke_color("white").line_width(1).line(50, 20, 50, 80).stroke
|
104
125
|
PROJECTING_SQUARE_CAP = NamedValue.new(:projecting_square, 2)
|
105
126
|
|
106
127
|
end
|
107
128
|
|
108
129
|
# Defines all available line join styles as constants. Each line join style is an instance of
|
109
|
-
# NamedValue
|
130
|
+
# NamedValue, see ::normalize For use with e.g. Content::Canvas#line_join_style.
|
110
131
|
#
|
111
132
|
# See: PDF1.7 s8.4.3.4
|
112
133
|
module LineJoinStyle
|
@@ -127,20 +148,47 @@ module HexaPDF
|
|
127
148
|
end
|
128
149
|
end
|
129
150
|
|
130
|
-
# The outer lines of the two segments continue until
|
151
|
+
# The outer lines of the two segments continue until they meet at an angle.
|
152
|
+
#
|
153
|
+
# Specify as 0 or :miter.
|
154
|
+
#
|
155
|
+
# #>pdf-small-hide
|
156
|
+
# canvas.line_join_style(:miter)
|
157
|
+
# canvas.line_width(10).
|
158
|
+
# polyline(20, 20, 50, 80, 80, 20).stroke
|
159
|
+
# canvas.stroke_color("white").line_width(1).line_join_style(:bevel).
|
160
|
+
# polyline(20, 20, 50, 80, 80, 20).stroke
|
131
161
|
MITER_JOIN = NamedValue.new(:miter, 0)
|
132
162
|
|
133
163
|
# An arc of a circle is drawn around the point where the segments meet.
|
164
|
+
#
|
165
|
+
# Specify as 1 or :round.
|
166
|
+
#
|
167
|
+
# #>pdf-small-hide
|
168
|
+
# canvas.line_join_style(:round)
|
169
|
+
# canvas.line_width(10).
|
170
|
+
# polyline(20, 20, 50, 80, 80, 20).stroke
|
171
|
+
# canvas.stroke_color("white").line_width(1).line_join_style(:bevel).
|
172
|
+
# polyline(20, 20, 50, 80, 80, 20).stroke
|
134
173
|
ROUND_JOIN = NamedValue.new(:round, 1)
|
135
174
|
|
136
|
-
# The two segments are finished with butt caps and the space between the ends is filled with
|
137
|
-
#
|
175
|
+
# The two segments are finished with butt caps and the space between the ends is filled with a
|
176
|
+
# triangle.
|
177
|
+
#
|
178
|
+
# Specify as 2 or :bevel.
|
179
|
+
#
|
180
|
+
# #>pdf-small-hide
|
181
|
+
# canvas.line_join_style(:bevel)
|
182
|
+
# canvas.line_width(10).
|
183
|
+
# polyline(20, 20, 50, 80, 80, 20).stroke
|
184
|
+
# canvas.stroke_color("white").line_width(1).line_join_style(:bevel).
|
185
|
+
# polyline(20, 20, 50, 80, 80, 20).stroke
|
138
186
|
BEVEL_JOIN = NamedValue.new(:bevel, 2)
|
139
187
|
|
140
188
|
end
|
141
189
|
|
142
|
-
# The line dash pattern defines how a line should be dashed. For use with
|
143
|
-
# Content::
|
190
|
+
# The line dash pattern defines how a line should be dashed. For use with e.g.
|
191
|
+
# Content::Canvas#line_dash_pattern.
|
144
192
|
#
|
145
193
|
# A dash pattern consists of two parts: the dash array and the dash phase. The dash array
|
146
194
|
# defines the length of alternating dashes and gaps (important: starting with dashes). And the
|
@@ -159,6 +207,12 @@ module HexaPDF
|
|
159
207
|
# See: PDF1.7 s8.4.3.6
|
160
208
|
class LineDashPattern
|
161
209
|
|
210
|
+
# :call-seq:
|
211
|
+
# LineDashPattern.normalize(line_dash_pattern) -> line_dash_pattern
|
212
|
+
# LineDashPattern.normalize(array, phase = 0) -> LineDashPattern.new(array, phase)
|
213
|
+
# LineDashPattern.normalize(number, phase = 0) -> LineDashPattern.new([number], phase)
|
214
|
+
# LineDashPattern.normalize(0) -> LineDashPattern.new
|
215
|
+
#
|
162
216
|
# Returns the arguments normalized to a valid LineDashPattern instance.
|
163
217
|
#
|
164
218
|
# If +array+ is 0, the default line dash pattern representing a solid line will be used. If it
|
@@ -206,8 +260,8 @@ module HexaPDF
|
|
206
260
|
|
207
261
|
end
|
208
262
|
|
209
|
-
# Defines all available rendering intents as constants. For use with
|
210
|
-
# Content::
|
263
|
+
# Defines all available rendering intents as constants. For use with e.g.
|
264
|
+
# Content::Canvas#rendering_intent.
|
211
265
|
#
|
212
266
|
# See: PDF1.7 s8.6.5.8
|
213
267
|
module RenderingIntent
|
@@ -241,7 +295,7 @@ module HexaPDF
|
|
241
295
|
end
|
242
296
|
|
243
297
|
# Defines all available text rendering modes as constants. Each text rendering mode is an
|
244
|
-
# instance of NamedValue. For use with Content::
|
298
|
+
# instance of NamedValue. For use with e.g. Content::Canvas#text_rendering_mode.
|
245
299
|
#
|
246
300
|
# See: PDF1.7 s9.3.6
|
247
301
|
module TextRenderingMode
|
@@ -272,28 +326,97 @@ module HexaPDF
|
|
272
326
|
end
|
273
327
|
end
|
274
328
|
|
275
|
-
# Fill text
|
329
|
+
# Fill text.
|
330
|
+
#
|
331
|
+
# Specify as 0 or :fill.
|
332
|
+
#
|
333
|
+
# #>pdf-small-hide
|
334
|
+
# canvas.font("Helvetica", size: 13)
|
335
|
+
# canvas.stroke_color("green").line_width(0.5)
|
336
|
+
# canvas.text_rendering_mode(:fill)
|
337
|
+
# canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
|
276
338
|
FILL = NamedValue.new(:fill, 0)
|
277
339
|
|
278
|
-
# Stroke text
|
340
|
+
# Stroke text.
|
341
|
+
#
|
342
|
+
# Specify as 1 or :stroke.
|
343
|
+
#
|
344
|
+
# #>pdf-small-hide
|
345
|
+
# canvas.font("Helvetica", size: 13)
|
346
|
+
# canvas.stroke_color("green").line_width(0.5)
|
347
|
+
# canvas.text_rendering_mode(:stroke)
|
348
|
+
# canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
|
279
349
|
STROKE = NamedValue.new(:stroke, 1)
|
280
350
|
|
281
|
-
# Fill, then stroke text
|
351
|
+
# Fill, then stroke text.
|
352
|
+
#
|
353
|
+
# Specify as 2 or :fill_stroke.
|
354
|
+
#
|
355
|
+
# #>pdf-small-hide
|
356
|
+
# canvas.font("Helvetica", size: 13)
|
357
|
+
# canvas.stroke_color("green").line_width(0.5)
|
358
|
+
# canvas.text_rendering_mode(:fill_stroke)
|
359
|
+
# canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
|
282
360
|
FILL_STROKE = NamedValue.new(:fill_stroke, 2)
|
283
361
|
|
284
|
-
# Neither fill nor stroke text (invisible)
|
362
|
+
# Neither fill nor stroke text (invisible).
|
363
|
+
#
|
364
|
+
# Specify as 3 or :invisible.
|
365
|
+
#
|
366
|
+
# #>pdf-small-hide
|
367
|
+
# canvas.font("Helvetica", size: 13)
|
368
|
+
# canvas.stroke_color("green").line_width(0.5)
|
369
|
+
# canvas.text_rendering_mode(:invisible)
|
370
|
+
# canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
|
371
|
+
# canvas.stroke_color("red").line_width(20).line(30, 20, 30, 80).stroke
|
285
372
|
INVISIBLE = NamedValue.new(:invisible, 3)
|
286
373
|
|
287
|
-
# Fill text and add to path for clipping
|
374
|
+
# Fill text and add to path for clipping.
|
375
|
+
#
|
376
|
+
# Specify as 4 or :fill_clip.
|
377
|
+
#
|
378
|
+
# #>pdf-small-hide
|
379
|
+
# canvas.font("Helvetica", size: 13)
|
380
|
+
# canvas.stroke_color("green").line_width(0.5)
|
381
|
+
# canvas.text_rendering_mode(:fill_clip)
|
382
|
+
# canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
|
383
|
+
# canvas.stroke_color("red").line_width(20).line(30, 20, 30, 80).stroke
|
288
384
|
FILL_CLIP = NamedValue.new(:fill_clip, 4)
|
289
385
|
|
290
|
-
# Stroke text and add to path for clipping
|
386
|
+
# Stroke text and add to path for clipping.
|
387
|
+
#
|
388
|
+
# Specify as 5 or :stroke_clip.
|
389
|
+
#
|
390
|
+
# #>pdf-small-hide
|
391
|
+
# canvas.font("Helvetica", size: 13)
|
392
|
+
# canvas.stroke_color("green").line_width(0.5)
|
393
|
+
# canvas.text_rendering_mode(:stroke_clip)
|
394
|
+
# canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
|
395
|
+
# canvas.stroke_color("red").line_width(20).line(30, 20, 30, 80).stroke
|
291
396
|
STROKE_CLIP = NamedValue.new(:stroke_clip, 5)
|
292
397
|
|
293
|
-
# Fill, then stroke text and add to path for clipping
|
398
|
+
# Fill, then stroke text and add to path for clipping.
|
399
|
+
#
|
400
|
+
# Specify as 6 or :fill_stroke_clip.
|
401
|
+
#
|
402
|
+
# #>pdf-small-hide
|
403
|
+
# canvas.font("Helvetica", size: 13)
|
404
|
+
# canvas.stroke_color("green").line_width(0.5)
|
405
|
+
# canvas.text_rendering_mode(:fill_stroke_clip)
|
406
|
+
# canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
|
407
|
+
# canvas.stroke_color("red").line_width(20).line(30, 20, 30, 80).stroke
|
294
408
|
FILL_STROKE_CLIP = NamedValue.new(:fill_stroke_clip, 6)
|
295
409
|
|
296
|
-
# Add text to path for clipping
|
410
|
+
# Add text to path for clipping.
|
411
|
+
#
|
412
|
+
# Specify as 7 or :clip.
|
413
|
+
#
|
414
|
+
# #>pdf-small-hide
|
415
|
+
# canvas.font("Helvetica", size: 13)
|
416
|
+
# canvas.stroke_color("green").line_width(0.5)
|
417
|
+
# canvas.text_rendering_mode(:clip)
|
418
|
+
# canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
|
419
|
+
# canvas.stroke_color("red").line_width(20).line(30, 20, 30, 80).stroke
|
297
420
|
CLIP = NamedValue.new(:clip, 7)
|
298
421
|
|
299
422
|
end
|
@@ -389,7 +512,7 @@ module HexaPDF
|
|
389
512
|
attr_accessor :leading
|
390
513
|
|
391
514
|
# The font for the text.
|
392
|
-
|
515
|
+
attr_reader :font
|
393
516
|
|
394
517
|
# The font size.
|
395
518
|
attr_reader :font_size
|
@@ -415,23 +538,25 @@ module HexaPDF
|
|
415
538
|
|
416
539
|
# The scaled character spacing used in glyph displacement calculations.
|
417
540
|
#
|
418
|
-
# This returns the
|
541
|
+
# This returns the character spacing multiplied by #scaled_horizontal_scaling.
|
419
542
|
#
|
420
543
|
# See PDF1.7 s9.4.4
|
421
544
|
attr_reader :scaled_character_spacing
|
422
545
|
|
423
546
|
# The scaled word spacing used in glyph displacement calculations.
|
424
547
|
#
|
425
|
-
# This returns the
|
548
|
+
# This returns the word spacing multiplied by #scaled_horizontal_scaling.
|
426
549
|
#
|
427
550
|
# See PDF1.7 s9.4.4
|
428
551
|
attr_reader :scaled_word_spacing
|
429
552
|
|
430
553
|
# The scaled font size used in glyph displacement calculations.
|
431
554
|
#
|
432
|
-
# This returns the
|
555
|
+
# This returns the font size multiplied by the scaling factor from glyph space to text space
|
556
|
+
# (0.001 for all fonts except Type3 fonts or the scaling specified in /FontMatrix for Type3
|
557
|
+
# fonts) and multiplied by #scaled_horizontal_scaling.
|
433
558
|
#
|
434
|
-
# See PDF1.7 s9.4.4
|
559
|
+
# See PDF1.7 s9.4.4, HexaPDF::Type::FontType3
|
435
560
|
attr_reader :scaled_font_size
|
436
561
|
|
437
562
|
# The scaled horizontal scaling used in glyph displacement calculations.
|
@@ -542,6 +667,15 @@ module HexaPDF
|
|
542
667
|
self.fill_color = color_space.default_color
|
543
668
|
end
|
544
669
|
|
670
|
+
##
|
671
|
+
# :attr_writer: font
|
672
|
+
#
|
673
|
+
# Sets the font and updates the glyph space to text space scaling.
|
674
|
+
def font=(font)
|
675
|
+
@font = font
|
676
|
+
update_scaled_font_size
|
677
|
+
end
|
678
|
+
|
545
679
|
##
|
546
680
|
# :attr_writer: character_spacing
|
547
681
|
#
|
@@ -566,7 +700,7 @@ module HexaPDF
|
|
566
700
|
# Sets the font size and updates the scaled font size.
|
567
701
|
def font_size=(size)
|
568
702
|
@font_size = size
|
569
|
-
|
703
|
+
update_scaled_font_size
|
570
704
|
end
|
571
705
|
|
572
706
|
##
|
@@ -579,7 +713,15 @@ module HexaPDF
|
|
579
713
|
@scaled_horizontal_scaling = scaling / 100.0
|
580
714
|
@scaled_character_spacing = @character_spacing * @scaled_horizontal_scaling
|
581
715
|
@scaled_word_spacing = @word_spacing * @scaled_horizontal_scaling
|
582
|
-
|
716
|
+
update_scaled_font_size
|
717
|
+
end
|
718
|
+
|
719
|
+
private
|
720
|
+
|
721
|
+
# Updates the cached value for the scaled font size.
|
722
|
+
def update_scaled_font_size
|
723
|
+
@scaled_font_size = @font_size * (@font&.glyph_scaling_factor || 0.001) *
|
724
|
+
@scaled_horizontal_scaling
|
583
725
|
end
|
584
726
|
|
585
727
|
end
|