hexapdf 0.32.2 → 0.33.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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +63 -1
  3. data/README.md +9 -0
  4. data/examples/002-graphics.rb +15 -17
  5. data/examples/003-arcs.rb +9 -9
  6. data/examples/009-text_layouter_alignment.rb +1 -1
  7. data/examples/010-text_layouter_inline_boxes.rb +2 -2
  8. data/examples/011-text_layouter_line_wrapping.rb +1 -1
  9. data/examples/012-text_layouter_styling.rb +7 -7
  10. data/examples/013-text_layouter_shapes.rb +1 -1
  11. data/examples/014-text_in_polygon.rb +1 -1
  12. data/examples/015-boxes.rb +8 -7
  13. data/examples/016-frame_automatic_box_placement.rb +2 -2
  14. data/examples/017-frame_text_flow.rb +2 -1
  15. data/examples/018-composer.rb +1 -1
  16. data/examples/020-column_box.rb +2 -1
  17. data/examples/025-table_box.rb +46 -0
  18. data/lib/hexapdf/cli/command.rb +5 -2
  19. data/lib/hexapdf/cli/form.rb +5 -5
  20. data/lib/hexapdf/cli/inspect.rb +3 -3
  21. data/lib/hexapdf/composer.rb +104 -52
  22. data/lib/hexapdf/configuration.rb +44 -39
  23. data/lib/hexapdf/content/canvas.rb +393 -267
  24. data/lib/hexapdf/content/color_space.rb +72 -25
  25. data/lib/hexapdf/content/graphic_object/arc.rb +57 -24
  26. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +66 -23
  27. data/lib/hexapdf/content/graphic_object/geom2d.rb +47 -6
  28. data/lib/hexapdf/content/graphic_object/solid_arc.rb +58 -36
  29. data/lib/hexapdf/content/graphic_object.rb +6 -7
  30. data/lib/hexapdf/content/graphics_state.rb +54 -45
  31. data/lib/hexapdf/content/operator.rb +52 -54
  32. data/lib/hexapdf/content/parser.rb +2 -2
  33. data/lib/hexapdf/content/processor.rb +15 -15
  34. data/lib/hexapdf/content/transformation_matrix.rb +1 -1
  35. data/lib/hexapdf/content.rb +5 -0
  36. data/lib/hexapdf/dictionary.rb +6 -5
  37. data/lib/hexapdf/dictionary_fields.rb +42 -14
  38. data/lib/hexapdf/digital_signature/cms_handler.rb +2 -2
  39. data/lib/hexapdf/digital_signature/handler.rb +1 -1
  40. data/lib/hexapdf/digital_signature/pkcs1_handler.rb +2 -3
  41. data/lib/hexapdf/digital_signature/signature.rb +6 -6
  42. data/lib/hexapdf/digital_signature/signatures.rb +13 -12
  43. data/lib/hexapdf/digital_signature/signing/default_handler.rb +14 -5
  44. data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +2 -4
  45. data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +4 -4
  46. data/lib/hexapdf/digital_signature/signing.rb +4 -0
  47. data/lib/hexapdf/digital_signature/verification_result.rb +2 -2
  48. data/lib/hexapdf/digital_signature.rb +7 -2
  49. data/lib/hexapdf/document/destinations.rb +12 -11
  50. data/lib/hexapdf/document/files.rb +1 -1
  51. data/lib/hexapdf/document/fonts.rb +1 -1
  52. data/lib/hexapdf/document/layout.rb +167 -39
  53. data/lib/hexapdf/document/pages.rb +3 -2
  54. data/lib/hexapdf/document.rb +89 -55
  55. data/lib/hexapdf/encryption/aes.rb +5 -5
  56. data/lib/hexapdf/encryption/arc4.rb +1 -1
  57. data/lib/hexapdf/encryption/fast_aes.rb +2 -2
  58. data/lib/hexapdf/encryption/fast_arc4.rb +1 -1
  59. data/lib/hexapdf/encryption/identity.rb +1 -1
  60. data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
  61. data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
  62. data/lib/hexapdf/encryption/security_handler.rb +31 -24
  63. data/lib/hexapdf/encryption/standard_security_handler.rb +45 -36
  64. data/lib/hexapdf/encryption.rb +7 -2
  65. data/lib/hexapdf/error.rb +18 -0
  66. data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
  67. data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
  68. data/lib/hexapdf/filter/flate_decode.rb +1 -1
  69. data/lib/hexapdf/filter/lzw_decode.rb +1 -1
  70. data/lib/hexapdf/filter/pass_through.rb +1 -1
  71. data/lib/hexapdf/filter/predictor.rb +1 -1
  72. data/lib/hexapdf/filter/run_length_decode.rb +1 -1
  73. data/lib/hexapdf/filter.rb +55 -6
  74. data/lib/hexapdf/font/cmap/parser.rb +2 -2
  75. data/lib/hexapdf/font/cmap.rb +1 -1
  76. data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
  77. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
  78. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +2 -2
  79. data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
  80. data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
  81. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +3 -3
  82. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
  83. data/lib/hexapdf/font/invalid_glyph.rb +3 -0
  84. data/lib/hexapdf/font/true_type_wrapper.rb +17 -4
  85. data/lib/hexapdf/font/type1_wrapper.rb +19 -4
  86. data/lib/hexapdf/font_loader/from_configuration.rb +5 -2
  87. data/lib/hexapdf/font_loader/from_file.rb +5 -5
  88. data/lib/hexapdf/font_loader/standard14.rb +3 -3
  89. data/lib/hexapdf/font_loader.rb +3 -0
  90. data/lib/hexapdf/image_loader/jpeg.rb +2 -2
  91. data/lib/hexapdf/image_loader/pdf.rb +1 -1
  92. data/lib/hexapdf/image_loader/png.rb +2 -2
  93. data/lib/hexapdf/image_loader.rb +1 -1
  94. data/lib/hexapdf/importer.rb +13 -0
  95. data/lib/hexapdf/layout/box.rb +9 -2
  96. data/lib/hexapdf/layout/box_fitter.rb +2 -2
  97. data/lib/hexapdf/layout/column_box.rb +18 -4
  98. data/lib/hexapdf/layout/frame.rb +30 -12
  99. data/lib/hexapdf/layout/image_box.rb +5 -0
  100. data/lib/hexapdf/layout/inline_box.rb +1 -0
  101. data/lib/hexapdf/layout/list_box.rb +17 -1
  102. data/lib/hexapdf/layout/page_style.rb +4 -4
  103. data/lib/hexapdf/layout/style.rb +18 -3
  104. data/lib/hexapdf/layout/table_box.rb +682 -0
  105. data/lib/hexapdf/layout/text_box.rb +5 -3
  106. data/lib/hexapdf/layout/text_fragment.rb +1 -1
  107. data/lib/hexapdf/layout/text_layouter.rb +12 -4
  108. data/lib/hexapdf/layout.rb +1 -0
  109. data/lib/hexapdf/name_tree_node.rb +1 -1
  110. data/lib/hexapdf/number_tree_node.rb +1 -1
  111. data/lib/hexapdf/object.rb +18 -7
  112. data/lib/hexapdf/parser.rb +7 -7
  113. data/lib/hexapdf/pdf_array.rb +1 -1
  114. data/lib/hexapdf/rectangle.rb +1 -1
  115. data/lib/hexapdf/reference.rb +1 -1
  116. data/lib/hexapdf/revision.rb +1 -1
  117. data/lib/hexapdf/revisions.rb +3 -3
  118. data/lib/hexapdf/serializer.rb +15 -15
  119. data/lib/hexapdf/stream.rb +4 -2
  120. data/lib/hexapdf/tokenizer.rb +14 -14
  121. data/lib/hexapdf/type/acro_form/appearance_generator.rb +22 -22
  122. data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
  123. data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
  124. data/lib/hexapdf/type/acro_form/field.rb +2 -2
  125. data/lib/hexapdf/type/acro_form/form.rb +1 -1
  126. data/lib/hexapdf/type/acro_form/signature_field.rb +4 -4
  127. data/lib/hexapdf/type/acro_form/text_field.rb +1 -1
  128. data/lib/hexapdf/type/acro_form/variable_text_field.rb +1 -1
  129. data/lib/hexapdf/type/acro_form.rb +1 -1
  130. data/lib/hexapdf/type/action.rb +1 -1
  131. data/lib/hexapdf/type/actions/go_to.rb +1 -1
  132. data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
  133. data/lib/hexapdf/type/actions/launch.rb +1 -1
  134. data/lib/hexapdf/type/actions/uri.rb +1 -1
  135. data/lib/hexapdf/type/actions.rb +1 -1
  136. data/lib/hexapdf/type/annotation.rb +3 -3
  137. data/lib/hexapdf/type/annotations/link.rb +1 -1
  138. data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
  139. data/lib/hexapdf/type/annotations/text.rb +1 -1
  140. data/lib/hexapdf/type/annotations/widget.rb +2 -2
  141. data/lib/hexapdf/type/annotations.rb +1 -1
  142. data/lib/hexapdf/type/catalog.rb +1 -1
  143. data/lib/hexapdf/type/cid_font.rb +3 -3
  144. data/lib/hexapdf/type/embedded_file.rb +1 -1
  145. data/lib/hexapdf/type/file_specification.rb +2 -2
  146. data/lib/hexapdf/type/font_descriptor.rb +1 -1
  147. data/lib/hexapdf/type/font_simple.rb +2 -2
  148. data/lib/hexapdf/type/font_type0.rb +3 -3
  149. data/lib/hexapdf/type/font_type3.rb +1 -1
  150. data/lib/hexapdf/type/form.rb +1 -1
  151. data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
  152. data/lib/hexapdf/type/icon_fit.rb +1 -1
  153. data/lib/hexapdf/type/image.rb +1 -1
  154. data/lib/hexapdf/type/info.rb +1 -1
  155. data/lib/hexapdf/type/mark_information.rb +1 -1
  156. data/lib/hexapdf/type/names.rb +2 -2
  157. data/lib/hexapdf/type/object_stream.rb +2 -1
  158. data/lib/hexapdf/type/outline.rb +1 -1
  159. data/lib/hexapdf/type/outline_item.rb +1 -1
  160. data/lib/hexapdf/type/page.rb +19 -10
  161. data/lib/hexapdf/type/page_label.rb +1 -1
  162. data/lib/hexapdf/type/page_tree_node.rb +1 -1
  163. data/lib/hexapdf/type/resources.rb +1 -1
  164. data/lib/hexapdf/type/trailer.rb +2 -2
  165. data/lib/hexapdf/type/viewer_preferences.rb +1 -1
  166. data/lib/hexapdf/type/xref_stream.rb +2 -2
  167. data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
  168. data/lib/hexapdf/version.rb +1 -1
  169. data/lib/hexapdf/writer.rb +4 -4
  170. data/lib/hexapdf/xref_section.rb +2 -2
  171. data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +11 -1
  172. data/test/hexapdf/content/graphic_object/test_geom2d.rb +7 -0
  173. data/test/hexapdf/content/test_canvas.rb +0 -1
  174. data/test/hexapdf/digital_signature/test_signatures.rb +22 -0
  175. data/test/hexapdf/document/test_files.rb +2 -2
  176. data/test/hexapdf/document/test_layout.rb +98 -0
  177. data/test/hexapdf/encryption/test_security_handler.rb +12 -11
  178. data/test/hexapdf/encryption/test_standard_security_handler.rb +35 -23
  179. data/test/hexapdf/font/test_true_type_wrapper.rb +18 -1
  180. data/test/hexapdf/font/test_type1_wrapper.rb +15 -1
  181. data/test/hexapdf/layout/test_box.rb +1 -1
  182. data/test/hexapdf/layout/test_column_box.rb +65 -21
  183. data/test/hexapdf/layout/test_frame.rb +14 -14
  184. data/test/hexapdf/layout/test_image_box.rb +4 -0
  185. data/test/hexapdf/layout/test_inline_box.rb +5 -0
  186. data/test/hexapdf/layout/test_list_box.rb +40 -6
  187. data/test/hexapdf/layout/test_page_style.rb +3 -2
  188. data/test/hexapdf/layout/test_style.rb +50 -0
  189. data/test/hexapdf/layout/test_table_box.rb +722 -0
  190. data/test/hexapdf/layout/test_text_box.rb +18 -0
  191. data/test/hexapdf/layout/test_text_layouter.rb +4 -0
  192. data/test/hexapdf/test_dictionary_fields.rb +4 -1
  193. data/test/hexapdf/test_document.rb +1 -0
  194. data/test/hexapdf/test_filter.rb +8 -0
  195. data/test/hexapdf/test_importer.rb +9 -0
  196. data/test/hexapdf/test_object.rb +16 -5
  197. data/test/hexapdf/test_stream.rb +7 -0
  198. data/test/hexapdf/test_writer.rb +3 -3
  199. data/test/hexapdf/type/acro_form/test_appearance_generator.rb +13 -5
  200. data/test/hexapdf/type/acro_form/test_form.rb +4 -3
  201. data/test/hexapdf/type/test_page.rb +18 -4
  202. metadata +17 -8
