hexapdf 1.2.0 → 1.4.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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +90 -0
  3. data/README.md +1 -1
  4. data/lib/hexapdf/cli/form.rb +9 -4
  5. data/lib/hexapdf/cli/inspect.rb +13 -4
  6. data/lib/hexapdf/composer.rb +14 -0
  7. data/lib/hexapdf/configuration.rb +15 -0
  8. data/lib/hexapdf/dictionary_fields.rb +1 -1
  9. data/lib/hexapdf/digital_signature/signing/default_handler.rb +1 -2
  10. data/lib/hexapdf/document/annotations.rb +107 -2
  11. data/lib/hexapdf/document/layout.rb +94 -15
  12. data/lib/hexapdf/document/metadata.rb +10 -3
  13. data/lib/hexapdf/document.rb +9 -0
  14. data/lib/hexapdf/encryption/standard_security_handler.rb +7 -2
  15. data/lib/hexapdf/error.rb +11 -3
  16. data/lib/hexapdf/font/true_type/subsetter.rb +15 -2
  17. data/lib/hexapdf/layout/box.rb +5 -0
  18. data/lib/hexapdf/layout/container_box.rb +63 -28
  19. data/lib/hexapdf/layout/style.rb +129 -20
  20. data/lib/hexapdf/layout/table_box.rb +20 -2
  21. data/lib/hexapdf/object.rb +2 -2
  22. data/lib/hexapdf/pdf_array.rb +25 -3
  23. data/lib/hexapdf/tokenizer.rb +4 -1
  24. data/lib/hexapdf/type/acro_form/appearance_generator.rb +57 -8
  25. data/lib/hexapdf/type/acro_form/field.rb +1 -0
  26. data/lib/hexapdf/type/acro_form/form.rb +7 -6
  27. data/lib/hexapdf/type/annotation.rb +12 -0
  28. data/lib/hexapdf/type/annotations/appearance_generator.rb +169 -16
  29. data/lib/hexapdf/type/annotations/border_effect.rb +99 -0
  30. data/lib/hexapdf/type/annotations/circle.rb +65 -0
  31. data/lib/hexapdf/type/annotations/interior_color.rb +84 -0
  32. data/lib/hexapdf/type/annotations/line.rb +5 -192
  33. data/lib/hexapdf/type/annotations/line_ending_styling.rb +208 -0
  34. data/lib/hexapdf/type/annotations/markup_annotation.rb +0 -1
  35. data/lib/hexapdf/type/annotations/polygon.rb +64 -0
  36. data/lib/hexapdf/type/annotations/polygon_polyline.rb +109 -0
  37. data/lib/hexapdf/type/annotations/polyline.rb +64 -0
  38. data/lib/hexapdf/type/annotations/square.rb +65 -0
  39. data/lib/hexapdf/type/annotations/square_circle.rb +77 -0
  40. data/lib/hexapdf/type/annotations/widget.rb +50 -20
  41. data/lib/hexapdf/type/annotations.rb +9 -0
  42. data/lib/hexapdf/type/measure.rb +57 -0
  43. data/lib/hexapdf/type.rb +1 -0
  44. data/lib/hexapdf/version.rb +1 -1
  45. data/test/hexapdf/digital_signature/signing/test_default_handler.rb +0 -1
  46. data/test/hexapdf/document/test_annotations.rb +42 -0
  47. data/test/hexapdf/document/test_layout.rb +38 -10
  48. data/test/hexapdf/document/test_metadata.rb +13 -1
  49. data/test/hexapdf/encryption/test_standard_security_handler.rb +2 -1
  50. data/test/hexapdf/font/true_type/test_subsetter.rb +10 -0
  51. data/test/hexapdf/layout/test_box.rb +8 -0
  52. data/test/hexapdf/layout/test_container_box.rb +34 -6
  53. data/test/hexapdf/layout/test_page_style.rb +1 -1
  54. data/test/hexapdf/layout/test_style.rb +46 -2
  55. data/test/hexapdf/layout/test_table_box.rb +14 -1
  56. data/test/hexapdf/test_composer.rb +7 -0
  57. data/test/hexapdf/test_dictionary_fields.rb +1 -0
  58. data/test/hexapdf/test_object.rb +1 -1
  59. data/test/hexapdf/test_pdf_array.rb +36 -3
  60. data/test/hexapdf/type/acro_form/test_appearance_generator.rb +78 -3
  61. data/test/hexapdf/type/acro_form/test_button_field.rb +7 -6
  62. data/test/hexapdf/type/acro_form/test_field.rb +5 -0
  63. data/test/hexapdf/type/acro_form/test_form.rb +17 -1
  64. data/test/hexapdf/type/annotations/test_appearance_generator.rb +210 -0
  65. data/test/hexapdf/type/annotations/test_border_effect.rb +59 -0
  66. data/test/hexapdf/type/annotations/test_interior_color.rb +37 -0
  67. data/test/hexapdf/type/annotations/test_line.rb +0 -45
  68. data/test/hexapdf/type/annotations/test_line_ending_styling.rb +42 -0
  69. data/test/hexapdf/type/annotations/test_polygon_polyline.rb +29 -0
  70. data/test/hexapdf/type/annotations/test_widget.rb +35 -0
  71. metadata +16 -2
