hexapdf 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +76 -2
  3. data/CONTRIBUTERS +1 -1
  4. data/Rakefile +1 -1
  5. data/VERSION +1 -1
  6. data/examples/boxes.rb +68 -0
  7. data/examples/graphics.rb +12 -12
  8. data/examples/{text_box_alignment.rb → text_layouter_alignment.rb} +14 -14
  9. data/examples/text_layouter_inline_boxes.rb +66 -0
  10. data/examples/{text_box_line_wrapping.rb → text_layouter_line_wrapping.rb} +9 -10
  11. data/examples/{text_box_shapes.rb → text_layouter_shapes.rb} +58 -54
  12. data/examples/text_layouter_styling.rb +125 -0
  13. data/examples/truetype.rb +5 -7
  14. data/lib/hexapdf/cli/command.rb +1 -0
  15. data/lib/hexapdf/configuration.rb +170 -106
  16. data/lib/hexapdf/content/canvas.rb +41 -36
  17. data/lib/hexapdf/content/graphics_state.rb +15 -0
  18. data/lib/hexapdf/content/operator.rb +1 -1
  19. data/lib/hexapdf/dictionary.rb +20 -8
  20. data/lib/hexapdf/dictionary_fields.rb +8 -6
  21. data/lib/hexapdf/document.rb +25 -26
  22. data/lib/hexapdf/document/fonts.rb +4 -4
  23. data/lib/hexapdf/document/images.rb +2 -2
  24. data/lib/hexapdf/document/pages.rb +16 -16
  25. data/lib/hexapdf/encryption/security_handler.rb +41 -9
  26. data/lib/hexapdf/filter/flate_decode.rb +1 -1
  27. data/lib/hexapdf/filter/lzw_decode.rb +1 -1
  28. data/lib/hexapdf/filter/predictor.rb +7 -1
  29. data/lib/hexapdf/font/true_type/font.rb +20 -0
  30. data/lib/hexapdf/font/type1/font.rb +23 -0
  31. data/lib/hexapdf/font_loader.rb +1 -0
  32. data/lib/hexapdf/font_loader/from_configuration.rb +2 -3
  33. data/lib/hexapdf/font_loader/from_file.rb +65 -0
  34. data/lib/hexapdf/image_loader/png.rb +2 -2
  35. data/lib/hexapdf/layout.rb +3 -2
  36. data/lib/hexapdf/layout/box.rb +146 -0
  37. data/lib/hexapdf/layout/inline_box.rb +40 -31
  38. data/lib/hexapdf/layout/{line_fragment.rb → line.rb} +12 -13
  39. data/lib/hexapdf/layout/style.rb +630 -41
  40. data/lib/hexapdf/layout/text_fragment.rb +80 -12
  41. data/lib/hexapdf/layout/{text_box.rb → text_layouter.rb} +164 -109
  42. data/lib/hexapdf/number_tree_node.rb +1 -1
  43. data/lib/hexapdf/parser.rb +4 -1
  44. data/lib/hexapdf/revisions.rb +11 -4
  45. data/lib/hexapdf/stream.rb +8 -9
  46. data/lib/hexapdf/tokenizer.rb +5 -3
  47. data/lib/hexapdf/type.rb +3 -0
  48. data/lib/hexapdf/type/action.rb +56 -0
  49. data/lib/hexapdf/type/actions.rb +52 -0
  50. data/lib/hexapdf/type/actions/go_to.rb +52 -0
  51. data/lib/hexapdf/type/actions/go_to_r.rb +54 -0
  52. data/lib/hexapdf/type/actions/launch.rb +73 -0
  53. data/lib/hexapdf/type/actions/uri.rb +65 -0
  54. data/lib/hexapdf/type/annotation.rb +85 -0
  55. data/lib/hexapdf/type/annotations.rb +51 -0
  56. data/lib/hexapdf/type/annotations/link.rb +70 -0
  57. data/lib/hexapdf/type/annotations/markup_annotation.rb +70 -0
  58. data/lib/hexapdf/type/annotations/text.rb +81 -0
  59. data/lib/hexapdf/type/catalog.rb +3 -1
  60. data/lib/hexapdf/type/embedded_file.rb +6 -11
  61. data/lib/hexapdf/type/file_specification.rb +4 -6
  62. data/lib/hexapdf/type/font.rb +3 -1
  63. data/lib/hexapdf/type/font_descriptor.rb +18 -16
  64. data/lib/hexapdf/type/form.rb +3 -1
  65. data/lib/hexapdf/type/graphics_state_parameter.rb +3 -1
  66. data/lib/hexapdf/type/image.rb +4 -2
  67. data/lib/hexapdf/type/info.rb +2 -5
  68. data/lib/hexapdf/type/names.rb +2 -5
  69. data/lib/hexapdf/type/object_stream.rb +2 -1
  70. data/lib/hexapdf/type/page.rb +14 -1
  71. data/lib/hexapdf/type/page_tree_node.rb +9 -6
  72. data/lib/hexapdf/type/resources.rb +2 -5
  73. data/lib/hexapdf/type/trailer.rb +2 -5
  74. data/lib/hexapdf/type/viewer_preferences.rb +2 -5
  75. data/lib/hexapdf/type/xref_stream.rb +3 -1
  76. data/lib/hexapdf/version.rb +1 -1
  77. data/test/hexapdf/common_tokenizer_tests.rb +3 -1
  78. data/test/hexapdf/content/test_canvas.rb +29 -3
  79. data/test/hexapdf/content/test_graphics_state.rb +11 -0
  80. data/test/hexapdf/content/test_operator.rb +3 -2
  81. data/test/hexapdf/document/test_fonts.rb +8 -8
  82. data/test/hexapdf/document/test_images.rb +4 -12
  83. data/test/hexapdf/document/test_pages.rb +7 -7
  84. data/test/hexapdf/encryption/test_security_handler.rb +1 -5
  85. data/test/hexapdf/filter/test_predictor.rb +40 -12
  86. data/test/hexapdf/font/true_type/test_font.rb +16 -0
  87. data/test/hexapdf/font/type1/test_font.rb +30 -0
  88. data/test/hexapdf/font_loader/test_from_file.rb +29 -0
  89. data/test/hexapdf/font_loader/test_standard14.rb +4 -3
  90. data/test/hexapdf/layout/test_box.rb +104 -0
  91. data/test/hexapdf/layout/test_inline_box.rb +24 -10
  92. data/test/hexapdf/layout/{test_line_fragment.rb → test_line.rb} +9 -9
  93. data/test/hexapdf/layout/test_style.rb +519 -31
  94. data/test/hexapdf/layout/test_text_fragment.rb +136 -15
  95. data/test/hexapdf/layout/{test_text_box.rb → test_text_layouter.rb} +224 -144
  96. data/test/hexapdf/layout/test_text_shaper.rb +1 -1
  97. data/test/hexapdf/test_configuration.rb +12 -6
  98. data/test/hexapdf/test_dictionary.rb +27 -2
  99. data/test/hexapdf/test_dictionary_fields.rb +10 -1
  100. data/test/hexapdf/test_document.rb +14 -13
  101. data/test/hexapdf/test_parser.rb +12 -0
  102. data/test/hexapdf/test_revisions.rb +34 -0
  103. data/test/hexapdf/test_stream.rb +1 -1
  104. data/test/hexapdf/test_type.rb +18 -0
  105. data/test/hexapdf/test_writer.rb +2 -2
  106. data/test/hexapdf/type/actions/test_launch.rb +24 -0
  107. data/test/hexapdf/type/actions/test_uri.rb +23 -0
  108. data/test/hexapdf/type/annotations/test_link.rb +19 -0
  109. data/test/hexapdf/type/annotations/test_markup_annotation.rb +22 -0
  110. data/test/hexapdf/type/annotations/test_text.rb +38 -0
  111. data/test/hexapdf/type/test_annotation.rb +38 -0
  112. data/test/hexapdf/type/test_file_specification.rb +0 -7
  113. data/test/hexapdf/type/test_info.rb +0 -5
  114. data/test/hexapdf/type/test_page.rb +14 -0
  115. data/test/hexapdf/type/test_page_tree_node.rb +4 -1
  116. data/test/hexapdf/type/test_trailer.rb +0 -4
  117. data/test/test_helper.rb +6 -3
  118. metadata +36 -15
  119. data/examples/text_box_inline_boxes.rb +0 -56
  120. data/examples/text_box_styling.rb +0 -72
  121. data/test/hexapdf/type/test_embedded_file.rb +0 -16
  122. data/test/hexapdf/type/test_names.rb +0 -9
