hexapdf 0.32.1 → 0.33.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +76 -1
- data/README.md +9 -0
- data/examples/002-graphics.rb +15 -17
- data/examples/003-arcs.rb +9 -9
- data/examples/009-text_layouter_alignment.rb +1 -1
- data/examples/010-text_layouter_inline_boxes.rb +2 -2
- data/examples/011-text_layouter_line_wrapping.rb +1 -1
- data/examples/012-text_layouter_styling.rb +7 -7
- data/examples/013-text_layouter_shapes.rb +1 -1
- data/examples/014-text_in_polygon.rb +1 -1
- data/examples/015-boxes.rb +8 -7
- data/examples/016-frame_automatic_box_placement.rb +2 -2
- data/examples/017-frame_text_flow.rb +2 -1
- data/examples/018-composer.rb +1 -1
- data/examples/020-column_box.rb +2 -1
- data/examples/025-table_box.rb +46 -0
- data/lib/hexapdf/cli/command.rb +5 -2
- data/lib/hexapdf/cli/form.rb +5 -5
- data/lib/hexapdf/cli/inspect.rb +3 -3
- data/lib/hexapdf/cli.rb +4 -0
- data/lib/hexapdf/composer.rb +104 -52
- data/lib/hexapdf/configuration.rb +44 -39
- data/lib/hexapdf/content/canvas.rb +393 -267
- data/lib/hexapdf/content/color_space.rb +72 -25
- data/lib/hexapdf/content/graphic_object/arc.rb +57 -24
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +66 -23
- data/lib/hexapdf/content/graphic_object/geom2d.rb +47 -6
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +58 -36
- data/lib/hexapdf/content/graphic_object.rb +6 -7
- data/lib/hexapdf/content/graphics_state.rb +54 -45
- data/lib/hexapdf/content/operator.rb +52 -54
- data/lib/hexapdf/content/parser.rb +2 -2
- data/lib/hexapdf/content/processor.rb +15 -15
- data/lib/hexapdf/content/transformation_matrix.rb +1 -1
- data/lib/hexapdf/content.rb +5 -0
- data/lib/hexapdf/dictionary.rb +6 -5
- data/lib/hexapdf/dictionary_fields.rb +42 -14
- data/lib/hexapdf/digital_signature/cms_handler.rb +2 -2
- data/lib/hexapdf/digital_signature/handler.rb +1 -1
- data/lib/hexapdf/digital_signature/pkcs1_handler.rb +2 -3
- data/lib/hexapdf/digital_signature/signature.rb +6 -6
- data/lib/hexapdf/digital_signature/signatures.rb +13 -12
- data/lib/hexapdf/digital_signature/signing/default_handler.rb +14 -5
- data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +2 -4
- data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +4 -4
- data/lib/hexapdf/digital_signature/signing.rb +4 -0
- data/lib/hexapdf/digital_signature/verification_result.rb +2 -2
- data/lib/hexapdf/digital_signature.rb +7 -2
- data/lib/hexapdf/document/destinations.rb +12 -11
- data/lib/hexapdf/document/files.rb +1 -1
- data/lib/hexapdf/document/fonts.rb +1 -1
- data/lib/hexapdf/document/layout.rb +167 -39
- data/lib/hexapdf/document/pages.rb +3 -2
- data/lib/hexapdf/document.rb +89 -55
- data/lib/hexapdf/encryption/aes.rb +5 -5
- data/lib/hexapdf/encryption/arc4.rb +1 -1
- data/lib/hexapdf/encryption/fast_aes.rb +2 -2
- data/lib/hexapdf/encryption/fast_arc4.rb +1 -1
- data/lib/hexapdf/encryption/identity.rb +1 -1
- data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
- data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
- data/lib/hexapdf/encryption/security_handler.rb +31 -24
- data/lib/hexapdf/encryption/standard_security_handler.rb +45 -36
- data/lib/hexapdf/encryption.rb +7 -2
- data/lib/hexapdf/error.rb +18 -0
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
- data/lib/hexapdf/filter/flate_decode.rb +1 -1
- data/lib/hexapdf/filter/lzw_decode.rb +1 -1
- data/lib/hexapdf/filter/pass_through.rb +1 -1
- data/lib/hexapdf/filter/predictor.rb +1 -1
- data/lib/hexapdf/filter/run_length_decode.rb +1 -1
- data/lib/hexapdf/filter.rb +55 -6
- data/lib/hexapdf/font/cmap/parser.rb +2 -2
- data/lib/hexapdf/font/cmap.rb +1 -1
- data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +3 -3
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
- data/lib/hexapdf/font/invalid_glyph.rb +3 -0
- data/lib/hexapdf/font/true_type_wrapper.rb +17 -4
- data/lib/hexapdf/font/type1_wrapper.rb +19 -4
- data/lib/hexapdf/font_loader/from_configuration.rb +5 -2
- data/lib/hexapdf/font_loader/from_file.rb +5 -5
- data/lib/hexapdf/font_loader/standard14.rb +3 -3
- data/lib/hexapdf/font_loader.rb +3 -0
- data/lib/hexapdf/image_loader/jpeg.rb +2 -2
- data/lib/hexapdf/image_loader/pdf.rb +1 -1
- data/lib/hexapdf/image_loader/png.rb +2 -2
- data/lib/hexapdf/image_loader.rb +1 -1
- data/lib/hexapdf/importer.rb +13 -0
- data/lib/hexapdf/layout/box.rb +9 -2
- data/lib/hexapdf/layout/box_fitter.rb +2 -2
- data/lib/hexapdf/layout/column_box.rb +18 -4
- data/lib/hexapdf/layout/frame.rb +30 -12
- data/lib/hexapdf/layout/image_box.rb +5 -0
- data/lib/hexapdf/layout/inline_box.rb +1 -0
- data/lib/hexapdf/layout/list_box.rb +17 -1
- data/lib/hexapdf/layout/page_style.rb +4 -4
- data/lib/hexapdf/layout/style.rb +18 -3
- data/lib/hexapdf/layout/table_box.rb +682 -0
- data/lib/hexapdf/layout/text_box.rb +5 -3
- data/lib/hexapdf/layout/text_fragment.rb +1 -1
- data/lib/hexapdf/layout/text_layouter.rb +12 -4
- data/lib/hexapdf/layout.rb +1 -0
- data/lib/hexapdf/name_tree_node.rb +1 -1
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/object.rb +18 -7
- data/lib/hexapdf/parser.rb +8 -8
- data/lib/hexapdf/pdf_array.rb +1 -1
- data/lib/hexapdf/rectangle.rb +1 -1
- data/lib/hexapdf/reference.rb +1 -1
- data/lib/hexapdf/revision.rb +1 -1
- data/lib/hexapdf/revisions.rb +3 -3
- data/lib/hexapdf/serializer.rb +15 -15
- data/lib/hexapdf/stream.rb +4 -2
- data/lib/hexapdf/tokenizer.rb +14 -14
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +22 -22
- data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/field.rb +2 -2
- data/lib/hexapdf/type/acro_form/form.rb +1 -1
- data/lib/hexapdf/type/acro_form/signature_field.rb +4 -4
- data/lib/hexapdf/type/acro_form/text_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/variable_text_field.rb +1 -1
- data/lib/hexapdf/type/acro_form.rb +1 -1
- data/lib/hexapdf/type/action.rb +1 -1
- data/lib/hexapdf/type/actions/go_to.rb +1 -1
- data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
- data/lib/hexapdf/type/actions/launch.rb +1 -1
- data/lib/hexapdf/type/actions/uri.rb +1 -1
- data/lib/hexapdf/type/actions.rb +1 -1
- data/lib/hexapdf/type/annotation.rb +3 -3
- data/lib/hexapdf/type/annotations/link.rb +1 -1
- data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
- data/lib/hexapdf/type/annotations/text.rb +1 -1
- data/lib/hexapdf/type/annotations/widget.rb +2 -2
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/catalog.rb +1 -1
- data/lib/hexapdf/type/cid_font.rb +3 -3
- data/lib/hexapdf/type/embedded_file.rb +1 -1
- data/lib/hexapdf/type/file_specification.rb +2 -2
- data/lib/hexapdf/type/font_descriptor.rb +1 -1
- data/lib/hexapdf/type/font_simple.rb +2 -2
- data/lib/hexapdf/type/font_type0.rb +3 -3
- data/lib/hexapdf/type/font_type3.rb +1 -1
- data/lib/hexapdf/type/form.rb +1 -1
- data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
- data/lib/hexapdf/type/icon_fit.rb +1 -1
- data/lib/hexapdf/type/image.rb +1 -1
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/mark_information.rb +1 -1
- data/lib/hexapdf/type/names.rb +2 -2
- data/lib/hexapdf/type/object_stream.rb +7 -3
- data/lib/hexapdf/type/outline.rb +1 -1
- data/lib/hexapdf/type/outline_item.rb +1 -1
- data/lib/hexapdf/type/page.rb +19 -10
- data/lib/hexapdf/type/page_label.rb +1 -1
- data/lib/hexapdf/type/page_tree_node.rb +1 -1
- data/lib/hexapdf/type/resources.rb +1 -1
- data/lib/hexapdf/type/trailer.rb +2 -2
- data/lib/hexapdf/type/viewer_preferences.rb +1 -1
- data/lib/hexapdf/type/xref_stream.rb +2 -2
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
- data/lib/hexapdf/version.rb +1 -1
- data/lib/hexapdf/writer.rb +4 -4
- data/lib/hexapdf/xref_section.rb +2 -2
- data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +11 -1
- data/test/hexapdf/content/graphic_object/test_geom2d.rb +7 -0
- data/test/hexapdf/content/test_canvas.rb +0 -1
- data/test/hexapdf/digital_signature/test_signatures.rb +22 -0
- data/test/hexapdf/document/test_files.rb +2 -2
- data/test/hexapdf/document/test_layout.rb +98 -0
- data/test/hexapdf/encryption/test_security_handler.rb +12 -11
- data/test/hexapdf/encryption/test_standard_security_handler.rb +35 -23
- data/test/hexapdf/font/test_true_type_wrapper.rb +18 -1
- data/test/hexapdf/font/test_type1_wrapper.rb +15 -1
- data/test/hexapdf/layout/test_box.rb +1 -1
- data/test/hexapdf/layout/test_column_box.rb +65 -21
- data/test/hexapdf/layout/test_frame.rb +14 -14
- data/test/hexapdf/layout/test_image_box.rb +4 -0
- data/test/hexapdf/layout/test_inline_box.rb +5 -0
- data/test/hexapdf/layout/test_list_box.rb +40 -6
- data/test/hexapdf/layout/test_page_style.rb +3 -2
- data/test/hexapdf/layout/test_style.rb +50 -0
- data/test/hexapdf/layout/test_table_box.rb +722 -0
- data/test/hexapdf/layout/test_text_box.rb +18 -0
- data/test/hexapdf/layout/test_text_layouter.rb +4 -0
- data/test/hexapdf/test_dictionary_fields.rb +4 -1
- data/test/hexapdf/test_document.rb +1 -0
- data/test/hexapdf/test_filter.rb +8 -0
- data/test/hexapdf/test_importer.rb +9 -0
- data/test/hexapdf/test_object.rb +16 -5
- data/test/hexapdf/test_parser.rb +1 -1
- data/test/hexapdf/test_stream.rb +7 -0
- data/test/hexapdf/test_writer.rb +3 -3
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +13 -5
- data/test/hexapdf/type/acro_form/test_form.rb +4 -3
- data/test/hexapdf/type/test_object_stream.rb +9 -3
- data/test/hexapdf/type/test_page.rb +18 -4
- metadata +17 -8
@@ -87,6 +87,9 @@ module HexaPDF
|
|
87
87
|
# Returns the color corresponding to the given arguments without applying value normalization.
|
88
88
|
# The number and types of the arguments differ from one color space to another.
|
89
89
|
#
|
90
|
+
# This method should be used when the arguments are already normalized (e.g. when loaded from
|
91
|
+
# a content stream).
|
92
|
+
#
|
90
93
|
# The class representing a color in the color space needs to respond to the following methods:
|
91
94
|
#
|
92
95
|
# #color_space::
|
@@ -95,24 +98,26 @@ module HexaPDF
|
|
95
98
|
# #components::
|
96
99
|
# Returns an array of components that uniquely identifies this color within the color space.
|
97
100
|
#
|
98
|
-
# See:
|
101
|
+
# See: PDF2.0 s8.6
|
99
102
|
module ColorSpace
|
100
103
|
|
101
|
-
# Mapping of CSS Color Module Level 3 names
|
104
|
+
# Mapping of color names (CSS Color Module Level 3 names - see
|
105
|
+
# https://www.w3.org/TR/css-color-3/#svg-color - and HexaPDF design color names) to RGB and
|
106
|
+
# gray values.
|
102
107
|
#
|
103
108
|
# Visual listing of all colors:
|
104
109
|
#
|
105
110
|
# #>pdf-big
|
106
|
-
# canvas.font("Helvetica", size:
|
107
|
-
# map = HexaPDF::Content::ColorSpace::
|
108
|
-
# map.each_slice(
|
111
|
+
# canvas.font("Helvetica", size: 7.5)
|
112
|
+
# map = HexaPDF::Content::ColorSpace::COLOR_NAMES
|
113
|
+
# map.each_slice(43).each_with_index do |slice, col|
|
109
114
|
# x = 10 + col * 100
|
110
115
|
# slice.each_with_index do |(name, rgb), row|
|
111
|
-
# canvas.fill_color(rgb).rectangle(x, 380 - row *
|
112
|
-
# canvas.fill_color("black").text(name, at: [x + 15, 380 - row *
|
116
|
+
# canvas.fill_color(rgb).rectangle(x, 380 - row * 9, 9, 9).fill
|
117
|
+
# canvas.fill_color("black").text(name, at: [x + 15, 380 - row * 9 + 2])
|
113
118
|
# end
|
114
119
|
# end
|
115
|
-
|
120
|
+
COLOR_NAMES = {
|
116
121
|
"aliceblue" => [240, 248, 255],
|
117
122
|
"antiquewhite" => [250, 235, 215],
|
118
123
|
"aqua" => [0, 255, 255],
|
@@ -137,9 +142,9 @@ module HexaPDF
|
|
137
142
|
"darkblue" => [0, 0, 139],
|
138
143
|
"darkcyan" => [0, 139, 139],
|
139
144
|
"darkgoldenrod" => [184, 134, 11],
|
140
|
-
"darkgray" => [169
|
145
|
+
"darkgray" => [169],
|
141
146
|
"darkgreen" => [0, 100, 0],
|
142
|
-
"darkgrey" => [169
|
147
|
+
"darkgrey" => [169],
|
143
148
|
"darkkhaki" => [189, 183, 107],
|
144
149
|
"darkmagenta" => [139, 0, 139],
|
145
150
|
"darkolivegreen" => [85, 107, 47],
|
@@ -155,8 +160,8 @@ module HexaPDF
|
|
155
160
|
"darkviolet" => [148, 0, 211],
|
156
161
|
"deeppink" => [255, 20, 147],
|
157
162
|
"deepskyblue" => [0, 191, 255],
|
158
|
-
"dimgray" => [105
|
159
|
-
"dimgrey" => [105
|
163
|
+
"dimgray" => [105],
|
164
|
+
"dimgrey" => [105],
|
160
165
|
"dodgerblue" => [30, 144, 255],
|
161
166
|
"firebrick" => [178, 34, 34],
|
162
167
|
"floralwhite" => [255, 250, 240],
|
@@ -166,10 +171,10 @@ module HexaPDF
|
|
166
171
|
"ghostwhite" => [248, 248, 255],
|
167
172
|
"gold" => [255, 215, 0],
|
168
173
|
"goldenrod" => [218, 165, 32],
|
169
|
-
"gray" => [128
|
174
|
+
"gray" => [128],
|
170
175
|
"green" => [0, 128, 0],
|
171
176
|
"greenyellow" => [173, 255, 47],
|
172
|
-
"grey" => [128
|
177
|
+
"grey" => [128],
|
173
178
|
"honeydew" => [240, 255, 240],
|
174
179
|
"hotpink" => [255, 105, 180],
|
175
180
|
"indianred" => [205, 92, 92],
|
@@ -184,7 +189,7 @@ module HexaPDF
|
|
184
189
|
"lightcoral" => [240, 128, 128],
|
185
190
|
"lightcyan" => [224, 255, 255],
|
186
191
|
"lightgoldenrodyellow" => [250, 250, 210],
|
187
|
-
"lightgray" => [211
|
192
|
+
"lightgray" => [211],
|
188
193
|
"lightgreen" => [144, 238, 144],
|
189
194
|
"lightgrey" => [211, 211, 211],
|
190
195
|
"lightpink" => [255, 182, 193],
|
@@ -260,6 +265,24 @@ module HexaPDF
|
|
260
265
|
"whitesmoke" => [245, 245, 245],
|
261
266
|
"yellow" => [255, 255, 0],
|
262
267
|
"yellowgreen" => [154, 205, 50],
|
268
|
+
"hp-blue" => [0, 128, 255],
|
269
|
+
"hp-blue-dark" => [28, 91, 216],
|
270
|
+
"hp-blue-dark2" => [34, 57, 184],
|
271
|
+
"hp-blue-light" => [86, 176, 255],
|
272
|
+
"hp-blue-light2" => [185, 220, 255],
|
273
|
+
"hp-orange" => [255, 128, 0],
|
274
|
+
"hp-orange-light" => [255, 195, 29],
|
275
|
+
"hp-orange-light2" => [255, 246, 153],
|
276
|
+
"hp-teal" => [0, 140, 130],
|
277
|
+
"hp-teal-dark" => [5, 100, 94],
|
278
|
+
"hp-teal-dark2" => [6, 70, 63],
|
279
|
+
"hp-teal-light" => [75, 177, 176],
|
280
|
+
"hp-teal-light2" => [177, 221, 221],
|
281
|
+
"hp-gray" => [158],
|
282
|
+
"hp-gray-dark" => [97],
|
283
|
+
"hp-gray-dark2" => [33],
|
284
|
+
"hp-gray-light" => [224],
|
285
|
+
"hp-gray-light2" => [245],
|
263
286
|
}.freeze
|
264
287
|
|
265
288
|
# :call-seq:
|
@@ -269,7 +292,7 @@ module HexaPDF
|
|
269
292
|
# ColorSpace.device_color_from_specification(string) => color
|
270
293
|
# ColorSpace.device_color_from_specification(array) => color
|
271
294
|
#
|
272
|
-
# Creates a device color object from the given color specification.
|
295
|
+
# Creates and returns a device color object from the given color specification.
|
273
296
|
#
|
274
297
|
# There are several ways to define the color that should be used:
|
275
298
|
#
|
@@ -279,8 +302,8 @@ module HexaPDF
|
|
279
302
|
# for the green and "BB" for the blue color value also specifies an RGB color.
|
280
303
|
# * As does a string in the format "RGB" where "RR", "GG" and "BB" would be used as the
|
281
304
|
# hexadecimal numbers for the red, green and blue color values of an RGB color.
|
282
|
-
# * Any other string is treated as a CSS Color Module Level 3
|
283
|
-
#
|
305
|
+
# * Any other string is treated as a color name (CSS Color Module Level 3 and HexaPDF design
|
306
|
+
# color names are supported - see COLOR_NAMES).
|
284
307
|
# * Four numeric arguments specify a CMYK color (see DeviceCMYK::Color).
|
285
308
|
# * An array is treated as if its items were specified separately as arguments.
|
286
309
|
#
|
@@ -288,7 +311,30 @@ module HexaPDF
|
|
288
311
|
# values are first normalized (expected range by the PDF specification is 0.0 - 1.0) - see
|
289
312
|
# DeviceGray#color, DeviceRGB#color and DeviceCMYK#color for details.
|
290
313
|
#
|
291
|
-
#
|
314
|
+
# Examples:
|
315
|
+
#
|
316
|
+
# #>pdf
|
317
|
+
# cs = HexaPDF::Content::ColorSpace
|
318
|
+
# canvas.line_width(5)
|
319
|
+
#
|
320
|
+
# # Note that Canvas#stroke_color implicitly uses this method, so
|
321
|
+
# # explicitly using it like in this example is not needed
|
322
|
+
# canvas.stroke_color(cs.device_color_from_specification(160))
|
323
|
+
# canvas.line(10, 10, 10, 190).stroke
|
324
|
+
# canvas.stroke_color(cs.device_color_from_specification(0, 128, 255))
|
325
|
+
# canvas.line(35, 10, 35, 190).stroke
|
326
|
+
# canvas.stroke_color(cs.device_color_from_specification("0088FF"))
|
327
|
+
# canvas.line(60, 10, 60, 190).stroke
|
328
|
+
# canvas.stroke_color(cs.device_color_from_specification("08F"))
|
329
|
+
# canvas.line(85, 10, 85, 190).stroke
|
330
|
+
# canvas.stroke_color(cs.device_color_from_specification("gold"))
|
331
|
+
# canvas.line(110, 10, 110, 190).stroke
|
332
|
+
# canvas.stroke_color(cs.device_color_from_specification("hp-blue"))
|
333
|
+
# canvas.line(135, 10, 135, 190).stroke
|
334
|
+
# canvas.stroke_color(cs.device_color_from_specification(10, 50, 0, 60))
|
335
|
+
# canvas.line(160, 10, 160, 190).stroke
|
336
|
+
# canvas.stroke_color(cs.device_color_from_specification([0, 128, 255]))
|
337
|
+
# canvas.line(185, 10, 185, 190).stroke
|
292
338
|
def self.device_color_from_specification(*spec)
|
293
339
|
spec.flatten!
|
294
340
|
first_item = spec[0]
|
@@ -297,10 +343,11 @@ module HexaPDF
|
|
297
343
|
first_item.scan(/../).map!(&:hex)
|
298
344
|
elsif first_item.match?(/\A\h{3}\z/)
|
299
345
|
first_item.each_char.map {|x| (x * 2).hex }
|
300
|
-
elsif
|
301
|
-
|
346
|
+
elsif COLOR_NAMES.key?(first_item)
|
347
|
+
COLOR_NAMES[first_item]
|
302
348
|
else
|
303
|
-
raise ArgumentError, "Given string is neither a hex color
|
349
|
+
raise ArgumentError, "Given string '#{first_item}' is neither a hex color " \
|
350
|
+
"nor a color name"
|
304
351
|
end
|
305
352
|
end
|
306
353
|
GlobalConfiguration.constantize('color_space.map', for_components(spec)).new.color(*spec)
|
@@ -470,7 +517,7 @@ module HexaPDF
|
|
470
517
|
|
471
518
|
# A color in the DeviceRGB color space.
|
472
519
|
#
|
473
|
-
# See:
|
520
|
+
# See: PDF2.0 s8.6.4.3
|
474
521
|
class Color
|
475
522
|
|
476
523
|
include ColorUtils
|
@@ -540,7 +587,7 @@ module HexaPDF
|
|
540
587
|
|
541
588
|
# A color in the DeviceCMYK color space.
|
542
589
|
#
|
543
|
-
# See:
|
590
|
+
# See: PDF2.0 s8.6.4.4
|
544
591
|
class Color
|
545
592
|
|
546
593
|
include ColorUtils
|
@@ -610,7 +657,7 @@ module HexaPDF
|
|
610
657
|
|
611
658
|
# A color in the DeviceGray color space.
|
612
659
|
#
|
613
|
-
# See:
|
660
|
+
# See: PDF2.0 s8.6.4.2
|
614
661
|
class Color
|
615
662
|
|
616
663
|
include ColorUtils
|
@@ -45,6 +45,9 @@ module HexaPDF
|
|
45
45
|
# all either in clockwise or counterclockwise direction and optionally inclined in respect to
|
46
46
|
# the x-axis.
|
47
47
|
#
|
48
|
+
# Note that only the path of the arc itself is added to the canvas. So depending on the
|
49
|
+
# use-case the path itself still has to be, for example, stroked.
|
50
|
+
#
|
48
51
|
# This graphic object is registered under the :arc key for use with the
|
49
52
|
# HexaPDF::Content::Canvas class.
|
50
53
|
#
|
@@ -75,66 +78,64 @@ module HexaPDF
|
|
75
78
|
# Examples:
|
76
79
|
#
|
77
80
|
# #>pdf-center
|
78
|
-
# arc = canvas.graphic_object(:arc, cx: -50, a: 40, b: 40)
|
79
|
-
# arc.max_curves = 2
|
81
|
+
# arc = canvas.graphic_object(:arc, cx: -50, a: 40, b: 40, max_curves: 2)
|
80
82
|
# canvas.draw(arc)
|
81
|
-
# arc
|
82
|
-
# canvas.draw(arc, cx: 50)
|
83
|
+
# canvas.draw(arc, cx: 50, max_curves: 10)
|
83
84
|
# canvas.stroke
|
84
85
|
attr_accessor :max_curves
|
85
86
|
|
86
|
-
# x-coordinate of center point
|
87
|
+
# x-coordinate of center point, defaults to 0.
|
87
88
|
#
|
88
89
|
# Examples:
|
89
90
|
#
|
90
91
|
# #>pdf-center
|
91
92
|
# arc = canvas.graphic_object(:arc, a: 30, b: 20)
|
92
93
|
# canvas.draw(arc).stroke
|
93
|
-
# canvas.stroke_color("
|
94
|
+
# canvas.stroke_color("hp-blue").draw(arc, cx: 50).stroke
|
94
95
|
attr_reader :cx
|
95
96
|
|
96
|
-
# y-coordinate of center point
|
97
|
+
# y-coordinate of center point, defaults to 0.
|
97
98
|
#
|
98
99
|
# Examples:
|
99
100
|
#
|
100
101
|
# #>pdf-center
|
101
102
|
# arc = canvas.graphic_object(:arc, a: 30, b: 20)
|
102
103
|
# canvas.draw(arc).stroke
|
103
|
-
# canvas.stroke_color("
|
104
|
+
# canvas.stroke_color("hp-blue").draw(arc, cy: 50).stroke
|
104
105
|
attr_reader :cy
|
105
106
|
|
106
107
|
# Length of semi-major axis which (without altering the #inclination) is parallel to the
|
107
|
-
# x-axis
|
108
|
+
# x-axis, defaults to 1.
|
108
109
|
#
|
109
110
|
# Examples:
|
110
111
|
#
|
111
112
|
# #>pdf-center
|
112
113
|
# arc = canvas.graphic_object(:arc, a: 30, b: 30)
|
113
114
|
# canvas.draw(arc).stroke
|
114
|
-
# canvas.stroke_color("
|
115
|
+
# canvas.stroke_color("hp-blue").draw(arc, a: 60).stroke
|
115
116
|
attr_reader :a
|
116
117
|
|
117
118
|
# Length of semi-minor axis which (without altering the #inclination) is parallel to the
|
118
|
-
# y-axis
|
119
|
+
# y-axis, defaults to 1.
|
119
120
|
#
|
120
121
|
# Examples:
|
121
122
|
#
|
122
123
|
# #>pdf-center
|
123
124
|
# arc = canvas.graphic_object(:arc, a: 30, b: 30)
|
124
125
|
# canvas.draw(arc).stroke
|
125
|
-
# canvas.stroke_color("
|
126
|
+
# canvas.stroke_color("hp-blue").draw(arc, b: 60).stroke
|
126
127
|
attr_reader :b
|
127
128
|
|
128
|
-
# Start angle of the arc in degrees
|
129
|
+
# Start angle of the arc in degrees, defaults to 0.
|
129
130
|
#
|
130
131
|
# Examples:
|
131
132
|
#
|
132
133
|
# #>pdf-center
|
133
134
|
# arc = canvas.graphic_object(:arc, a: 30, b: 30)
|
134
|
-
# canvas.draw(arc, start_angle:
|
135
|
+
# canvas.draw(arc, start_angle: 110).stroke
|
135
136
|
attr_reader :start_angle
|
136
137
|
|
137
|
-
# End angle of the arc in degrees
|
138
|
+
# End angle of the arc in degrees, defaults to 0.
|
138
139
|
#
|
139
140
|
# Examples:
|
140
141
|
#
|
@@ -143,7 +144,7 @@ module HexaPDF
|
|
143
144
|
# canvas.draw(arc, end_angle: 160).stroke
|
144
145
|
attr_reader :end_angle
|
145
146
|
|
146
|
-
# Inclination in degrees of the semi-major axis with respect to the x-axis
|
147
|
+
# Inclination in degrees of the semi-major axis with respect to the x-axis, defaults to 0.
|
147
148
|
#
|
148
149
|
# Examples:
|
149
150
|
#
|
@@ -153,6 +154,7 @@ module HexaPDF
|
|
153
154
|
attr_reader :inclination
|
154
155
|
|
155
156
|
# Direction of arc - if +true+ in clockwise direction, else in counterclockwise direction
|
157
|
+
# (the default).
|
156
158
|
#
|
157
159
|
# This is needed when filling paths using the nonzero winding number rule to achieve
|
158
160
|
# different effects.
|
@@ -161,7 +163,8 @@ module HexaPDF
|
|
161
163
|
#
|
162
164
|
# #>pdf-center
|
163
165
|
# arc = canvas.graphic_object(:arc, a: 40, b: 40)
|
164
|
-
# canvas.
|
166
|
+
# canvas.fill_color("hp-blue").
|
167
|
+
# draw(arc, cx: -50).draw(arc, cx: 50).
|
165
168
|
# draw(arc, cx: -50, b: 80).
|
166
169
|
# draw(arc, cx: 50, b: 80, clockwise: true).
|
167
170
|
# fill(:nonzero)
|
@@ -192,17 +195,27 @@ module HexaPDF
|
|
192
195
|
# * semi-minor axis +b+,
|
193
196
|
# * start angle of +start_angle+ degrees,
|
194
197
|
# * end angle of +end_angle+ degrees and
|
195
|
-
# * an inclination in respect to the x-axis of +inclination+ degrees
|
198
|
+
# * an inclination in respect to the x-axis of +inclination+ degrees,
|
199
|
+
# * as well as the maximal number of curves +max_curves+ used for approximation.
|
196
200
|
#
|
197
201
|
# The +clockwise+ argument determines if the arc is drawn in the counterclockwise direction
|
198
202
|
# (+false+) or in the clockwise direction (+true+).
|
199
203
|
#
|
204
|
+
# For the meaning of +max_curves+ see the description of #max_curves.
|
205
|
+
#
|
200
206
|
# Any arguments not specified are not modified and retain their old value, see #initialize
|
201
207
|
# for the inital values.
|
202
208
|
#
|
203
209
|
# Returns self.
|
210
|
+
#
|
211
|
+
# Examples:
|
212
|
+
#
|
213
|
+
# #>pdf-center
|
214
|
+
# arc = canvas.graphic_object(:arc)
|
215
|
+
# arc.configure(cx: 50, a: 40, b: 20, inclination: 10)
|
216
|
+
# canvas.draw(arc).stroke
|
204
217
|
def configure(cx: nil, cy: nil, a: nil, b: nil, start_angle: nil, end_angle: nil,
|
205
|
-
inclination: nil, clockwise: nil)
|
218
|
+
inclination: nil, clockwise: nil, max_curves: nil)
|
206
219
|
@cx = cx if cx
|
207
220
|
@cy = cy if cy
|
208
221
|
@a = a.abs if a
|
@@ -214,6 +227,7 @@ module HexaPDF
|
|
214
227
|
@end_angle = end_angle if end_angle
|
215
228
|
@inclination = inclination if inclination
|
216
229
|
@clockwise = clockwise unless clockwise.nil?
|
230
|
+
@max_curves = max_curves if max_curves
|
217
231
|
calculate_cached_values
|
218
232
|
self
|
219
233
|
end
|
@@ -225,7 +239,7 @@ module HexaPDF
|
|
225
239
|
# #>pdf-center
|
226
240
|
# arc = canvas.graphic_object(:arc, a: 40, b: 30, start_angle: 60)
|
227
241
|
# canvas.draw(arc).stroke
|
228
|
-
# canvas.fill_color("
|
242
|
+
# canvas.fill_color("hp-blue").circle(*arc.start_point, 2).fill
|
229
243
|
def start_point
|
230
244
|
evaluate(@start_eta)
|
231
245
|
end
|
@@ -237,7 +251,7 @@ module HexaPDF
|
|
237
251
|
# #>pdf-center
|
238
252
|
# arc = canvas.graphic_object(:arc, a: 40, b: 30, end_angle: 245)
|
239
253
|
# canvas.draw(arc).stroke
|
240
|
-
# canvas.fill_color("
|
254
|
+
# canvas.fill_color("hp-blue").circle(*arc.end_point, 2).fill
|
241
255
|
def end_point
|
242
256
|
evaluate(@end_eta)
|
243
257
|
end
|
@@ -245,18 +259,37 @@ module HexaPDF
|
|
245
259
|
# Returns the point at +angle+ degrees on the ellipse.
|
246
260
|
#
|
247
261
|
# Note that the point may not lie on the arc itself!
|
262
|
+
#
|
263
|
+
# Examples:
|
264
|
+
#
|
265
|
+
# #>pdf-center
|
266
|
+
# arc = canvas.graphic_object(:arc, a: 40, b: 30, end_angle: 245)
|
267
|
+
# canvas.draw(arc).stroke
|
268
|
+
# canvas.fill_color("hp-blue").
|
269
|
+
# circle(*arc.point_at(150), 2).
|
270
|
+
# circle(*arc.point_at(290), 2).
|
271
|
+
# fill
|
248
272
|
def point_at(angle)
|
249
273
|
evaluate(angle_to_param(angle))
|
250
274
|
end
|
251
275
|
|
252
276
|
# Draws the arc on the given Canvas.
|
253
277
|
#
|
254
|
-
# If the argument +move_to_start+ is +true+, a Canvas#move_to operation is executed to
|
255
|
-
#
|
256
|
-
#
|
278
|
+
# If the argument +move_to_start+ is +true+, a Canvas#move_to operation is executed to move
|
279
|
+
# the current point to the start point of the arc. Otherwise it is assumed that the current
|
280
|
+
# point already coincides with the start point. This functionality is used, for example, by
|
281
|
+
# the SolidArc implementation.
|
257
282
|
#
|
258
283
|
# The #max_curves value, if not already changed, is set to the value of the configuration
|
259
284
|
# option 'graphic_object.arc.max_curves' before drawing.
|
285
|
+
#
|
286
|
+
# Examples:
|
287
|
+
#
|
288
|
+
# #>pdf-center
|
289
|
+
# arc = canvas.graphic_object(:arc, a: 40, b: 30)
|
290
|
+
# canvas.stroke_color("hp-blue").move_to(-50, 0)
|
291
|
+
# arc.draw(canvas, move_to_start: false)
|
292
|
+
# canvas.stroke
|
260
293
|
def draw(canvas, move_to_start: true)
|
261
294
|
@max_curves ||= canvas.context.document.config['graphic_object.arc.max_curves']
|
262
295
|
canvas.move_to(*start_point) if move_to_start
|
@@ -41,7 +41,12 @@ module HexaPDF
|
|
41
41
|
module GraphicObject
|
42
42
|
|
43
43
|
# This class describes an elliptical arc in endpoint parameterization. It allows one to
|
44
|
-
# generate an arc from the current point to a given point, similar to
|
44
|
+
# generate an arc from the current point to a given point, similar to Canvas#line_to. Behind
|
45
|
+
# the scenes the endpoint parameterization is turned into a center parameterization and drawn
|
46
|
+
# with Arc.
|
47
|
+
#
|
48
|
+
# Note that only the path of the arc itself is added to the canvas. So depending on the
|
49
|
+
# use-case the path itself still has to be, for example, stroked.
|
45
50
|
#
|
46
51
|
# This graphic object is registered under the :endpoint_arc key for use with the
|
47
52
|
# HexaPDF::Content::Canvas class.
|
@@ -52,10 +57,12 @@ module HexaPDF
|
|
52
57
|
# arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 10)
|
53
58
|
# canvas.move_to(0, 0).draw(arc).stroke
|
54
59
|
#
|
55
|
-
# See:
|
60
|
+
# See: Arc, ARC - https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes (in the
|
61
|
+
# version of about 2016, see
|
62
|
+
# https://web.archive.org/web/20160310153722/https://www.w3.org/TR/SVG/implnote.html).
|
56
63
|
class EndpointArc
|
57
64
|
|
58
|
-
EPSILON = 1e-10
|
65
|
+
EPSILON = 1e-10 # :nodoc:
|
59
66
|
|
60
67
|
include Utils::MathHelpers
|
61
68
|
|
@@ -66,80 +73,95 @@ module HexaPDF
|
|
66
73
|
new.configure(**kwargs)
|
67
74
|
end
|
68
75
|
|
69
|
-
# x-coordinate of endpoint
|
76
|
+
# x-coordinate of endpoint, defaults to 0.
|
70
77
|
#
|
71
78
|
# Examples:
|
72
79
|
#
|
73
80
|
# #>pdf-center
|
74
81
|
# arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
|
75
82
|
# canvas.move_to(0, 0).draw(arc).stroke
|
76
|
-
# canvas.stroke_color("
|
83
|
+
# canvas.stroke_color("hp-blue").move_to(0, 0).draw(arc, x: -50).stroke
|
77
84
|
attr_reader :x
|
78
85
|
|
79
|
-
# y-coordinate of endpoint
|
86
|
+
# y-coordinate of endpoint, defaults to 0.
|
80
87
|
#
|
81
88
|
# Examples:
|
82
89
|
#
|
83
90
|
# #>pdf-center
|
84
91
|
# arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
|
85
92
|
# canvas.move_to(0, 0).draw(arc).stroke
|
86
|
-
# canvas.stroke_color("
|
93
|
+
# canvas.stroke_color("hp-blue").move_to(0, 0).draw(arc, y: -20).stroke
|
87
94
|
attr_reader :y
|
88
95
|
|
89
|
-
# Length of semi-major axis
|
96
|
+
# Length of semi-major axis, defaults to 0.
|
90
97
|
#
|
91
98
|
# Examples:
|
92
99
|
#
|
93
100
|
# #>pdf-center
|
94
101
|
# arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
|
95
102
|
# canvas.move_to(0, 0).draw(arc).stroke
|
96
|
-
# canvas.stroke_color("
|
103
|
+
# canvas.stroke_color("hp-blue").move_to(0, 0).draw(arc, a: 40).stroke
|
97
104
|
attr_reader :a
|
98
105
|
|
99
|
-
# Length of semi-minor axis
|
106
|
+
# Length of semi-minor axis, defaults to 0.
|
100
107
|
#
|
101
108
|
# Examples:
|
102
109
|
#
|
103
110
|
# #>pdf-center
|
104
111
|
# arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
|
105
112
|
# canvas.move_to(0, 0).draw(arc).stroke
|
106
|
-
# canvas.stroke_color("
|
113
|
+
# canvas.stroke_color("hp-blue").move_to(0, 0).draw(arc, b: 50).stroke
|
107
114
|
attr_reader :b
|
108
115
|
|
109
|
-
# Inclination in degrees of semi-major axis in respect to x-axis
|
116
|
+
# Inclination in degrees of semi-major axis in respect to x-axis, defaults to 0.
|
110
117
|
#
|
111
118
|
# Examples:
|
112
119
|
#
|
113
120
|
# #>pdf-center
|
114
121
|
# arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
|
115
122
|
# canvas.move_to(0, 0).draw(arc).stroke
|
116
|
-
# canvas.stroke_color("
|
123
|
+
# canvas.stroke_color("hp-blue").move_to(0, 0).draw(arc, inclination: 45).stroke
|
117
124
|
attr_reader :inclination
|
118
125
|
|
119
|
-
# Large arc choice - if +true+ use the large arc (i.e. the one spanning more
|
120
|
-
# degrees), else the small arc
|
126
|
+
# Large arc choice - if +true+ (the default) use the large arc (i.e. the one spanning more
|
127
|
+
# than 180 degrees), else the small arc
|
121
128
|
#
|
122
129
|
# Examples:
|
123
130
|
#
|
124
131
|
# #>pdf-center
|
125
132
|
# arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
|
126
133
|
# canvas.move_to(0, 0).draw(arc).stroke
|
127
|
-
# canvas.stroke_color("
|
134
|
+
# canvas.stroke_color("hp-blue").
|
135
|
+
# move_to(0, 0).draw(arc, large_arc: false, clockwise: true).stroke
|
128
136
|
attr_reader :large_arc
|
129
137
|
|
130
138
|
# Direction of arc - if +true+ in clockwise direction, else in counterclockwise direction
|
139
|
+
# (the default).
|
131
140
|
#
|
132
|
-
# This is needed, for example, when filling paths using the nonzero winding number rule to
|
133
|
-
# different effects.
|
141
|
+
# This is needed, for example, when filling paths using the nonzero winding number rule to
|
142
|
+
# achieve different effects.
|
134
143
|
#
|
135
144
|
# Examples:
|
136
145
|
#
|
137
146
|
# #>pdf-center
|
138
147
|
# arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
|
139
148
|
# canvas.move_to(0, 0).draw(arc).stroke
|
140
|
-
# canvas.stroke_color("
|
149
|
+
# canvas.stroke_color("hp-blue").move_to(0, 0).draw(arc, clockwise: true).stroke
|
141
150
|
attr_reader :clockwise
|
142
151
|
|
152
|
+
# The maximal number of curves used for approximating a complete ellipse.
|
153
|
+
#
|
154
|
+
# See Arc#max_curves for details.
|
155
|
+
#
|
156
|
+
# Examples:
|
157
|
+
#
|
158
|
+
# #>pdf-center
|
159
|
+
# arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 20)
|
160
|
+
# canvas.move_to(0, 0).draw(arc, max_curves: 1).stroke
|
161
|
+
# canvas.stroke_color("hp-blue").
|
162
|
+
# move_to(0, 0).draw(arc, max_curves: 2).stroke
|
163
|
+
attr_accessor :max_curves
|
164
|
+
|
143
165
|
# Creates an endpoint arc with default values x=0, y=0, a=0, b=0, inclination=0,
|
144
166
|
# large_arc=true, clockwise=false (a line to the origin).
|
145
167
|
#
|
@@ -153,6 +175,7 @@ module HexaPDF
|
|
153
175
|
@inclination = 0
|
154
176
|
@large_arc = true
|
155
177
|
@clockwise = false
|
178
|
+
@max_curves = nil
|
156
179
|
end
|
157
180
|
|
158
181
|
# Configures the endpoint arc with
|
@@ -161,8 +184,9 @@ module HexaPDF
|
|
161
184
|
# * semi-major axis +a+,
|
162
185
|
# * semi-minor axis +b+,
|
163
186
|
# * an inclination in respect to the x-axis of +inclination+ degrees,
|
164
|
-
# * the given large_arc flag
|
165
|
-
# * the given clockwise flag.
|
187
|
+
# * the given large_arc flag,
|
188
|
+
# * the given clockwise flag and.
|
189
|
+
# * the given maximum number of approximation curves.
|
166
190
|
#
|
167
191
|
# The +large_arc+ option determines whether the large arc, i.e. the one spanning more than
|
168
192
|
# 180 degrees, is used (+true+) or the small arc (+false+).
|
@@ -174,8 +198,15 @@ module HexaPDF
|
|
174
198
|
# for the inital values.
|
175
199
|
#
|
176
200
|
# Returns self.
|
201
|
+
#
|
202
|
+
# Examples:
|
203
|
+
#
|
204
|
+
# #>pdf-center
|
205
|
+
# arc = canvas.graphic_object(:endpoint_arc)
|
206
|
+
# arc.configure(x: 50, y: 20, a: 30, b: 10)
|
207
|
+
# canvas.move_to(0, 0).draw(arc).stroke
|
177
208
|
def configure(x: nil, y: nil, a: nil, b: nil, inclination: nil, large_arc: nil,
|
178
|
-
clockwise: nil)
|
209
|
+
clockwise: nil, max_curves: nil)
|
179
210
|
@x = x if x
|
180
211
|
@y = y if y
|
181
212
|
@a = a.abs if a
|
@@ -183,11 +214,23 @@ module HexaPDF
|
|
183
214
|
@inclination = inclination % 360 if inclination
|
184
215
|
@large_arc = large_arc unless large_arc.nil?
|
185
216
|
@clockwise = clockwise unless clockwise.nil?
|
217
|
+
@max_curves = max_curves if max_curves
|
186
218
|
|
187
219
|
self
|
188
220
|
end
|
189
221
|
|
190
222
|
# Draws the arc on the given Canvas.
|
223
|
+
#
|
224
|
+
# Since this method doesn't have any other arguments than +canvas+, it is usually better and
|
225
|
+
# easier to use Canvas#draw.
|
226
|
+
#
|
227
|
+
# Examples:
|
228
|
+
#
|
229
|
+
# #>pdf-center
|
230
|
+
# arc = canvas.graphic_object(:endpoint_arc, x: 50, y: 20, a: 30, b: 10)
|
231
|
+
# canvas.move_to(-20, -20)
|
232
|
+
# arc.draw(canvas)
|
233
|
+
# canvas.stroke
|
191
234
|
def draw(canvas)
|
192
235
|
x1, y1 = *canvas.current_point
|
193
236
|
|
@@ -257,7 +300,7 @@ module HexaPDF
|
|
257
300
|
end_angle = compute_angle_to_x_axis((-x1p - cxp), (-y1p - cyp)) % 360
|
258
301
|
|
259
302
|
{cx: cx, cy: cy, a: rx, b: ry, start_angle: start_angle, end_angle: end_angle,
|
260
|
-
inclination: @inclination, clockwise: @clockwise}
|
303
|
+
inclination: @inclination, clockwise: @clockwise, max_curves: @max_curves}
|
261
304
|
end
|
262
305
|
|
263
306
|
# Compares two float numbers if they are within a certain delta.
|