@@ -43,10 +43,10 @@ module HexaPDF
43
43
  # A line annotation is a markup annotation that displays a single straight line.
44
44
  #
45
45
  # The style of the line annotation, like adding leader lines, changing the colors and so on,
46
- # can be customized using the provided convenience methods.
46
+ # can be customized using the provided convenience methods and those from the included
47
+ # modules.
47
48
  #
48
- # Note that changing the line width and color is done using the included
49
- # BorderStyling#border_style. While that method allows special styling of the line (like
49
+ # Note that while BorderStyling#border_style allows special styling of the line (like
50
50
  # :beveled), only a simple line dash pattern is supported by the line annotation.
51
51
  #
52
52
  # Example:
@@ -70,6 +70,8 @@ module HexaPDF
70
70
  class Line < MarkupAnnotation
71
71
 
72
72
  include BorderStyling
73
+ include InteriorColor
74
+ include LineEndingStyling
73
75
 
74
76
  define_field :Subtype, type: Symbol, required: true, default: :Line
75
77
  define_field :L, type: PDFArray, required: true
@@ -115,195 +117,6 @@ module HexaPDF
115
117
  end
116
118
  end
117
119
 
118
- # Maps HexaPDF names to PDF names.
119
- LINE_ENDING_STYLE_MAP = { # :nodoc:
120
- Square: :Square, square: :Square,
121
- Circle: :Circle, circle: :Circle,
122
- Diamond: :Diamond, diamond: :Diamond,
123
- OpenArrow: :OpenArrow, open_arrow: :OpenArrow,
124
- ClosedArrow: :ClosedArrow, closed_arrow: :ClosedArrow,
125
- None: :None, none: :None,
126
- Butt: :Butt, butt: :Butt,
127
- ROpenArrow: :ROpenArrow, ropen_arrow: :ROpenArrow,
128
- RClosedArrow: :RClosedArrow, rclosed_arrow: :RClosedArrow,
129
- Slash: :Slash, slash: :Slash,
130
- }.freeze
131
- LINE_ENDING_STYLE_REVERSE_MAP = LINE_ENDING_STYLE_MAP.invert # :nodoc:
132
-
133
-
134
- # Describes the line ending style for a line annotation, i.e. the +start_style+ and the
135
- # +end_style+.
136
- #
137
- # See Line#line_ending_style for more information.
138
- LineEndingStyle = Struct.new(:start_style, :end_style)
139
-
140
- # :call-seq:
141
- # line.line_ending_style => style
142
- # line.line_ending_style(start_style: :none, end_style: :none) => line
143
- #
144
- # Returns a LineEndingStyle instance holding the current line ending styles when no argument
145
- # is given. Otherwise sets the line ending style of the line and returns self.
146
- #
147
- # When returning the styles, unknown line ending styles are mapped to :none.
148
- #
149
- # When setting the line ending style, arguments that are not provided will use the currently
150
- # defined value or fall back to the default of +:none+.
151
- #
152
- # Possible line ending styles (the first one is the HexaPDF name, the second the PDF name):
153
- #
154
- # :square or :Square::
155
- # A square filled with the annotation's interior colour, if any.
156
- #
157
- # #>pdf-small-hide
158
- # doc.annotations.
159
- # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
160
- # interior_color("hp-orange").
161
- # line_ending_style(end_style: :square).
162
- # regenerate_appearance
163
- #
164
- # :circle or :Circle::
165
- # A circle filled with the annotation’s interior colour, if any.
166
- #
167
- # #>pdf-small-hide
168
- # doc.annotations.
169
- # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
170
- # interior_color("hp-orange").
171
- # line_ending_style(end_style: :circle).
172
- # regenerate_appearance
173
- #
174
- # :diamond or :Diamond::
175
- # A diamond shape filled with the annotation’s interior colour, if any.
176
- #
177
- # #>pdf-small-hide
178
- # doc.annotations.
179
- # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
180
- # interior_color("hp-orange").
181
- # line_ending_style(end_style: :diamond).
182
- # regenerate_appearance
183
- #
184
- # :open_arrow or :OpenArrow::
185
- # Two short lines meeting in an acute angle to form an open arrowhead.
186
- #
187
- # #>pdf-small-hide
188
- # doc.annotations.
189
- # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
190
- # interior_color("hp-orange").
191
- # line_ending_style(end_style: :open_arrow).
192
- # regenerate_appearance
193
- #
194
- # :closed_arrow or :ClosedArrow::
195
- # Two short lines meeting in an acute angle as in the +:open_arrow+ style and connected
196
- # by a third line to form a triangular closed arrowhead filled with the annotation’s
197
- # interior colour, if any.
198
- #
199
- # #>pdf-small-hide
200
- # doc.annotations.
201
- # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
202
- # interior_color("hp-orange").
203
- # line_ending_style(end_style: :closed_arrow).
204
- # regenerate_appearance
205
- #
206
- # :none or :None::
207
- # No line ending.
208
- #
209
- # #>pdf-small-hide
210
- # doc.annotations.
211
- # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
212
- # interior_color("hp-orange").
213
- # line_ending_style(end_style: :none).
214
- # regenerate_appearance
215
- #
216
- # :butt or :Butt::
217
- # A short line at the endpoint perpendicular to the line itself.
218
- #
219
- # #>pdf-small-hide
220
- # doc.annotations.
221
- # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
222
- # interior_color("hp-orange").
223
- # line_ending_style(end_style: :butt).
224
- # regenerate_appearance
225
- #
226
- # :ropen_arrow or :ROpenArrow::
227
- # Two short lines in the reverse direction from +:open_arrow+.
228
- #
229
- # #>pdf-small-hide
230
- # doc.annotations.
231
- # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
232
- # interior_color("hp-orange").
233
- # line_ending_style(end_style: :ropen_arrow).
234
- # regenerate_appearance
235
- #
236
- # :rclosed_arrow or :RClosedArrow::
237
- # A triangular closed arrowhead in the reverse direction from +:closed_arrow+.
238
- #
239
- # #>pdf-small-hide
240
- # doc.annotations.
241
- # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
242
- # interior_color("hp-orange").
243
- # line_ending_style(end_style: :rclosed_arrow).
244
- # regenerate_appearance
245
- #
246
- # :slash or :Slash::
247
- # A short line at the endpoint approximately 30 degrees clockwise from perpendicular to
248
- # the line itself.
249
- #
250
- # #>pdf-small-hide
251
- # doc.annotations.
252
- # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
253
- # interior_color("hp-orange").
254
- # line_ending_style(end_style: :slash).
255
- # regenerate_appearance
256
- def line_ending_style(start_style: :UNSET, end_style: :UNSET)
257
- if start_style == :UNSET && end_style == :UNSET
258
- le = self[:LE]
259
- LineEndingStyle.new(LINE_ENDING_STYLE_REVERSE_MAP.fetch(le[0], :none),
260
- LINE_ENDING_STYLE_REVERSE_MAP.fetch(le[1], :none))
261
- else
262
- start_style = self[:LE][0] if start_style == :UNSET
263
- end_style = self[:LE][1] if end_style == :UNSET
264
- start_style = LINE_ENDING_STYLE_MAP.fetch(start_style) do
265
- raise ArgumentError, "Invalid line ending style: #{start_style.inspect}"
266
- end
267
- end_style = LINE_ENDING_STYLE_MAP.fetch(end_style) do
268
- raise ArgumentError, "Invalid line ending style: #{end_style.inspect}"
269
- end
270
- self[:LE] = [start_style, end_style]
271
- self
272
- end
273
- end
274
-
275
- # :call-seq:
276
- # line.interior_color => color or nil
277
- # line.interior_color(*color) => line
278
- #
279
- # Returns the interior color or +nil+ (in case the interior color should be transparent)
280
- # when no argument is given. Otherwise sets the interior color and returns self.
281
- #
282
- # The interior color is used to fill the line endings depending on the line ending styles.
283
- #
284
- # +color+:: The interior color. See
285
- # HexaPDF::Content::ColorSpace.device_color_from_specification for information on
286
- # the allowed arguments.
287
- #
288
- # If the special value +:transparent+ is used when setting the color, no color is
289
- # used for filling the line endings.
290
- #
291
- # Also see: #line_ending_style
292
- def interior_color(*color)
293
- if color.empty?
294
- color = self[:IC]
295
- color && !color.empty? ? Content::ColorSpace.prenormalized_device_color(color.value) : nil
296
- else
297
- color = if color.length == 1 && color.first == :transparent
298
- []
299
- else
300
- Content::ColorSpace.device_color_from_specification(color).components
301
- end
302
- self[:IC] = color
303
- self
304
- end
305
- end
306
-
307
120
  # :call-seq:
308
121
  # line.leader_line_length => leader_line_length
309
122
  # line.leader_line_length(length) => line
@@ -0,0 +1,208 @@
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2014-2025 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #
33
+ # If the GNU Affero General Public License doesn't fit your need,
34
+ # commercial licenses are available at <https://gettalong.at/hexapdf/>.
35
+ #++
36
+
37
+ require 'hexapdf/type/annotations'
38
+
39
+ module HexaPDF
40
+ module Type
41
+ module Annotations
42
+
43
+ # This module provides a convenience method for getting and setting the line ending style for
44
+ # line and polyline annotations.
45
+ #
46
+ # See: PDF2.0 s12.5.6.7
47
+ module LineEndingStyling
48
+
49
+ # Maps HexaPDF names to PDF names.
50
+ LINE_ENDING_STYLE_MAP = { # :nodoc:
51
+ Square: :Square, square: :Square,
52
+ Circle: :Circle, circle: :Circle,
53
+ Diamond: :Diamond, diamond: :Diamond,
54
+ OpenArrow: :OpenArrow, open_arrow: :OpenArrow,
55
+ ClosedArrow: :ClosedArrow, closed_arrow: :ClosedArrow,
56
+ None: :None, none: :None,
57
+ Butt: :Butt, butt: :Butt,
58
+ ROpenArrow: :ROpenArrow, ropen_arrow: :ROpenArrow,
59
+ RClosedArrow: :RClosedArrow, rclosed_arrow: :RClosedArrow,
60
+ Slash: :Slash, slash: :Slash,
61
+ }.freeze
62
+ LINE_ENDING_STYLE_REVERSE_MAP = LINE_ENDING_STYLE_MAP.invert # :nodoc:
63
+
64
+ # Describes the line ending style, i.e. the +start_style+ and the +end_style+.
65
+ #
66
+ # See LineEndingStyling#line_ending_style for more information.
67
+ LineEndingStyle = Struct.new(:start_style, :end_style)
68
+
69
+ # :call-seq:
70
+ # annot.line_ending_style => style
71
+ # annot.line_ending_style(start_style: :none, end_style: :none) => line
72
+ #
73
+ # Returns a LineEndingStyle instance holding the current line ending styles when no argument
74
+ # is given. Otherwise sets the line ending style of the annotation and returns self.
75
+ #
76
+ # When returning the styles, unknown line ending styles are mapped to :none.
77
+ #
78
+ # When setting the line ending style, arguments that are not provided will use the currently
79
+ # defined value or fall back to the default of +:none+.
80
+ #
81
+ # Possible line ending styles (the first one is the HexaPDF name, the second the PDF name):
82
+ #
83
+ # :square or :Square::
84
+ # A square filled with the annotation's interior colour, if any.
85
+ #
86
+ # #>pdf-small-hide
87
+ # doc.annotations.
88
+ # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
89
+ # interior_color("hp-orange").
90
+ # line_ending_style(end_style: :square).
91
+ # regenerate_appearance
92
+ #
93
+ # :circle or :Circle::
94
+ # A circle filled with the annotation’s interior colour, if any.
95
+ #
96
+ # #>pdf-small-hide
97
+ # doc.annotations.
98
+ # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
99
+ # interior_color("hp-orange").
100
+ # line_ending_style(end_style: :circle).
101
+ # regenerate_appearance
102
+ #
103
+ # :diamond or :Diamond::
104
+ # A diamond shape filled with the annotation’s interior colour, if any.
105
+ #
106
+ # #>pdf-small-hide
107
+ # doc.annotations.
108
+ # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
109
+ # interior_color("hp-orange").
110
+ # line_ending_style(end_style: :diamond).
111
+ # regenerate_appearance
112
+ #
113
+ # :open_arrow or :OpenArrow::
114
+ # Two short lines meeting in an acute angle to form an open arrowhead.
115
+ #
116
+ # #>pdf-small-hide
117
+ # doc.annotations.
118
+ # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
119
+ # interior_color("hp-orange").
120
+ # line_ending_style(end_style: :open_arrow).
121
+ # regenerate_appearance
122
+ #
123
+ # :closed_arrow or :ClosedArrow::
124
+ # Two short lines meeting in an acute angle as in the +:open_arrow+ style and connected
125
+ # by a third line to form a triangular closed arrowhead filled with the annotation’s
126
+ # interior colour, if any.
127
+ #
128
+ # #>pdf-small-hide
129
+ # doc.annotations.
130
+ # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
131
+ # interior_color("hp-orange").
132
+ # line_ending_style(end_style: :closed_arrow).
133
+ # regenerate_appearance
134
+ #
135
+ # :none or :None::
136
+ # No line ending.
137
+ #
138
+ # #>pdf-small-hide
139
+ # doc.annotations.
140
+ # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
141
+ # interior_color("hp-orange").
142
+ # line_ending_style(end_style: :none).
143
+ # regenerate_appearance
144
+ #
145
+ # :butt or :Butt::
146
+ # A short line at the endpoint perpendicular to the line itself.
147
+ #
148
+ # #>pdf-small-hide
149
+ # doc.annotations.
150
+ # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
151
+ # interior_color("hp-orange").
152
+ # line_ending_style(end_style: :butt).
153
+ # regenerate_appearance
154
+ #
155
+ # :ropen_arrow or :ROpenArrow::
156
+ # Two short lines in the reverse direction from +:open_arrow+.
157
+ #
158
+ # #>pdf-small-hide
159
+ # doc.annotations.
160
+ # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
161
+ # interior_color("hp-orange").
162
+ # line_ending_style(end_style: :ropen_arrow).
163
+ # regenerate_appearance
164
+ #
165
+ # :rclosed_arrow or :RClosedArrow::
166
+ # A triangular closed arrowhead in the reverse direction from +:closed_arrow+.
167
+ #
168
+ # #>pdf-small-hide
169
+ # doc.annotations.
170
+ # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
171
+ # interior_color("hp-orange").
172
+ # line_ending_style(end_style: :rclosed_arrow).
173
+ # regenerate_appearance
174
+ #
175
+ # :slash or :Slash::
176
+ # A short line at the endpoint approximately 30 degrees clockwise from perpendicular to
177
+ # the line itself.
178
+ #
179
+ # #>pdf-small-hide
180
+ # doc.annotations.
181
+ # create_line(doc.pages[0], start_point: [20, 20], end_point: [80, 60]).
182
+ # interior_color("hp-orange").
183
+ # line_ending_style(end_style: :slash).
184
+ # regenerate_appearance
185
+ def line_ending_style(start_style: :UNSET, end_style: :UNSET)
186
+ if start_style == :UNSET && end_style == :UNSET
187
+ le = self[:LE]
188
+ LineEndingStyle.new(LINE_ENDING_STYLE_REVERSE_MAP.fetch(le[0], :none),
189
+ LINE_ENDING_STYLE_REVERSE_MAP.fetch(le[1], :none))
190
+ else
191
+ start_style = self[:LE][0] if start_style == :UNSET
192
+ end_style = self[:LE][1] if end_style == :UNSET
193
+ start_style = LINE_ENDING_STYLE_MAP.fetch(start_style) do
194
+ raise ArgumentError, "Invalid line ending style: #{start_style.inspect}"
195
+ end
196
+ end_style = LINE_ENDING_STYLE_MAP.fetch(end_style) do
197
+ raise ArgumentError, "Invalid line ending style: #{end_style.inspect}"
198
+ end
199
+ self[:LE] = [start_style, end_style]
200
+ self
201
+ end
202
+ end
203
+
204
+ end
205
+
206
+ end
207
+ end
208
+ end
@@ -61,7 +61,6 @@ module HexaPDF
61
61
 