@@ -43,6 +43,22 @@ module HexaPDF
43
43
 
44
44
  # This class provides support for drawing Geom2D objects like line segments and polygons.
45
45
  #
46
+ # By default, the paths for the objects are not only added to the canvas but are also stroked
47
+ # or filled (depending on the specific Geom2D object).
48
+ #
49
+ # Supported Geom2D objects are:
50
+ #
51
+ # * Geom2D::Point
52
+ # * Geom2D::Segment
53
+ # * Geom2D::Polygon
54
+ # * Geom2D::PolygonSet
55
+ #
56
+ # Examples:
57
+ #
58
+ # #>pdf-center
59
+ # canvas.draw(:geom2d, object: ::Geom2D::Point(-10, 10))
60
+ # canvas.draw(:geom2d, object: ::Geom2D::Polygon([10, 10], [30, 20], [0, 50]))
61
+ #
46
62
  # See: Geom2D - https://github.com/gettalong/geom2d
47
63
  class Geom2D
48
64
 
@@ -53,10 +69,12 @@ module HexaPDF
53
69
  new.configure(**kwargs)
54
70
  end
55
71
 
56
- # The Geom2D object that should be drawn
72
+ # The Geom2D object that should be drawn.
73
+ #
74
+ # This attribute *must* be set before drawing.
57
75
  attr_accessor :object