@@ -47,7 +47,7 @@ module HexaPDF
47
47
  include Utils::SortedTreeNode
48
48
 
49
49
  define_field :Kids, type: Array
50
- define_field :Nums, type: Array
50
+ define_field :Nums, type: Array
51
51
  define_field :Limits, type: Array
52
52
 
53
53
  private
@@ -228,7 +228,10 @@ module HexaPDF
228
228
 
229
229
  @tokenizer.skip_whitespace
230
230
  start.upto(start + number_of_entries - 1) do |oid|
231
- pos, gen, type = @tokenizer.next_xref_entry
231
+ pos, gen, type = @tokenizer.next_xref_entry do |matched_size|
232
+ maybe_raise("Invalid cross-reference subsection entry", pos: @tokenizer.pos,
233
+ force: matched_size == 20)
234
+ end
232
235
  if xref.entry?(oid)
233
236
  next
234
237
  elsif type == 'n'.freeze
@@ -67,15 +67,22 @@ module HexaPDF
67
67
  xref_section, trailer = parser.load_revision(parser.startxref_offset)
68
68
  revisions << Revision.new(document.wrap(trailer, type: :XXTrailer),
69
69
  xref_section: xref_section, loader: object_loader)
70
+ seen_xref_offsets = {parser.startxref_offset => true}
70
71
 