62
62
  define_field :T, type: String, version: '1.1'
63
63
  define_field :Popup, type: :Annot, version: '1.3'
64
- define_field :CA, type: Numeric, default: 1.0, version: '1.4'
65
64
  define_field :RC, type: [Stream, String], version: '1.5'
66
65
  define_field :CreationDate, type: PDFDate, version: '1.5'
67
66
  define_field :IRT, type: Dictionary, version: '1.5'
@@ -0,0 +1,64 @@
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2014-2025 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #
33
+ # If the GNU Affero General Public License doesn't fit your need,
34
+ # commercial licenses are available at <https://gettalong.at/hexapdf/>.
35
+ #++
36
+
37
+ require 'hexapdf/type/annotations'
38
+
39
+ module HexaPDF
40
+ module Type
41
+ module Annotations
42
+
43
+ # A polygon annotation displays a closed polygon inside the annotation rectangle.
44
+ #
45
+ # Also see PolygonPolyline for more information.
46
+ #
47
+ # Example:
48
+ #
49
+ # #>pdf-small
50
+ # doc.annotations.create_polygon(doc.pages[0], 20, 20, 30, 70, 80, 60, 40, 30).
51
+ # border_style(color: "hp-blue", width: 2, style: [3, 1]).
52
+ # interior_color("hp-orange").
53
+ # regenerate_appearance
54
+ #
55
+ # See: PDF2.0 s12.5.6.9, HexaPDF::Type::Annotations::PolygonPolyline
56
+ class Polygon < PolygonPolyline
57
+
58
+ define_field :Subtype, type: Symbol, required: true, default: :Polygon
59
+
60
+ end
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,109 @@
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2014-2025 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #
33
+ # If the GNU Affero General Public License doesn't fit your need,
34
+ # commercial licenses are available at <https://gettalong.at/hexapdf/>.
35
+ #++
36
+
37
+ require 'hexapdf/type/annotations'
38
+
39
+ module HexaPDF
40
+ module Type
41
+ module Annotations
42
+
43
+ # This is the base class for the polygon and polyline markup annotations which display either
44
+ # a closed polygon or a polyline inside the annotation rectangle.
45
+ #
46
+ # The styling is done through methods included by various modules:
47
+ #
48
+ # * Changing the line width, line dash pattern and color is done using the method
49
+ # BorderStyling#border_style. While that method allows special styling of the line (like
50
+ # :beveled), only a simple line dash pattern is supported.
51
+ #
52
+ # * The border effect can be changed through BorderEffect#border_effect. Note that cloudy
53
+ # borders are not supported.
54
+ #
55
+ # * The interior color can be changed through InteriorColor#interior_color.
56
+ #
57
+ # * The line ending style can be changed through LineEndingStyling#line_ending_style.
58
+ #
59
+ # See: PDF2.0 s12.5.6.9, HexaPDF::Type::Annotations::Polyline,
60
+ # HexaPDF::Type::Annotations::Polygon, HexaPDF::Type::MarkupAnnotation
61
+ class PolygonPolyline < MarkupAnnotation
62
+
63
+ include BorderStyling
64
+ include BorderEffect
65
+ include InteriorColor
66
+ include LineEndingStyling
67
+
68
+ # Field Subtype is defined in the two subclasses
69
+ define_field :Vertices, type: PDFArray, required: true
70
+ define_field :LE, type: PDFArray, default: [:None, :None]
71
+ define_field :BS, type: :Border
72
+ define_field :IC, type: PDFArray
73
+ define_field :BE, type: :XXBorderEffect, version: '1.5'
74
+ define_field :IT, type: Symbol, version: '1.6',
75
+ allowed_values: [:PolygonCloud, :PolyLineDimension, :PolygonDimension]
76
+ define_field :Measure, type: :Measure, version: '1.7'
77
+ define_field :Path, type: PDFArray, version: '2.0'
78
+
79
+ # :call-seq:
80
+ # annot.vertices => [x0, y0, x1, y1, ...]
81
+ # annot.vertices(*points) => annot
82
+ #
83
+ # Returns the array with the vertices, alternating between horizontal and vertical
84
+ # coordinates, when no argument is given. Otherwise sets the vertices and returns self.
85
+ #
86
+ # This is the only required setting. Note, however, that without setting the appearance
87
+ # style through convenience methods like #border_style nothing will be shown.
88
+ #
89
+ # Example:
90
+ #
91
+ # #>pdf-small
92
+ # doc.annotations.
93
+ # create_polyline(doc.pages[0], 20, 20, 30, 70, 80, 60, 40, 30).
94
+ # regenerate_appearance
95
+ def vertices(*points)
96
+ if points.empty?
97
+ self[:Vertices].to_ary
98
+ elsif points.length % 2 != 0
99
+ raise ArgumentError, "An even number of arguments must be provided"
100
+ else
101
+ self[:Vertices] = points
102
+ self
103
+ end
104
+ end
105
+ end
106
+
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,64 @@
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2014-2025 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #
33
+ # If the GNU Affero General Public License doesn't fit your need,
34
+ # commercial licenses are available at <https://gettalong.at/hexapdf/>.
35
+ #++
36
+
37
+ require 'hexapdf/type/annotations'
38
+
39
+ module HexaPDF
40
+ module Type
41
+ module Annotations
42
+
43
+ # A polyline annotation displays a polyline inside the annotation rectangle.
44
+ #
45
+ # Also see PolygonPolyline for more information.
46
+ #
47
+ # Example:
48
+ #
49
+ # #>pdf-small
50
+ # doc.annotations.create_polyline(doc.pages[0], 20, 20, 30, 70, 80, 60, 40, 30).
51
+ # border_style(color: "hp-blue", width: 2, style: [3, 1]).
52
+ # interior_color("hp-orange").
53
+ # regenerate_appearance
54
+ #
55
+ # See: PDF2.0 s12.5.6.9, HexaPDF::Type::Annotations::PolygonPolyline
56
+ class Polyline < PolygonPolyline
57
+
58
+ define_field :Subtype, type: Symbol, required: true, default: :PolyLine
59
+
60
+ end
61
+
62
+ end
63
+ end
64
+ end