58
76
 
59
- # The radius to use when drawing Geom2D::Point objects; defaults to 1
77
+ # The radius to use when drawing Geom2D::Point objects, defaults to 1.
60
78
  #
61
79
  # Examples:
62
80
  #
@@ -66,7 +84,7 @@ module HexaPDF
66
84
  attr_accessor :point_radius
67
85
 
68
86
  # Specifies whether only paths should be drawn or if they should be stroked/filled too
69
- # (default).
87
+ # (the default).
70
88
  #
71
89
  # Examples:
72
90
  #
@@ -76,6 +94,8 @@ module HexaPDF
76
94
  attr_accessor :path_only
77
95
 
78
96
  # Creates a Geom2D drawing support object.
97
+ #
98
+ # A call to #configure is mandatory afterwards to set the #object to be drawn.
79
99
  def initialize
80
100
  @object = nil
81
101
  @point_radius = 1
@@ -84,7 +104,8 @@ module HexaPDF
84
104
 
85
105
  # Configures the Geom2D drawing support object. The following arguments are allowed:
86
106
  #
87
- # :object:: The object that should be drawn.
107
+ # :object:: The object that should be drawn. If this argument has not been set before and is
108
+ # also not given, an error will be raised when calling #draw.
88
109
  # :point_radius:: The radius of the points when drawing points.
89
110
  # :path_only:: Whether only the path should be drawn.
90
111
  #
@@ -92,18 +113,33 @@ module HexaPDF
92
113
  # methods for the inital values.
93
114
  #
94
115
  # Returns self.
95
- def configure(object:, point_radius: nil, path_only: nil)
96
- @object = object
116
+ #
117
+ # Examples:
118
+ #
119
+ # #>pdf-center
120
+ # obj = canvas.graphic_object(:geom2d, object: ::Geom2D::Point(0, 0))
121
+ # canvas.draw(obj)
122
+ # canvas.opacity(fill_alpha: 0.5).fill_color("hp-blue").
123
+ # draw(obj, point_radius: 10)
124
+ def configure(object: nil, point_radius: nil, path_only: nil)
125
+ @object = object if object
97
126
  @point_radius = point_radius if point_radius
98
127
  @path_only = path_only if path_only
99
128
  self
100
129
  end
101
130
 
102
131
  # Draws the Geom2D object onto the given Canvas.
132
+ #
133
+ # Examples:
134
+ #
135
+ # #>pdf-center
136
+ # obj = canvas.graphic_object(:geom2d, object: ::Geom2D::Point(0, 0))
137
+ # obj.draw(canvas)
103
138
  def draw(canvas)