71
-
72
- while (prev = revisions[0].trailer.value[:Prev])
72
+ while (prev = revisions[0].trailer.value[:Prev]) &&
73
+ !seen_xref_offsets.key?(prev)
73
74
  # PDF1.7 s7.5.5 states that :Prev needs to be indirect, Adobe's reference 3.4.4 says it
74
75
  # should be direct. Adobe's POV is followed here. Same with :XRefStm.
75
76
  xref_section, trailer = parser.load_revision(prev)
77
+ seen_xref_offsets[prev] = true
78
+
76
79
  stm = revisions[0].trailer.value[:XRefStm]
77
- stm_xref_section, = parser.load_revision(stm) if stm
78
- xref_section.merge!(stm_xref_section) if stm
80
+ if stm && !seen_xref_offsets.key?(stm)
81
+ stm_xref_section, = parser.load_revision(stm)
82
+ xref_section.merge!(stm_xref_section)
83
+ seen_xref_offsets[stm] = true
84
+ end
85
+
79
86
  revisions.unshift(Revision.new(document.wrap(trailer, type: :XXTrailer),
80
87
  xref_section: xref_section, loader: object_loader))
81
88
  end
@@ -117,7 +117,7 @@ module HexaPDF
117
117
  define_field :Length, type: Integer # not required, will be auto-filled when writing
118
118
  define_field :Filter, type: [Symbol, Array]
119
119
  define_field :DecodeParms, type: [Dictionary, Hash, Array]
120
- define_field :F, type: :FileSpec, version: '1.2'
120
+ define_field :F, type: :Filespec, version: '1.2'
121
121
  define_field :FFilter, type: [Symbol, Array], version: '1.2'
122
122
  define_field :FDecodeParms, type: [Dictionary, Hash, Array], version: '1.2'
123
123
  define_field :DL, type: Integer
