pdfrb 0.8.3 → 0.8.5
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.
- checksums.yaml +4 -4
- data/lib/pdfrb/annotation/base.rb +2 -2
- data/lib/pdfrb/appearance/generator.rb +1 -1
- data/lib/pdfrb/cli/images.rb +1 -1
- data/lib/pdfrb/cli.rb +3 -3
- data/lib/pdfrb/color/default_profile.rb +1 -1
- data/lib/pdfrb/conformance/ltv.rb +1 -1
- data/lib/pdfrb/conformance/pades.rb +4 -4
- data/lib/pdfrb/conformance/pdf_2_af.rb +2 -2
- data/lib/pdfrb/conformance/pdf_a.rb +1 -1
- data/lib/pdfrb/conformance/pdf_x.rb +3 -3
- data/lib/pdfrb/conformance/tagged_pdf.rb +1 -1
- data/lib/pdfrb/content/canvas.rb +1 -1
- data/lib/pdfrb/content/hidden_text_detector.rb +1 -1
- data/lib/pdfrb/content/shading/base.rb +1 -1
- data/lib/pdfrb/content/tiling_pattern.rb +1 -1
- data/lib/pdfrb/digital_signature/signing.rb +2 -2
- data/lib/pdfrb/document/annotations.rb +10 -10
- data/lib/pdfrb/document/associated_files.rb +2 -2
- data/lib/pdfrb/document/colors.rb +1 -1
- data/lib/pdfrb/document/destinations.rb +4 -4
- data/lib/pdfrb/document/encryption.rb +1 -1
- data/lib/pdfrb/document/files.rb +5 -5
- data/lib/pdfrb/document/fonts/subsetting.rb +87 -0
- data/lib/pdfrb/document/fonts.rb +10 -80
- data/lib/pdfrb/document/form.rb +9 -9
- data/lib/pdfrb/document/form_xobject.rb +1 -1
- data/lib/pdfrb/document/graphics_state.rb +1 -1
- data/lib/pdfrb/document/images.rb +1 -6
- data/lib/pdfrb/document/info.rb +1 -1
- data/lib/pdfrb/document/layers.rb +1 -1
- data/lib/pdfrb/document/metadata.rb +1 -1
- data/lib/pdfrb/document/outline.rb +8 -8
- data/lib/pdfrb/document/output_intents.rb +3 -3
- data/lib/pdfrb/document/pages.rb +19 -8
- data/lib/pdfrb/document/pdf_a.rb +1 -1
- data/lib/pdfrb/document/portfolio.rb +3 -3
- data/lib/pdfrb/document/shadings.rb +2 -9
- data/lib/pdfrb/document/stamps.rb +2 -2
- data/lib/pdfrb/document/structure.rb +9 -9
- data/lib/pdfrb/document.rb +10 -3
- data/lib/pdfrb/encryption/security_handler.rb +1 -2
- data/lib/pdfrb/font/cff/subsetter.rb +0 -0
- data/lib/pdfrb/font/sfnt.rb +73 -0
- data/lib/pdfrb/font/true_type/subsetter.rb +1 -57
- data/lib/pdfrb/font/true_type/wrapper.rb +3 -3
- data/lib/pdfrb/font.rb +1 -0
- data/lib/pdfrb/font_loader/true_type.rb +2 -2
- data/lib/pdfrb/font_loader/type3.rb +1 -1
- data/lib/pdfrb/importer.rb +3 -3
- data/lib/pdfrb/linearization/writer.rb +1 -1
- data/lib/pdfrb/model/object.rb +7 -0
- data/lib/pdfrb/model/type/action_hide.rb +1 -1
- data/lib/pdfrb/model/type/action_sound.rb +2 -2
- data/lib/pdfrb/model/type/add_action_catalog.rb +1 -1
- data/lib/pdfrb/model/type/add_action_form_field.rb +1 -1
- data/lib/pdfrb/model/type/add_action_page_object.rb +1 -1
- data/lib/pdfrb/model/type/add_action_screen_annotation.rb +1 -1
- data/lib/pdfrb/model/type/add_action_widget_annotation.rb +1 -1
- data/lib/pdfrb/model/type/alternate_image.rb +2 -2
- data/lib/pdfrb/model/type/bead.rb +4 -4
- data/lib/pdfrb/model/type/catalog.rb +1 -1
- data/lib/pdfrb/model/type/color_space.rb +5 -31
- data/lib/pdfrb/model/type/crypt_filter.rb +6 -6
- data/lib/pdfrb/model/type/d_part.rb +4 -4
- data/lib/pdfrb/model/type/destination.rb +2 -18
- data/lib/pdfrb/model/type/document_security_store.rb +1 -1
- data/lib/pdfrb/model/type/dss.rb +1 -1
- data/lib/pdfrb/model/type/font_multiple_master.rb +3 -12
- data/lib/pdfrb/model/type/function_stitching.rb +1 -1
- data/lib/pdfrb/model/type/generic_appearance.rb +1 -1
- data/lib/pdfrb/model/type/misc_extras.rb +2 -7
- data/lib/pdfrb/model/type/name_map.rb +33 -0
- data/lib/pdfrb/model/type/opt_content_ext.rb +2 -2
- data/lib/pdfrb/model/type/optional_content_membership.rb +2 -2
- data/lib/pdfrb/model/type/page.rb +5 -7
- data/lib/pdfrb/model/type/page_tree_node.rb +2 -2
- data/lib/pdfrb/model/type/pattern.rb +2 -18
- data/lib/pdfrb/model/type/rich_media_configuration.rb +1 -1
- data/lib/pdfrb/model/type/shading.rb +2 -18
- data/lib/pdfrb/model/type/signature_extras.rb +6 -21
- data/lib/pdfrb/model/type/soft_mask.rb +1 -13
- data/lib/pdfrb/model/type/struct_elem.rb +2 -2
- data/lib/pdfrb/model/type/struct_tree_root.rb +2 -2
- data/lib/pdfrb/model/type/structure_attributes.rb +5 -18
- data/lib/pdfrb/model/type/thread.rb +3 -3
- data/lib/pdfrb/model/type/three_d_stream.rb +1 -1
- data/lib/pdfrb/model/type/viewport.rb +1 -1
- data/lib/pdfrb/model/type/vri.rb +1 -1
- data/lib/pdfrb/model/type/web_capture_command.rb +1 -1
- data/lib/pdfrb/model/type/web_capture_image_set.rb +1 -1
- data/lib/pdfrb/model/type/web_capture_page_set.rb +2 -2
- data/lib/pdfrb/model/type/xobject_form.rb +1 -13
- data/lib/pdfrb/model/type.rb +2 -0
- data/lib/pdfrb/task/extract_images.rb +1 -2
- data/lib/pdfrb/task/extract_text.rb +1 -1
- data/lib/pdfrb/task/merge.rb +3 -3
- data/lib/pdfrb/task/thumbnail.rb +1 -1
- data/lib/pdfrb/version.rb +1 -1
- data/lib/pdfrb/writer.rb +4 -5
- data/lib/pdfrb/xmp.rb +2 -2
- metadata +5 -2
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pdfrb
|
|
4
|
+
module Font
|
|
5
|
+
# sfnt container (OpenType/TTF) table directory: the shared seam
|
|
6
|
+
# for reading and rebuilding the wrapper around font outlines.
|
|
7
|
+
# Both subsetters (TrueType glyf and CFF) rebuild the directory
|
|
8
|
+
# around their subset tables; this module owns that format so
|
|
9
|
+
# the two implementations cannot drift (they once disagreed even
|
|
10
|
+
# on whether checksums are computed).
|
|
11
|
+
module Sfnt
|
|
12
|
+
Entry = Struct.new(:tag, :offset, :byte_length)
|
|
13
|
+
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
# Parse the table directory of an sfnt byte string.
|
|
17
|
+
# Returns [sfnt_version, Array<Entry>].
|
|
18
|
+
def parse_directory(sfnt)
|
|
19
|
+
num_tables = (sfnt.getbyte(4) * 256) + sfnt.getbyte(5)
|
|
20
|
+
version = sfnt.byteslice(0, 4)
|
|
21
|
+
entries = (0...num_tables).map do |i|
|
|
22
|
+
base = 12 + (i * 16)
|
|
23
|
+
Entry.new(
|
|
24
|
+
sfnt.byteslice(base, 4),
|
|
25
|
+
sfnt.byteslice(base + 8, 4).unpack1("N"),
|
|
26
|
+
sfnt.byteslice(base + 12, 4).unpack1("N")
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
[version, entries]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Raw bytes of +tag+'s table, or nil.
|
|
33
|
+
def table_bytes(sfnt, tag)
|
|
34
|
+
entry = parse_directory(sfnt)[1].find { |e| e.tag == tag }
|
|
35
|
+
entry && sfnt.byteslice(entry.offset, entry.byte_length)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Rebuild an sfnt wrapper: +sfnt_version+ is the 4-byte magic
|
|
39
|
+
# (e.g. "\x00\x01\x00\x00" or "OTTO"), +tables+ an Array of
|
|
40
|
+
# [tag, data] pairs. Checksums are computed per the sfnt spec
|
|
41
|
+
# (sum of big-endian u32s over zero-padded data).
|
|
42
|
+
def rebuild(sfnt_version, tables)
|
|
43
|
+
num = tables.length
|
|
44
|
+
search_range = (2**Math.log2(num).floor) * 16
|
|
45
|
+
entry_selector = Math.log2(num).floor
|
|
46
|
+
range_shift = (num * 16) - search_range
|
|
47
|
+
|
|
48
|
+
out = +"".b
|
|
49
|
+
out << sfnt_version.b
|
|
50
|
+
out << [num, search_range, entry_selector, range_shift].pack("n4")
|
|
51
|
+
|
|
52
|
+
sorted = tables.sort_by { |tag, _| tag }
|
|
53
|
+
offset = 12 + (num * 16)
|
|
54
|
+
sorted.each do |tag, data|
|
|
55
|
+
out << tag.b << [checksum(data), offset, data.bytesize].pack("NNN")
|
|
56
|
+
offset += (data.bytesize + 3) & ~3
|
|
57
|
+
end
|
|
58
|
+
sorted.to_h.each_value do |data|
|
|
59
|
+
out << data.b
|
|
60
|
+
out << ("\x00".b * ((4 - (out.bytesize % 4)) % 4))
|
|
61
|
+
end
|
|
62
|
+
out
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def checksum(data)
|
|
66
|
+
padded = data + ("\x00".b * ((4 - (data.bytesize % 4)) % 4))
|
|
67
|
+
sum = 0
|
|
68
|
+
padded.unpack("N*").each { |w| sum = (sum + w) & 0xFFFFFFFF }
|
|
69
|
+
sum
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -310,58 +310,7 @@ module Pdfrb
|
|
|
310
310
|
|
|
311
311
|
# rubocop:disable-next Metrics/MethodLength
|
|
312
312
|
def assemble_ttf(tables)
|
|
313
|
-
|
|
314
|
-
num = tables.length
|
|
315
|
-
search_range = power_of_2_floor(num) * 16
|
|
316
|
-
entry_selector = Math.log2(search_range / 16).to_i
|
|
317
|
-
range_shift = (num * 16) - search_range
|
|
318
|
-
|
|
319
|
-
header_size = 12
|
|
320
|
-
dir_size = num * 16
|
|
321
|
-
data_offset = header_size + dir_size
|
|
322
|
-
|
|
323
|
-
# Pad data_offset to 4 bytes
|
|
324
|
-
data_offset = (data_offset + 3) & ~3
|
|
325
|
-
|
|
326
|
-
out = +""
|
|
327
|
-
out << SFNT_VERSION.pack("N") # sfnt version
|
|
328
|
-
out << [num].pack("n")
|
|
329
|
-
out << [search_range].pack("n")
|
|
330
|
-
out << [entry_selector].pack("n")
|
|
331
|
-
out << [range_shift].pack("n")
|
|
332
|
-
|
|
333
|
-
# Sort tables by tag
|
|
334
|
-
sorted = tables.sort_by { |tag, _| tag }
|
|
335
|
-
|
|
336
|
-
# Calculate offsets
|
|
337
|
-
current = data_offset
|
|
338
|
-
offsets = {}
|
|
339
|
-
sorted.each do |tag, data|
|
|
340
|
-
offsets[tag] = current
|
|
341
|
-
current += data.bytesize
|
|
342
|
-
current = (current + 3) & ~3
|
|
343
|
-
|
|
344
|
-
# Directory
|
|
345
|
-
out << tag.to_s
|
|
346
|
-
out << checksum_placeholder # checksum (skip)
|
|
347
|
-
out << [offsets[tag]].pack("N")
|
|
348
|
-
out << [data.bytesize].pack("N")
|
|
349
|
-
end
|
|
350
|
-
|
|
351
|
-
# Pad to data_offset
|
|
352
|
-
while out.bytesize < data_offset
|
|
353
|
-
out << "\x00"
|
|
354
|
-
end
|
|
355
|
-
|
|
356
|
-
# Table data
|
|
357
|
-
sorted.each_value do |data|
|
|
358
|
-
out << data
|
|
359
|
-
while (out.bytesize % 4).nonzero?
|
|
360
|
-
out << "\x00"
|
|
361
|
-
end
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
out.force_encoding(::Encoding::BINARY)
|
|
313
|
+
Pdfrb::Font::Sfnt.rebuild(SFNT_VERSION.pack("N"), tables)
|
|
365
314
|
end
|
|
366
315
|
|
|
367
316
|
# rubocop:disable Naming/MethodName
|
|
@@ -382,11 +331,6 @@ module Pdfrb
|
|
|
382
331
|
def pad_to_even(str); str << "\x00" if (str.bytesize % 2).nonzero?; end
|
|
383
332
|
|
|
384
333
|
# rubocop:enable Naming/MethodName
|
|
385
|
-
def power_of_2_floor(n)
|
|
386
|
-
p = 1
|
|
387
|
-
while p * 2 <= n; p *= 2; end
|
|
388
|
-
p
|
|
389
|
-
end
|
|
390
334
|
end
|
|
391
335
|
end
|
|
392
336
|
end
|
|
@@ -16,7 +16,7 @@ module Pdfrb
|
|
|
16
16
|
tu_stream = build_tounicode(document, ttf)
|
|
17
17
|
font_file = embed_font_file(document, ttf_data)
|
|
18
18
|
|
|
19
|
-
fd.value[:FontFile2] =
|
|
19
|
+
fd.value[:FontFile2] = font_file.ref
|
|
20
20
|
|
|
21
21
|
document.add(
|
|
22
22
|
{
|
|
@@ -26,8 +26,8 @@ module Pdfrb
|
|
|
26
26
|
FirstChar: 0,
|
|
27
27
|
LastChar: 255,
|
|
28
28
|
Widths: widths,
|
|
29
|
-
FontDescriptor:
|
|
30
|
-
ToUnicode:
|
|
29
|
+
FontDescriptor: fd.ref,
|
|
30
|
+
ToUnicode: tu_stream.ref,
|
|
31
31
|
Encoding: :WinAnsiEncoding,
|
|
32
32
|
},
|
|
33
33
|
type: Pdfrb::Model::Type::FontTrueType
|
data/lib/pdfrb/font.rb
CHANGED
|
@@ -10,6 +10,7 @@ module Pdfrb
|
|
|
10
10
|
autoload :CMap, "pdfrb/font/cmap"
|
|
11
11
|
autoload :TrueType, "pdfrb/font/true_type"
|
|
12
12
|
autoload :CFF, "pdfrb/font/cff"
|
|
13
|
+
autoload :Sfnt, "pdfrb/font/sfnt"
|
|
13
14
|
autoload :Type1, "pdfrb/font/type1"
|
|
14
15
|
autoload :Metrics, "pdfrb/font/metrics_helper"
|
|
15
16
|
autoload :MetricsHelper, "pdfrb/font/metrics_helper"
|
|
@@ -45,12 +45,12 @@ module Pdfrb
|
|
|
45
45
|
Descent: -200,
|
|
46
46
|
CapHeight: 700,
|
|
47
47
|
StemV: 80,
|
|
48
|
-
FontFile2:
|
|
48
|
+
FontFile2: font_stream.ref
|
|
49
49
|
},
|
|
50
50
|
type: Pdfrb::Model::Type::FontDescriptor
|
|
51
51
|
)
|
|
52
52
|
font_dict.value[:FontDescriptor] =
|
|
53
|
-
|
|
53
|
+
descriptor.ref
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
font_dict
|
|
@@ -40,7 +40,7 @@ module Pdfrb
|
|
|
40
40
|
stream = document.add({ Length: glyph.procedure.bytesize },
|
|
41
41
|
type: Pdfrb::Model::Cos::Stream)
|
|
42
42
|
stream.stream = glyph.procedure
|
|
43
|
-
char_procs[glyph.name.to_sym] =
|
|
43
|
+
char_procs[glyph.name.to_sym] = stream.ref
|
|
44
44
|
widths[code] = glyph.width
|
|
45
45
|
encoding[:Differences] << code << glyph.name.to_sym
|
|
46
46
|
end
|
data/lib/pdfrb/importer.rb
CHANGED
|
@@ -38,10 +38,10 @@ module Pdfrb
|
|
|
38
38
|
|
|
39
39
|
def import_reference(ref, source_doc)
|
|
40
40
|
cached = @mappings[ref.oid]
|
|
41
|
-
return
|
|
41
|
+
return cached.ref if cached
|
|
42
42
|
|
|
43
43
|
in_progress = @in_progress[ref.oid]
|
|
44
|
-
return
|
|
44
|
+
return in_progress.ref if in_progress
|
|
45
45
|
|
|
46
46
|
source_obj = source_doc.object(ref)
|
|
47
47
|
return nil unless source_obj
|
|
@@ -58,7 +58,7 @@ module Pdfrb
|
|
|
58
58
|
end
|
|
59
59
|
@mappings[ref.oid] = stub
|
|
60
60
|
@in_progress.delete(ref.oid)
|
|
61
|
-
|
|
61
|
+
stub.ref
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def import_hash(hash, source_doc)
|
|
@@ -239,7 +239,7 @@ module Pdfrb
|
|
|
239
239
|
def build_trailer(xref_offset)
|
|
240
240
|
root = @document.catalog
|
|
241
241
|
root_ref = if root.is_a?(Pdfrb::Model::Object) && root.indirect?
|
|
242
|
-
|
|
242
|
+
root.ref
|
|
243
243
|
end
|
|
244
244
|
size = [@document.next_oid || 1, 2].max
|
|
245
245
|
|
data/lib/pdfrb/model/object.rb
CHANGED
|
@@ -27,6 +27,13 @@ module Pdfrb
|
|
|
27
27
|
@document = document
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
# The indirect reference denoting this object. The single
|
|
31
|
+
# seam for "a reference to this" — callers never construct
|
|
32
|
+
# Reference.new(obj.oid, obj.gen) by hand.
|
|
33
|
+
def ref
|
|
34
|
+
Pdfrb::Model::Reference.new(oid, gen)
|
|
35
|
+
end
|
|
36
|
+
|
|
30
37
|
# True when this object is referenced indirectly (oid > 0).
|
|
31
38
|
def indirect?
|
|
32
39
|
@oid > 0
|
|
@@ -23,7 +23,7 @@ module Pdfrb
|
|
|
23
23
|
ref = value[:Sound]
|
|
24
24
|
return nil unless ref && document
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
document.resolve(ref)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
# /Volume — optional, -1.0 to 1.0 (default 1.0).
|
|
@@ -52,7 +52,7 @@ module Pdfrb
|
|
|
52
52
|
ref = value[:Next]
|
|
53
53
|
return nil unless ref && document
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
document.resolve(ref)
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
end
|
|
@@ -16,7 +16,7 @@ module Pdfrb
|
|
|
16
16
|
ref = value[:Image]
|
|
17
17
|
return nil unless ref && document
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
document.resolve(ref)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
# /DefaultForPrinting — optional, default false. When true,
|
|
@@ -31,7 +31,7 @@ module Pdfrb
|
|
|
31
31
|
ref = value[:OC]
|
|
32
32
|
return nil unless ref && document
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
document.resolve(ref)
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
end
|
|
@@ -19,7 +19,7 @@ module Pdfrb
|
|
|
19
19
|
ref = value[:T]
|
|
20
20
|
return nil unless ref && document
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
document.resolve(ref)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
# /N — required indirect next Bead.
|
|
@@ -27,7 +27,7 @@ module Pdfrb
|
|
|
27
27
|
ref = value[:N]
|
|
28
28
|
return nil unless ref && document
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
document.resolve(ref)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
# /V — required indirect previous Bead.
|
|
@@ -35,7 +35,7 @@ module Pdfrb
|
|
|
35
35
|
ref = value[:V]
|
|
36
36
|
return nil unless ref && document
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
document.resolve(ref)
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
# /P — required indirect Page the bead sits on.
|
|
@@ -43,7 +43,7 @@ module Pdfrb
|
|
|
43
43
|
ref = value[:P]
|
|
44
44
|
return nil unless ref && document
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
document.resolve(ref)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
# /R — required rectangle on the page.
|
|
@@ -123,7 +123,7 @@ module Pdfrb
|
|
|
123
123
|
return unless arr.is_a?(Array) || arr.is_a?(Pdfrb::Model::PdfArray)
|
|
124
124
|
|
|
125
125
|
arr.each do |entry|
|
|
126
|
-
obj =
|
|
126
|
+
obj = document.resolve(entry)
|
|
127
127
|
yield obj if obj
|
|
128
128
|
end
|
|
129
129
|
end
|
|
@@ -168,49 +168,23 @@ module Pdfrb
|
|
|
168
168
|
# defaults /DefaultGray, /DefaultRGB, /DefaultCMYK.
|
|
169
169
|
class ColorSpaceMap < Pdfrb::Model::Cos::Dictionary
|
|
170
170
|
arlington_object "ColorSpaceMap"
|
|
171
|
-
|
|
172
|
-
def [](name)
|
|
173
|
-
value[name.to_sym] || value[name.to_s]
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def add(name, color_space)
|
|
177
|
-
value[name.to_sym] = color_space
|
|
178
|
-
name.to_sym
|
|
179
|
-
end
|
|
171
|
+
include NameMap
|
|
180
172
|
|
|
181
173
|
def default_gray; self[:DefaultGray]; end
|
|
182
174
|
def default_rgb; self[:DefaultRGB]; end
|
|
183
175
|
def default_cmyk; self[:DefaultCMYK]; end
|
|
184
176
|
|
|
185
|
-
|
|
186
|
-
return enum_for(:each_color_space) unless block_given?
|
|
187
|
-
|
|
188
|
-
value.each(&)
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
def names
|
|
192
|
-
value.keys
|
|
193
|
-
end
|
|
177
|
+
alias each_color_space each_entry
|
|
194
178
|
end
|
|
195
179
|
|
|
196
180
|
# Colorants dictionary (s8.6.6.5, DeviceN /Colorants). Maps
|
|
197
181
|
# individual colorant names to Separation spaces.
|
|
198
182
|
class ColorantsDict < Pdfrb::Model::Cos::Dictionary
|
|
199
183
|
arlington_object "ColorantsDict"
|
|
184
|
+
include NameMap
|
|
200
185
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
def each_colorant(&)
|
|
206
|
-
return enum_for(:each_colorant) unless block_given?
|
|
207
|
-
|
|
208
|
-
value.each(&)
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
def colorant_names
|
|
212
|
-
value.keys
|
|
213
|
-
end
|
|
186
|
+
alias each_colorant each_entry
|
|
187
|
+
alias colorant_names names
|
|
214
188
|
end
|
|
215
189
|
|
|
216
190
|
# Box style dictionary (s7.11.4, BoxColorInfo entries). Guides
|
|
@@ -29,9 +29,9 @@ module Pdfrb
|
|
|
29
29
|
# names to the default CryptFilter used.
|
|
30
30
|
class CryptFilterMap < Pdfrb::Model::Cos::Dictionary
|
|
31
31
|
arlington_object "CryptFilterMap"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
include NameMap
|
|
33
|
+
|
|
34
|
+
alias filter_for []
|
|
35
35
|
|
|
36
36
|
def each_filter(&)
|
|
37
37
|
return enum_for(:each_filter) unless block_given?
|
|
@@ -53,9 +53,9 @@ module Pdfrb
|
|
|
53
53
|
# public-key crypt filters.
|
|
54
54
|
class CryptFilterPublicKeyMap < Pdfrb::Model::Cos::Dictionary
|
|
55
55
|
arlington_object "CryptFilterPublicKeyMap"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
include NameMap
|
|
57
|
+
|
|
58
|
+
alias filter_for []
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
end
|
|
@@ -21,7 +21,7 @@ module Pdfrb
|
|
|
21
21
|
ref = value[:DPartRootNode]
|
|
22
22
|
return nil unless ref && document
|
|
23
23
|
|
|
24
|
-
resolved =
|
|
24
|
+
resolved = document.resolve(ref)
|
|
25
25
|
return nil unless resolved && resolved.value.is_a?(::Hash)
|
|
26
26
|
|
|
27
27
|
DPart.new(resolved.value)
|
|
@@ -57,7 +57,7 @@ module Pdfrb
|
|
|
57
57
|
ref = value[:Parent]
|
|
58
58
|
return nil unless ref && document
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
document.resolve(ref)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
# /DParts — array of arrays of child DParts. Mutually
|
|
@@ -71,7 +71,7 @@ module Pdfrb
|
|
|
71
71
|
ref = value[:Start]
|
|
72
72
|
return nil unless ref && document
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
document.resolve(ref)
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
# /End — indirect ref to the last Page in this part.
|
|
@@ -79,7 +79,7 @@ module Pdfrb
|
|
|
79
79
|
ref = value[:End]
|
|
80
80
|
return nil unless ref && document
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
document.resolve(ref)
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
def leaf?
|
|
@@ -111,25 +111,9 @@ module Pdfrb
|
|
|
111
111
|
# map living on the (page or) catalog.
|
|
112
112
|
class DestsMap < Pdfrb::Model::Cos::Dictionary
|
|
113
113
|
arlington_object "DestsMap"
|
|
114
|
+
include NameMap
|
|
114
115
|
|
|
115
|
-
|
|
116
|
-
value[name.to_sym] || value[name.to_s]
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
def add(name, destination)
|
|
120
|
-
value[name.to_sym] = destination
|
|
121
|
-
name.to_sym
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def each_destination(&)
|
|
125
|
-
return enum_for(:each_destination) unless block_given?
|
|
126
|
-
|
|
127
|
-
value.each(&)
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def names
|
|
131
|
-
value.keys
|
|
132
|
-
end
|
|
116
|
+
alias each_destination each_entry
|
|
133
117
|
end
|
|
134
118
|
end
|
|
135
119
|
end
|
data/lib/pdfrb/model/type/dss.rb
CHANGED
|
@@ -73,7 +73,7 @@ module Pdfrb
|
|
|
73
73
|
|
|
74
74
|
arr = refs.is_a?(Pdfrb::Model::PdfArray) ? refs.value : refs
|
|
75
75
|
arr = [arr] unless arr.is_a?(::Array)
|
|
76
|
-
arr.filter_map { |r|
|
|
76
|
+
arr.filter_map { |r| document.resolve(r) }
|
|
77
77
|
end
|
|
78
78
|
end
|
|
79
79
|
end
|
|
@@ -39,19 +39,10 @@ module Pdfrb
|
|
|
39
39
|
# Tiling pattern's Resources.
|
|
40
40
|
class CharProcMap < Pdfrb::Model::Cos::Dictionary
|
|
41
41
|
arlington_object "CharProcMap"
|
|
42
|
-
|
|
43
|
-
value.each
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def each_procedure(&block)
|
|
47
|
-
return enum_for(:each_procedure) unless block
|
|
42
|
+
include NameMap
|
|
48
43
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def procedure_for(char_name)
|
|
53
|
-
value[char_name.to_sym] || value[char_name.to_s]
|
|
54
|
-
end
|
|
44
|
+
alias each_procedure each_entry
|
|
45
|
+
alias procedure_for []
|
|
55
46
|
|
|
56
47
|
def has_glyph?(char_name)
|
|
57
48
|
!!procedure_for(char_name)
|
|
@@ -24,7 +24,7 @@ module Pdfrb
|
|
|
24
24
|
|
|
25
25
|
arr = sub_functions.is_a?(Pdfrb::Model::PdfArray) ? sub_functions.to_a : sub_functions
|
|
26
26
|
arr.each do |ref|
|
|
27
|
-
obj =
|
|
27
|
+
obj = document.resolve(ref)
|
|
28
28
|
yield obj if obj
|
|
29
29
|
end
|
|
30
30
|
end
|
|
@@ -208,14 +208,9 @@ module Pdfrb
|
|
|
208
208
|
# colorant name -> ink solidity percentage.
|
|
209
209
|
class Solidities < Pdfrb::Model::Cos::Dictionary
|
|
210
210
|
arlington_object "Solidities"
|
|
211
|
+
include NameMap
|
|
211
212
|
|
|
212
|
-
|
|
213
|
-
value[colorant.to_sym] || value[colorant.to_s]
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
def colorant_names
|
|
217
|
-
value.keys
|
|
218
|
-
end
|
|
213
|
+
alias colorant_names names
|
|
219
214
|
end
|
|
220
215
|
|
|
221
216
|
# Source information (s14.10.2, /SourceInfo): provenance for
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pdfrb
|
|
4
|
+
module Model
|
|
5
|
+
module Type
|
|
6
|
+
# Shared behaviour for name-keyed maps (Resources
|
|
7
|
+
# sub-dictionaries, role/class maps, VRI entries): lookup
|
|
8
|
+
# accepts Symbol or String, +add+ normalises the key to a
|
|
9
|
+
# Symbol, +names+ lists the keys.
|
|
10
|
+
module NameMap
|
|
11
|
+
def [](name)
|
|
12
|
+
key = name.to_sym
|
|
13
|
+
value.key?(key) ? value[key] : value[name.to_s]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def add(name, entry)
|
|
17
|
+
value[name.to_sym] = entry
|
|
18
|
+
name.to_sym
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def names
|
|
22
|
+
value.keys
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def each_entry(&)
|
|
26
|
+
return enum_for(:each_entry) unless block_given?
|
|
27
|
+
|
|
28
|
+
value.each(&)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|