104
139
  case @object
105
140
  when ::Geom2D::Point then draw_point(canvas)
106
141
  when ::Geom2D::Segment then draw_segment(canvas)
142
+ when ::Geom2D::Rectangle then draw_rectangle(canvas)
107
143
  when ::Geom2D::Polygon then draw_polygon(canvas)
108
144
  when ::Geom2D::PolygonSet then draw_polygon_set(canvas)
109
145
  else
@@ -124,6 +160,11 @@ module HexaPDF
124
160
  canvas.stroke unless @path_only
125
161
  end
126
162
 
163
+ def draw_rectangle(canvas)
164
+ canvas.rectangle(@object.x, @object.y, @object.width, @object.height)
165
+ canvas.stroke unless @path_only
166
+ end
167
+
127
168
  def draw_polygon(canvas)
128
169
  return unless @object.nr_of_vertices > 1
129
170
  canvas.move_to(@object[0].x, @object[0].y)
@@ -41,41 +41,43 @@ 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
+ # Note that only the path itself is added to the canvas. So depending on the use-case the path
45
+ # itself still has to be, for example, stroked.
46
+ #
44
47
  # This graphic object is registered under the :solid_arc key for use with the
45
48
  # HexaPDF::Content::Canvas class.
46
49
  #
47
- # Thus it can be used to create
50
+ # It can be used to create
48
51
  #
49
52
  # * an (*elliptical*) *disk* (when the inner a/b are zero and the difference between start and
50
53
  # end angles is greater than or equal to 360),
51
54
  #
52
55
  # #>pdf-center
53
- # canvas.fill_color("red").
54
- # draw(:solid_arc, outer_a: 80, outer_b: 50, end_angle: 360).
56
+ # canvas.fill_color("hp-blue").
57
+ # draw(:solid_arc, outer_a: 80, outer_b: 50).
55
58
  # fill_stroke
56
59
  #
57
60
  # * an (*elliptical*) *sector* (when the inner a/b are zero and the difference between start
58
61
  # and end angles is less than 360),
59
62
  #
60
63
  # #>pdf-center
61
- # canvas.fill_color("red").
64
+ # canvas.fill_color("hp-blue").
62
65
  # draw(:solid_arc, outer_a: 80, outer_b: 50, start_angle: 20, end_angle: 230).
63
66
  # fill_stroke
64
67
  #
65
68
  # * an (*elliptical*) *annulus* (when the inner a/b are nonzero and the difference between
66
- # start and end angles is greater than or equal to 360), and
69
+ # start and end angles is greater than or equal to 360),
67
70
  #
68
71
  # #>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
+ # canvas.fill_color("hp-blue").
73
+ # draw(:solid_arc, outer_a: 80, outer_b: 50, inner_a: 70, inner_b: 30).
72
74
  # fill_stroke
73
75
  #
74
- # * an (*elliptical*) *annular sector* (when the inner a/b are nonzero and the difference
76
+ # * and an (*elliptical*) *annular sector* (when the inner a/b are nonzero and the difference
75
77
  # between start and end angles is less than 360)
76
78
  #
77
79
  # #>pdf-center
78
- # canvas.fill_color("red").
80
+ # canvas.fill_color("hp-blue").
79
81
  # draw(:solid_arc, outer_a: 80, outer_b: 50, inner_a: 70, inner_b: 30,
80
82
  # start_angle: 20, end_angle: 230).
81
83
  # fill_stroke
@@ -90,7 +92,7 @@ module HexaPDF
90
92
  new.configure(**kwargs)
91
93
  end
92
94
 
93
- # x-coordinate of center point
95
+ # x-coordinate of center point, defaults to 0.
94
96
  #
95
97
  # Examples:
96
98
  #
@@ -98,10 +100,10 @@ module HexaPDF
98
100
  # solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
99
101
  # inner_a: 20, inner_b: 10)
100
102
  # canvas.draw(solid_arc).stroke
101
- # canvas.stroke_color("red").draw(solid_arc, cx: 50).stroke
103
+ # canvas.stroke_color("hp-blue").draw(solid_arc, cx: 50).stroke
102
104
  attr_reader :cx
103
105
 
104
- # y-coordinate of center point
106
+ # y-coordinate of center point, defaults to 0.
105
107
  #
106
108
  # Examples:
107
109
  #
@@ -109,91 +111,96 @@ module HexaPDF
109
111
  # solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
110
112
  # inner_a: 20, inner_b: 10)
111
113
  # canvas.draw(solid_arc).stroke
112
- # canvas.stroke_color("red").draw(solid_arc, cy: 50).stroke
114
+ # canvas.stroke_color("hp-blue").draw(solid_arc, cy: 50).stroke
113
115
  attr_reader :cy
114
116
 
115
117
  # Length of inner semi-major axis which (without altering the #inclination) is parallel to
116
- # the x-axis
118
+ # the x-axis, defaults to 0.
117
119
  #
118
120
  # Examples:
119
121
  #
120
122
  # #>pdf-center
121
- # solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
123
+ # solid_arc = canvas.graphic_object(:solid_arc, cx: -50, outer_a: 30, outer_b: 20,
122
124
  # inner_a: 20, inner_b: 10)
123
125
  # canvas.draw(solid_arc).stroke
124
- # canvas.stroke_color("red").draw(solid_arc, inner_a: 5).stroke
126
+ # canvas.stroke_color("hp-blue").draw(solid_arc, cx: 50, inner_a: 5).stroke
125
127
  attr_reader :inner_a
126
128
 
