hexapdf 0.32.1 → 0.33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (205) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +76 -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/cli.rb +4 -0
  22. data/lib/hexapdf/composer.rb +104 -52
  23. data/lib/hexapdf/configuration.rb +44 -39
  24. data/lib/hexapdf/content/canvas.rb +393 -267
  25. data/lib/hexapdf/content/color_space.rb +72 -25
  26. data/lib/hexapdf/content/graphic_object/arc.rb +57 -24
  27. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +66 -23
  28. data/lib/hexapdf/content/graphic_object/geom2d.rb +47 -6
  29. data/lib/hexapdf/content/graphic_object/solid_arc.rb +58 -36
  30. data/lib/hexapdf/content/graphic_object.rb +6 -7
  31. data/lib/hexapdf/content/graphics_state.rb +54 -45
  32. data/lib/hexapdf/content/operator.rb +52 -54
  33. data/lib/hexapdf/content/parser.rb +2 -2
  34. data/lib/hexapdf/content/processor.rb +15 -15
  35. data/lib/hexapdf/content/transformation_matrix.rb +1 -1
  36. data/lib/hexapdf/content.rb +5 -0
  37. data/lib/hexapdf/dictionary.rb +6 -5
  38. data/lib/hexapdf/dictionary_fields.rb +42 -14
  39. data/lib/hexapdf/digital_signature/cms_handler.rb +2 -2
  40. data/lib/hexapdf/digital_signature/handler.rb +1 -1
  41. data/lib/hexapdf/digital_signature/pkcs1_handler.rb +2 -3
  42. data/lib/hexapdf/digital_signature/signature.rb +6 -6
  43. data/lib/hexapdf/digital_signature/signatures.rb +13 -12
  44. data/lib/hexapdf/digital_signature/signing/default_handler.rb +14 -5
  45. data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +2 -4
  46. data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +4 -4
  47. data/lib/hexapdf/digital_signature/signing.rb +4 -0
  48. data/lib/hexapdf/digital_signature/verification_result.rb +2 -2
  49. data/lib/hexapdf/digital_signature.rb +7 -2
  50. data/lib/hexapdf/document/destinations.rb +12 -11
  51. data/lib/hexapdf/document/files.rb +1 -1
  52. data/lib/hexapdf/document/fonts.rb +1 -1
  53. data/lib/hexapdf/document/layout.rb +167 -39
  54. data/lib/hexapdf/document/pages.rb +3 -2
  55. data/lib/hexapdf/document.rb +89 -55
  56. data/lib/hexapdf/encryption/aes.rb +5 -5
  57. data/lib/hexapdf/encryption/arc4.rb +1 -1
  58. data/lib/hexapdf/encryption/fast_aes.rb +2 -2
  59. data/lib/hexapdf/encryption/fast_arc4.rb +1 -1
  60. data/lib/hexapdf/encryption/identity.rb +1 -1
  61. data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
  62. data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
  63. data/lib/hexapdf/encryption/security_handler.rb +31 -24
  64. data/lib/hexapdf/encryption/standard_security_handler.rb +45 -36
  65. data/lib/hexapdf/encryption.rb +7 -2
  66. data/lib/hexapdf/error.rb +18 -0
  67. data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
  68. data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
  69. data/lib/hexapdf/filter/flate_decode.rb +1 -1
  70. data/lib/hexapdf/filter/lzw_decode.rb +1 -1
  71. data/lib/hexapdf/filter/pass_through.rb +1 -1
  72. data/lib/hexapdf/filter/predictor.rb +1 -1
  73. data/lib/hexapdf/filter/run_length_decode.rb +1 -1
  74. data/lib/hexapdf/filter.rb +55 -6
  75. data/lib/hexapdf/font/cmap/parser.rb +2 -2
  76. data/lib/hexapdf/font/cmap.rb +1 -1
  77. data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
  78. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
  79. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +2 -2
  80. data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
  81. data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
  82. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +3 -3
  83. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
  84. data/lib/hexapdf/font/invalid_glyph.rb +3 -0
  85. data/lib/hexapdf/font/true_type_wrapper.rb +17 -4
  86. data/lib/hexapdf/font/type1_wrapper.rb +19 -4
  87. data/lib/hexapdf/font_loader/from_configuration.rb +5 -2
  88. data/lib/hexapdf/font_loader/from_file.rb +5 -5
  89. data/lib/hexapdf/font_loader/standard14.rb +3 -3
  90. data/lib/hexapdf/font_loader.rb +3 -0
  91. data/lib/hexapdf/image_loader/jpeg.rb +2 -2
  92. data/lib/hexapdf/image_loader/pdf.rb +1 -1
  93. data/lib/hexapdf/image_loader/png.rb +2 -2
  94. data/lib/hexapdf/image_loader.rb +1 -1
  95. data/lib/hexapdf/importer.rb +13 -0
  96. data/lib/hexapdf/layout/box.rb +9 -2
  97. data/lib/hexapdf/layout/box_fitter.rb +2 -2
  98. data/lib/hexapdf/layout/column_box.rb +18 -4
  99. data/lib/hexapdf/layout/frame.rb +30 -12
  100. data/lib/hexapdf/layout/image_box.rb +5 -0
  101. data/lib/hexapdf/layout/inline_box.rb +1 -0
  102. data/lib/hexapdf/layout/list_box.rb +17 -1
  103. data/lib/hexapdf/layout/page_style.rb +4 -4
  104. data/lib/hexapdf/layout/style.rb +18 -3
  105. data/lib/hexapdf/layout/table_box.rb +682 -0
  106. data/lib/hexapdf/layout/text_box.rb +5 -3
  107. data/lib/hexapdf/layout/text_fragment.rb +1 -1
  108. data/lib/hexapdf/layout/text_layouter.rb +12 -4
  109. data/lib/hexapdf/layout.rb +1 -0
  110. data/lib/hexapdf/name_tree_node.rb +1 -1
  111. data/lib/hexapdf/number_tree_node.rb +1 -1
  112. data/lib/hexapdf/object.rb +18 -7
  113. data/lib/hexapdf/parser.rb +8 -8
  114. data/lib/hexapdf/pdf_array.rb +1 -1
  115. data/lib/hexapdf/rectangle.rb +1 -1
  116. data/lib/hexapdf/reference.rb +1 -1
  117. data/lib/hexapdf/revision.rb +1 -1
  118. data/lib/hexapdf/revisions.rb +3 -3
  119. data/lib/hexapdf/serializer.rb +15 -15
  120. data/lib/hexapdf/stream.rb +4 -2
  121. data/lib/hexapdf/tokenizer.rb +14 -14
  122. data/lib/hexapdf/type/acro_form/appearance_generator.rb +22 -22
  123. data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
  124. data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
  125. data/lib/hexapdf/type/acro_form/field.rb +2 -2
  126. data/lib/hexapdf/type/acro_form/form.rb +1 -1
  127. data/lib/hexapdf/type/acro_form/signature_field.rb +4 -4
  128. data/lib/hexapdf/type/acro_form/text_field.rb +1 -1
  129. data/lib/hexapdf/type/acro_form/variable_text_field.rb +1 -1
  130. data/lib/hexapdf/type/acro_form.rb +1 -1
  131. data/lib/hexapdf/type/action.rb +1 -1
  132. data/lib/hexapdf/type/actions/go_to.rb +1 -1
  133. data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
  134. data/lib/hexapdf/type/actions/launch.rb +1 -1
  135. data/lib/hexapdf/type/actions/uri.rb +1 -1
  136. data/lib/hexapdf/type/actions.rb +1 -1
  137. data/lib/hexapdf/type/annotation.rb +3 -3
  138. data/lib/hexapdf/type/annotations/link.rb +1 -1
  139. data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
  140. data/lib/hexapdf/type/annotations/text.rb +1 -1
  141. data/lib/hexapdf/type/annotations/widget.rb +2 -2
  142. data/lib/hexapdf/type/annotations.rb +1 -1
  143. data/lib/hexapdf/type/catalog.rb +1 -1
  144. data/lib/hexapdf/type/cid_font.rb +3 -3
  145. data/lib/hexapdf/type/embedded_file.rb +1 -1
  146. data/lib/hexapdf/type/file_specification.rb +2 -2
  147. data/lib/hexapdf/type/font_descriptor.rb +1 -1
  148. data/lib/hexapdf/type/font_simple.rb +2 -2
  149. data/lib/hexapdf/type/font_type0.rb +3 -3
  150. data/lib/hexapdf/type/font_type3.rb +1 -1
  151. data/lib/hexapdf/type/form.rb +1 -1
  152. data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
  153. data/lib/hexapdf/type/icon_fit.rb +1 -1
  154. data/lib/hexapdf/type/image.rb +1 -1
  155. data/lib/hexapdf/type/info.rb +1 -1
  156. data/lib/hexapdf/type/mark_information.rb +1 -1
  157. data/lib/hexapdf/type/names.rb +2 -2
  158. data/lib/hexapdf/type/object_stream.rb +7 -3
  159. data/lib/hexapdf/type/outline.rb +1 -1
  160. data/lib/hexapdf/type/outline_item.rb +1 -1
  161. data/lib/hexapdf/type/page.rb +19 -10
  162. data/lib/hexapdf/type/page_label.rb +1 -1
  163. data/lib/hexapdf/type/page_tree_node.rb +1 -1
  164. data/lib/hexapdf/type/resources.rb +1 -1
  165. data/lib/hexapdf/type/trailer.rb +2 -2
  166. data/lib/hexapdf/type/viewer_preferences.rb +1 -1
  167. data/lib/hexapdf/type/xref_stream.rb +2 -2
  168. data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
  169. data/lib/hexapdf/version.rb +1 -1
  170. data/lib/hexapdf/writer.rb +4 -4
  171. data/lib/hexapdf/xref_section.rb +2 -2
  172. data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +11 -1
  173. data/test/hexapdf/content/graphic_object/test_geom2d.rb +7 -0
  174. data/test/hexapdf/content/test_canvas.rb +0 -1
  175. data/test/hexapdf/digital_signature/test_signatures.rb +22 -0
  176. data/test/hexapdf/document/test_files.rb +2 -2
  177. data/test/hexapdf/document/test_layout.rb +98 -0
  178. data/test/hexapdf/encryption/test_security_handler.rb +12 -11
  179. data/test/hexapdf/encryption/test_standard_security_handler.rb +35 -23
  180. data/test/hexapdf/font/test_true_type_wrapper.rb +18 -1
  181. data/test/hexapdf/font/test_type1_wrapper.rb +15 -1
  182. data/test/hexapdf/layout/test_box.rb +1 -1
  183. data/test/hexapdf/layout/test_column_box.rb +65 -21
  184. data/test/hexapdf/layout/test_frame.rb +14 -14
  185. data/test/hexapdf/layout/test_image_box.rb +4 -0
  186. data/test/hexapdf/layout/test_inline_box.rb +5 -0
  187. data/test/hexapdf/layout/test_list_box.rb +40 -6
  188. data/test/hexapdf/layout/test_page_style.rb +3 -2
  189. data/test/hexapdf/layout/test_style.rb +50 -0
  190. data/test/hexapdf/layout/test_table_box.rb +722 -0
  191. data/test/hexapdf/layout/test_text_box.rb +18 -0
  192. data/test/hexapdf/layout/test_text_layouter.rb +4 -0
  193. data/test/hexapdf/test_dictionary_fields.rb +4 -1
  194. data/test/hexapdf/test_document.rb +1 -0
  195. data/test/hexapdf/test_filter.rb +8 -0
  196. data/test/hexapdf/test_importer.rb +9 -0
  197. data/test/hexapdf/test_object.rb +16 -5
  198. data/test/hexapdf/test_parser.rb +1 -1
  199. data/test/hexapdf/test_stream.rb +7 -0
  200. data/test/hexapdf/test_writer.rb +3 -3
  201. data/test/hexapdf/type/acro_form/test_appearance_generator.rb +13 -5
  202. data/test/hexapdf/type/acro_form/test_form.rb +4 -3
  203. data/test/hexapdf/type/test_object_stream.rb +9 -3
  204. data/test/hexapdf/type/test_page.rb +18 -4
  205. 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.