@@ -181,17 +181,16 @@ module HexaPDF
181
181
  source
182
182
  end
183
183
 
184
- # Returns the encoder Fiber for the stream data.
184
+ # :call-seq:
185
+ # stream.stream_encoder
185
186
  #
186
- # The two arguments can be used to add additional filters for *only* this returned encoder
187
- # Fiber. They should normally *not* be used and are here for use by the encryption facilities.
187
+ # Returns the encoder Fiber for the stream data.
188
188
  #
189
189
  # See the Filter module for more information on how to work with the fiber.
190
- def stream_encoder(additional_filter = nil, additional_decode_parms = nil)
191
- encoder_data = [additional_filter, document.unwrap(self[:Filter])].flatten.
192
- zip([additional_decode_parms, document.unwrap(self[:DecodeParms])].flatten).
190
+ def stream_encoder(source = stream_source)
191
+ encoder_data = [document.unwrap(self[:Filter])].flatten.
192
+ zip([document.unwrap(self[:DecodeParms])].flatten).
193
193
  delete_if {|f, _| f.nil?}
194
- source = stream_source
195
194
 
196
195
  if data.stream.kind_of?(StreamData)
197
196
  decoder_data = data.stream.filter.zip(data.stream.decode_parms)
@@ -249,7 +248,7 @@ module HexaPDF
249
248
  #
250
249
  # See: HexaPDF::Filter
251
250
  def filter_for_name(filter_name)
252
- GlobalConfiguration.constantize('filter.map', filter_name) do
251
+ config.constantize('filter.map', filter_name) do
253
252
  raise HexaPDF::Error, "Unknown stream filter '#{filter_name}' encountered"
254
253
  end
255
254
  end
@@ -196,11 +196,13 @@ module HexaPDF
196
196
  # Reads the cross-reference subsection entry at the current position and advances the scan
197
197
  # pointer.
198
198
  #
199
+ # If a possible problem is detected, yields to caller.
200
+ #
199
201
  # See: PDF1.7 7.5.4
200
- def next_xref_entry
202
+ def next_xref_entry #:yield: matched_size
201
203
  prepare_string_scanner(20)
202
- unless @ss.skip(/(\d{10}) (\d{5}) ([nf])(?: \r| \n|\r\n)/)
203
- raise HexaPDF::MalformedPDFError.new("Invalid cross-reference subsection entry", pos: pos)
204
+ unless @ss.skip(/(\d{10}) (\d{5}) ([nf])(?: \r| \n|\r\n|\r|\n)/) && @ss.matched_size == 20
205
+ yield(@ss.matched_size)
204
206
  end
205
207
  [@ss[1].to_i, @ss[2].to_i, @ss[3]]
206
208
  end
@@ -31,6 +31,9 @@
31
31
  # is created or manipulated using HexaPDF.
32
32
  #++
33
33
 
34
+ require 'hexapdf/type/actions'
35
+ require 'hexapdf/type/annotations'
36
+
34
37
  module HexaPDF
35
38
 
36
39
  # == Overview