127
- # Length of inner semi-minor axis which (without altering the #inclination) is parallel to the
128
- # y-axis
129
+ # Length of inner semi-minor axis which (without altering the #inclination) is parallel to
130
+ # the y-axis, defaults to 0.
129
131
  #
130
132
  # Examples:
131
133
  #
132
134
  # #>pdf-center
133
- # solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
135
+ # solid_arc = canvas.graphic_object(:solid_arc, cx: -50, outer_a: 30, outer_b: 20,
134
136
  # inner_a: 20, inner_b: 10)
135
137
  # canvas.draw(solid_arc).stroke
136
- # canvas.stroke_color("red").draw(solid_arc, inner_b: 20).stroke
138
+ # canvas.stroke_color("hp-blue").draw(solid_arc, cx: 50, inner_b: 20).stroke
137
139
  attr_reader :inner_b
138
140
 
139
141
  # Length of outer semi-major axis which (without altering the #inclination) is parallel to
140
- # the x-axis
142
+ # the x-axis, defaults to 1.
141
143
  #
142
144
  # Examples:
143
145
  #
144
146
  # #>pdf-center
145
- # solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
147
+ # solid_arc = canvas.graphic_object(:solid_arc, cx: -50, outer_a: 30, outer_b: 20,
146
148
  # inner_a: 20, inner_b: 10)
147
149
  # canvas.draw(solid_arc).stroke
148
- # canvas.stroke_color("red").draw(solid_arc, outer_a: 45).stroke
150
+ # canvas.stroke_color("hp-blue").draw(solid_arc, cx: 50, outer_a: 45).stroke
149
151
  attr_reader :outer_a
150
152
 
151
153
  # Length of outer semi-minor axis which (without altering the #inclination) is parallel to the
152
- # y-axis
154
+ # y-axis, defaults to 1.
153
155
  #
154
156
  # Examples:
155
157
  #
156
158
  # #>pdf-center
157
- # solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
159
+ # solid_arc = canvas.graphic_object(:solid_arc, cx: -50, outer_a: 30, outer_b: 20,
158
160
  # inner_a: 20, inner_b: 10)
159
161
  # canvas.draw(solid_arc).stroke
160
- # canvas.stroke_color("red").draw(solid_arc, outer_b: 40).stroke
162
+ # canvas.stroke_color("hp-blue").draw(solid_arc, cx: 50, outer_b: 40).stroke
161
163
  attr_reader :outer_b
162
164
 
163
- # Start angle of the solid arc in degrees
165
+ # Start angle of the solid arc in degrees, defaults to 0.
164
166
  #
165
167
  # Examples:
166
168
  #
167
169
  # #>pdf-center
168
- # solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
170
+ # solid_arc = canvas.graphic_object(:solid_arc, cx: -50, outer_a: 30, outer_b: 20,
169
171
  # inner_a: 20, inner_b: 10)
170
172
  # canvas.draw(solid_arc).stroke
171
- # canvas.stroke_color("red").draw(solid_arc, start_angle: 60).stroke
173
+ # canvas.stroke_color("hp-blue").draw(solid_arc, cx: 50, start_angle: 60).stroke
172
174
  attr_reader :start_angle
173
175
 
174
- # End angle of the solid arc in degrees
176
+ # End angle of the solid arc in degrees, defaults to 0.
175
177
  #
176
178
  # Examples:
177
179
  #
178
180
  # #>pdf-center
179
- # solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
181
+ # solid_arc = canvas.graphic_object(:solid_arc, cx: -50, outer_a: 30, outer_b: 20,
180
182
  # inner_a: 20, inner_b: 10)
181
183
  # canvas.draw(solid_arc).stroke
182
- # canvas.stroke_color("red").draw(solid_arc, end_angle: 120).stroke
184
+ # canvas.stroke_color("hp-blue").draw(solid_arc, cx: 50, end_angle: 120).stroke
183
185
  attr_reader :end_angle
184
186
 
185
- # Inclination in degrees of semi-major axis in respect to x-axis
187
+ # Inclination in degrees of semi-major axis in respect to x-axis, defaults to 0.
186
188
  #
187
189
  # Examples:
188
190
  #
189
191
  # #>pdf-center
190
- # solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
192
+ # solid_arc = canvas.graphic_object(:solid_arc, cx: -50, outer_a: 30, outer_b: 20,
191
193
  # inner_a: 20, inner_b: 10)
192
194
  # canvas.draw(solid_arc).stroke
193
- # canvas.stroke_color("red").draw(solid_arc, inclination: 40).stroke
195
+ # canvas.stroke_color("hp-blue").draw(solid_arc, cx: 50, inclination: 40).stroke
194
196
  attr_reader :inclination
195
197
 
196
198
  # Creates a solid arc with default values (a unit disk at the origin).
199
+ #
200
+ # Examples:
201
+ #
202
+ # #>pdf-center
203
+ # canvas.draw(:solid_arc).stroke
197
204
  def initialize
198
205
  @cx = @cy = 0
199
206
  @inner_a = @inner_b = 0
@@ -218,6 +225,13 @@ module HexaPDF
218
225
  # for the inital values.
219
226
  #
220
227
  # Returns self.
228
+ #
229
+ # Examples:
230
+ #
231
+ # #>pdf-center
232
+ # solid_arc = canvas.graphic_object(:solid_arc)
233
+ # solid_arc.configure(outer_a: 30, outer_b: 20, inner_a: 20, inner_b: 10)
234
+ # canvas.draw(solid_arc).stroke
221
235
  def configure(cx: nil, cy: nil, inner_a: nil, inner_b: nil, outer_a: nil, outer_b: nil,
222
236
  start_angle: nil, end_angle: nil, inclination: nil)
223
237
  @cx = cx if cx
@@ -234,6 +248,14 @@ module HexaPDF
234
248
  end
235
249
 
236
250
  # Draws the solid arc on the given Canvas.
251
+ #
252
+ # Examples:
253
+ #
254
+ # #>pdf-center
255
+ # solid_arc = canvas.graphic_object(:solid_arc, outer_a: 30, outer_b: 20,
256
+ # inner_a: 20, inner_b: 10)
257
+ # solid_arc.draw(canvas)
258
+ # canvas.stroke
237
259
  def draw(canvas)
238
260
  angle_difference = (@end_angle - @start_angle).abs
239
261
  if @inner_a == 0 && @inner_b == 0
@@ -49,16 +49,15 @@ module HexaPDF
49
49
  # A graphic object should only use the path creation methods or other graphic objects when it
50
50
  # is drawn. Stroking and filling, or optionally clipping, is left to the user.
51
51
  #
52
- # The Content::Canvas class provides a Content::Canvas#draw method that can be used to draw
53
- # complex graphic objects as well as a Content::Canvas#graphic_object method to retrieve an
54
- # instance of a graphic object for custom use. The latter method uses graphic object factories
55
- # that can be registered via a name using the document specific 'graphic_object.map'
56
- # configuration option.
52
+ # The Canvas class provides a Canvas#draw method that can be used to draw complex graphic
53
+ # objects as well as a Canvas#graphic_object method to retrieve an instance of a graphic object
54
+ # for custom use. The latter method uses graphic object factories that can be registered via a
55
+ # name using the document specific 'graphic_object.map' configuration option.
57
56
  #
58
57
  # == Implementation of a Graphic Object
59
58
  #
60
- # Graphic objects are normally implemented as classes since this automatically allows using
61
- # the class itself as the graphic object's factory.
59
+ # Graphic objects are usually implemented as classes since this automatically allows using the
60
+ # class itself as the graphic object's factory.
62
61
  #
63
62
  # A graphic object factory is an object that responds to #configure(**kwargs) and returns a
64
63
  # configured graphic object. When the factory is implemented as a class, the #configure method
@@ -43,6 +43,8 @@ module HexaPDF
43
43
  module Content
44
44
 
45
45
  # Associates a name with a value, used by various graphics state parameters.
46
+ #
47
+ # See LineCapStyle, LineJoinStyle, TextRenderingMode
46
48
  class NamedValue
47
49
 
48
50
  # The value itself.
@@ -73,12 +75,12 @@ module HexaPDF
73
75
  end
74
76
 
75
77
  # Defines all available line cap styles as constants. Each line cap style is an instance of
76
- # NamedValue, see ::normalize. For use with e.g. Content::Canvas#line_cap_style.
78
+ # NamedValue, see ::normalize. For use with e.g. Canvas#line_cap_style.
77
79
  #
78
- # See: PDF1.7 s8.4.3.3
80
+ # See: PDF2.0 s8.4.3.3
79
81
  module LineCapStyle
80
82
 
81
- # Returns the argument normalized to a valid line cap style.
83
+ # Returns the argument normalized to a valid line cap style, i.e. a NamedValue instance.
82
84
  #
83
85
  # * 0 or +:butt+ can be used for the BUTT_CAP style.
84
86
  # * 1 or +:round+ can be used for the ROUND_CAP style.
@@ -96,7 +98,7 @@ module HexaPDF
96
98
 
97
99
  # Stroke is squared off at the endpoint of a path.
98
100
  #
99
- # Specify as 0 or :butt.
101
+ # Specify as 0 or +:butt+.
100
102
  #
101
103
  # #>pdf-small-hide
102
104
  # canvas.line_cap_style(:butt)
@@ -106,7 +108,7 @@ module HexaPDF
106
108
 
107
109
  # A semicircular arc is drawn at the endpoint of a path.
108
110
  #
109
- # Specify as 1 or :round.
111
+ # Specify as 1 or +:round+.
110
112
  #
111
113
  # #>pdf-small-hide
112
114
  # canvas.line_cap_style(:round)
@@ -116,7 +118,7 @@ module HexaPDF
116
118
 
117
119
  # The stroke continues half the line width beyond the endpoint of a path.
118
120
  #
119
- # Specify as 2 or :projecting_square.
121
+ # Specify as 2 or +:projecting_square+.
120
122
  #
121
123
  # #>pdf-small-hide
122
124
  # canvas.line_cap_style(:projecting_square)
@@ -127,12 +129,12 @@ module HexaPDF
127
129
  end
128
130
 
129
131
  # Defines all available line join styles as constants. Each line join style is an instance of
130
- # NamedValue, see ::normalize For use with e.g. Content::Canvas#line_join_style.
132
+ # NamedValue, see ::normalize For use with e.g. Canvas#line_join_style.
131
133
  #
132
- # See: PDF1.7 s8.4.3.4
134
+ # See: PDF2.0 s8.4.3.4
133
135
  module LineJoinStyle
134
136
 
135
- # Returns the argument normalized to a valid line join style.
137
+ # Returns the argument normalized to a valid line join style, i.e. a NamedValue instance.
136
138
  #
137
139
  # * 0 or +:miter+ can be used for the MITER_JOIN style.
138
140
  # * 1 or +:round+ can be used for the ROUND_JOIN style.
@@ -150,7 +152,7 @@ module HexaPDF
150
152
 
151
153
  # The outer lines of the two segments continue until they meet at an angle.
152
154
  #
153
- # Specify as 0 or :miter.
155
+ # Specify as 0 or +:miter+.
154
156
  #
155
157
  # #>pdf-small-hide
156
158
  # canvas.line_join_style(:miter)
@@ -162,7 +164,7 @@ module HexaPDF
162
164
 
163
165
  # An arc of a circle is drawn around the point where the segments meet.
164
166
  #