@@ -0,0 +1,56 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2014-2017 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #++
33
+
34
+ require 'hexapdf/dictionary'
35
+
36
+ module HexaPDF
37
+ module Type
38
+
39
+ # Represents a generic PDF action dictionary.
40
+ #
41
+ # Action dictionaries are used, for example, by annotations or outline items to specify the
42
+ # action that should be performed. Each action class should be defined under the Actions module.
43
+ #
44
+ # See: PDF1.7 s12.6
45
+ class Action < Dictionary
46
+
47
+ define_type :Action
48
+
49
+ define_field :Type, type: Symbol, default: self.type
50
+ define_field :S, type: Symbol, required: true
51
+ define_field :Next, type: [Dictionary, Hash, Array], version: '1.2'
52
+
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,52 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2014-2017 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #++
33
+
34
+ module HexaPDF
35
+ module Type
36
+
37
+ autoload(:Action, 'hexapdf/type/action')
38
+
39
+ # Namespace module for all PDF action dictionary types.
40
+ #
41
+ # See: PDF1.7 s12.6.4, Action
42
+ module Actions
43
+
44
+ autoload(:GoTo, 'hexapdf/type/actions/go_to')
45
+ autoload(:GoToR, 'hexapdf/type/actions/go_to_r')
46
+ autoload(:Launch, 'hexapdf/type/actions/launch')
47
+ autoload(:URI, 'hexapdf/type/actions/uri')
48
+
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,52 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2014-2017 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #++
33
+
34
+ require 'hexapdf/type/action'
35
+
36
+ module HexaPDF
37
+ module Type
38
+ module Actions
39
+
40
+ # A Go-To action changes the view to a specific destination.
41
+ #
42
+ # See: PDF1.7 s12.6.4.2
43
+ class GoTo < Action
44
+
45
+ define_field :S, type: Symbol, required: true, default: :GoTo
46
+ define_field :D, type: [Symbol, PDFByteString, Array], required: true
47
+
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,54 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2014-2017 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #++
33
+
34
+ require 'hexapdf/type/action'
35
+
36
+ module HexaPDF
37
+ module Type
38
+ module Actions
39
+
40
+ # A remote Go-To action dictionary jumps to a destination in a different PDF file.
41
+ #
42
+ # See: PDF1.7 s12.6.4.3
43
+ class GoToR < Action
44
+
45
+ define_field :S, type: Symbol, required: true, default: :GoToR
46
+ define_field :F, type: :Filespec, required: true
47
+ define_field :D, type: [Symbol, PDFByteString, Array], required: true
48
+ define_field :NewWindow, type: Boolean, version: '1.2'
49
+
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,73 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2014-2017 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #++
33
+
34
+ require 'hexapdf/type/action'
35
+
36
+ module HexaPDF
37
+ module Type
38
+ module Actions
39
+
40
+ # A Launch action dictionary launches an application, opens a document or prints a document.
41
+ #
42
+ # See: PDF1.7 s12.6.4.5
43
+ class Launch < Action
44
+
45
+ # The type used for the /Win field of a Launch action dictionary.
46
+ class WinParameters < Dictionary
47
+
48
+ define_type :XXLaunchActionWinParameters
49
+
50
+ define_field :F, type: PDFByteString, required: true
51
+ define_field :D, type: PDFByteString
52
+ define_field :O, type: String
53
+ define_field :P, type: PDFByteString
54
+
55
+ end
56
+
57
+ define_field :S, type: Symbol, required: true, default: :Launch
58
+ define_field :F, type: :Filespec
59
+ define_field :Win, type: :XXLaunchActionWinParameters
60
+ define_field :NewWindow, type: Boolean, version: '1.2'
61
+
62
+ private
63
+
64
+ def perform_validation #:nodoc:
65
+ super
66
+ yield("A Launch action needs a target") unless key?(:F) || key?(:Win)
67
+ end
68
+
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,65 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2014-2017 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #++
33
+
34
+ require 'hexapdf/type/action'
35
+
36
+ module HexaPDF
37
+ module Type
38
+ module Actions
39
+
40
+ # Represents an URI action dictionary, mostly used for opening Internet pages.
41
+ #
42
+ # See: PDF1.7 s12.6.4.7
43
+ class URI < Action
44
+
45
+ define_field :S, type: Symbol, required: true, default: :URI
46
+ define_field :URI, type: String, required: true
47
+ define_field :IsMap, type: Boolean
48
+
49
+ private
50
+
51
+ def perform_validation #:nodoc:
52
+ super
53
+ unless self[:URI].ascii_only?
54
+ yield("URIs have to contain ASCII characters only", true)
55
+ uri = self[:URI].dup.force_encoding(Encoding::BINARY)
56
+ uri.encode!(Encoding::US_ASCII, fallback: ->(c) { "%#{c.ord.to_s(16).upcase}"})
57
+ self[:URI] = uri
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+ end
65
+ end