165
- # Specify as 1 or :round.
167
+ # Specify as 1 or +:round+.
166
168
  #
167
169
  # #>pdf-small-hide
168
170
  # canvas.line_join_style(:round)
@@ -175,7 +177,7 @@ module HexaPDF
175
177
  # The two segments are finished with butt caps and the space between the ends is filled with a
176
178
  # triangle.
177
179
  #
178
- # Specify as 2 or :bevel.
180
+ # Specify as 2 or +:bevel+.
179
181
  #
180
182
  # #>pdf-small-hide
181
183
  # canvas.line_join_style(:bevel)
@@ -188,7 +190,7 @@ module HexaPDF
188
190
  end
189
191
 
190
192
  # The line dash pattern defines how a line should be dashed. For use with e.g.
191
- # Content::Canvas#line_dash_pattern.
193
+ # Canvas#line_dash_pattern.
192
194
  #
193
195
  # A dash pattern consists of two parts: the dash array and the dash phase. The dash array
194
196
  # defines the length of alternating dashes and gaps (important: starting with dashes). And the
@@ -204,7 +206,17 @@ module HexaPDF
204
206
  # [3 5] 6 2 unit gap, 3 unit dash, 5 unit gap, 3 unit dash, ...
205
207
  # [2 3] 6 1 unit dash, 3 unit gap, 2 unit dash, 3 unit gap, ...
206
208
  #
207
- # See: PDF1.7 s8.4.3.6
209
+ # And visualized it looks like this:
210
+ #
211
+ # #>pdf-canvas-hide
212
+ # canvas.line_width(2)
213
+ # [[[], 0], [[3], 0], [[3], 1], [[2, 1], 0],
214
+ # [[3, 5], 6], [[2, 3], 6]].each_with_index do |(arr, phase), index|
215
+ # canvas.line_dash_pattern(arr, phase)
216
+ # canvas.line(20, 180 - index * 30, 180, 180 - index * 30).stroke
217
+ # end
218
+ #
219
+ # See: PDF2.0 s8.4.3.6
208
220
  class LineDashPattern
209
221
 
210
222
  # :call-seq:
@@ -261,9 +273,9 @@ module HexaPDF
261
273
  end
262
274
 
263
275
  # Defines all available rendering intents as constants. For use with e.g.
264
- # Content::Canvas#rendering_intent.
276
+ # Canvas#rendering_intent.
265
277
  #
266
- # See: PDF1.7 s8.6.5.8
278
+ # See: PDF2.0 s8.6.5.8
267
279
  module RenderingIntent
268
280
 
269
281
  # Returns the argument normalized to a valid rendering intent.
@@ -295,12 +307,12 @@ module HexaPDF
295
307
  end
296
308
 
297
309
  # Defines all available text rendering modes as constants. Each text rendering mode is an
298
- # instance of NamedValue. For use with e.g. Content::Canvas#text_rendering_mode.
310
+ # instance of NamedValue. For use with e.g. Canvas#text_rendering_mode.
299
311
  #
300
- # See: PDF1.7 s9.3.6
312
+ # See: PDF2.0 s9.3.6
301
313
  module TextRenderingMode
302
314
 
303
- # Returns the argument normalized to a valid text rendering mode.
315
+ # Returns the argument normalized to a valid text rendering mode, i.e. a NamedValue instance.
304
316
  #
305
317
  # * 0 or +:fill+ can be used for the FILL mode.
306
318
  # * 1 or +:stroke+ can be used for the STROKE mode.
@@ -328,95 +340,92 @@ module HexaPDF
328
340
 
329
341
  # Fill text.
330
342
  #
331
- # Specify as 0 or :fill.
343
+ # Specify as 0 or +:fill+.
332
344
  #
333
345
  # #>pdf-small-hide
334
346
  # canvas.font("Helvetica", size: 13)
335
- # canvas.stroke_color("green").line_width(0.5)
336
347
  # canvas.text_rendering_mode(:fill)
337
348
  # canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
338
349
  FILL = NamedValue.new(:fill, 0)
339
350
 
340
351
  # Stroke text.
341
352
  #
342
- # Specify as 1 or :stroke.
353
+ # Specify as 1 or +:stroke+.
343
354
  #
344
355
  # #>pdf-small-hide
345
356
  # canvas.font("Helvetica", size: 13)
346
- # canvas.stroke_color("green").line_width(0.5)
357
+ # canvas.stroke_color("hp-blue").line_width(0.5)
347
358
  # canvas.text_rendering_mode(:stroke)
348
359
  # canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
349
360
  STROKE = NamedValue.new(:stroke, 1)
350
361
 
351
362
  # Fill, then stroke text.
352
363
  #
353
- # Specify as 2 or :fill_stroke.
364
+ # Specify as 2 or +:fill_stroke+.
354
365
  #
355
366
  # #>pdf-small-hide
356
367
  # canvas.font("Helvetica", size: 13)
357
- # canvas.stroke_color("green").line_width(0.5)
368
+ # canvas.stroke_color("hp-blue").line_width(0.5)
358
369
  # canvas.text_rendering_mode(:fill_stroke)
359
370
  # canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
360
371
  FILL_STROKE = NamedValue.new(:fill_stroke, 2)
361
372
 
362
373
  # Neither fill nor stroke text (invisible).
363
374
  #
364
- # Specify as 3 or :invisible.
375
+ # Specify as 3 or +:invisible+.
365
376
  #
366
377
  # #>pdf-small-hide
367
378
  # canvas.font("Helvetica", size: 13)
368
- # canvas.stroke_color("green").line_width(0.5)
369
379
  # canvas.text_rendering_mode(:invisible)
370
380
  # canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
371
- # canvas.stroke_color("red").line_width(20).line(30, 20, 30, 80).stroke
381
+ # canvas.stroke_color("hp-blue").line_width(20).line(30, 20, 30, 80).stroke
372
382
  INVISIBLE = NamedValue.new(:invisible, 3)
373
383
 
374
384
  # Fill text and add to path for clipping.
375
385
  #
376
- # Specify as 4 or :fill_clip.
386
+ # Specify as 4 or +:fill_clip+.
377
387
  #
378
388
  # #>pdf-small-hide
379
389
  # canvas.font("Helvetica", size: 13)
380
- # canvas.stroke_color("green").line_width(0.5)
381
390
  # canvas.text_rendering_mode(:fill_clip)
382
391
  # canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
383
- # canvas.stroke_color("red").line_width(20).line(30, 20, 30, 80).stroke
392
+ # canvas.stroke_color("hp-orange").line_width(20).line(30, 20, 30, 80).stroke
384
393
  FILL_CLIP = NamedValue.new(:fill_clip, 4)
385
394
 
386
395
  # Stroke text and add to path for clipping.
387
396
  #
388
- # Specify as 5 or :stroke_clip.
397
+ # Specify as 5 or +:stroke_clip+.
389
398
  #
390
399
  # #>pdf-small-hide
391
400
  # canvas.font("Helvetica", size: 13)
392
- # canvas.stroke_color("green").line_width(0.5)
401
+ # canvas.stroke_color("hp-blue").line_width(0.5)
393
402
  # canvas.text_rendering_mode(:stroke_clip)
394
403
  # canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
395
- # canvas.stroke_color("red").line_width(20).line(30, 20, 30, 80).stroke
404
+ # canvas.stroke_color("hp-orange").line_width(20).line(30, 20, 30, 80).stroke
396
405
  STROKE_CLIP = NamedValue.new(:stroke_clip, 5)
397
406
 
398
407
  # Fill, then stroke text and add to path for clipping.
399
408
  #
400
- # Specify as 6 or :fill_stroke_clip.
409
+ # Specify as 6 or +:fill_stroke_clip+.
401
410
  #
402
411
  # #>pdf-small-hide
403
412
  # canvas.font("Helvetica", size: 13)
404
- # canvas.stroke_color("green").line_width(0.5)
413
+ # canvas.stroke_color("hp-blue").line_width(0.5)
405
414
  # canvas.text_rendering_mode(:fill_stroke_clip)
406
415
  # canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
407
- # canvas.stroke_color("red").line_width(20).line(30, 20, 30, 80).stroke
416
+ # canvas.stroke_color("hp-orange").line_width(20).line(30, 20, 30, 80).stroke
408
417
  FILL_STROKE_CLIP = NamedValue.new(:fill_stroke_clip, 6)
409
418
 
410
419
  # Add text to path for clipping.
411
420
  #
412
- # Specify as 7 or :clip.
421
+ # Specify as 7 or +:clip+.
413
422
  #
414
423
  # #>pdf-small-hide
415
424
  # canvas.font("Helvetica", size: 13)
416
- # canvas.stroke_color("green").line_width(0.5)
425
+ # canvas.stroke_color("hp-blue").line_width(0.5)
417
426
  # canvas.text_rendering_mode(:clip)
418
427
  # canvas.text("#{canvas.text_rendering_mode.name}", at: [10, 50])
419
- # canvas.stroke_color("red").line_width(20).line(30, 20, 30, 80).stroke
428
+ # canvas.stroke_color("hp-orange").line_width(20).line(30, 20, 30, 80).stroke
420
429
  CLIP = NamedValue.new(:clip, 7)
421
430
 
422
431
  end
@@ -429,7 +438,7 @@ module HexaPDF
429
438
  #
430
439
  # The device-dependent graphics state parameters have not been implemented!
431
440
  #
432
- # See: PDF1.7 s8.4.1
441
+ # See: PDF2.0 s8.4.1
433
442
  class GraphicsState
434
443
 
435
444
  # The current transformation matrix.
@@ -540,14 +549,14 @@ module HexaPDF
540
549
  #
541
550
  # This returns the character spacing multiplied by #scaled_horizontal_scaling.
542
551
  #
543
- # See PDF1.7 s9.4.4
552
+ # See PDF2.0 s9.4.4
544
553
  attr_reader :scaled_character_spacing
545
554
 
546
555
  # The scaled word spacing used in glyph displacement calculations.
547
556
  #
548
557
  # This returns the word spacing multiplied by #scaled_horizontal_scaling.
549
558
  #
550
- # See PDF1.7 s9.4.4
559
+ # See PDF2.0 s9.4.4
551
560
  attr_reader :scaled_word_spacing
552
561
 
553
562
  # The scaled font size used in glyph displacement calculations.
@@ -556,7 +565,7 @@ module HexaPDF
556
565
  # (0.001 for all fonts except Type3 fonts or the scaling specified in /FontMatrix for Type3
557
566
  # fonts) and multiplied by #scaled_horizontal_scaling.
558
567
  #
559
- # See PDF1.7 s9.4.4, HexaPDF::Type::FontType3
568
+ # See PDF2.0 s9.4.4, HexaPDF::Type::FontType3
560
569
  attr_reader :scaled_font_size
561
570
 
562
571
  # The scaled horizontal scaling used in glyph displacement calculations.
@@ -564,7 +573,7 @@ module HexaPDF
564
573
  # Since the horizontal scaling attribute is stored in percent of 100, this method returns the
565
574
  # correct value for calculations.
566
575
  #
567
- # See PDF1.7 s9.4.4
576
+ # See PDF2.0 s9.4.4
568
577
  attr_reader :scaled_horizontal_scaling
569
578
 
570
579
  # Initializes the graphics state parameters to their default values.