Class: Pdfrb::Model::Cos::Dictionary
Overview
Common Object Syntax dictionary (s7.3.7). Wraps a Hash of
Symbol -> PDF value. Subclassed by every semantic Type::*.
Field metadata can come from two sources (mutually exclusive
per field; last declaration wins):
* `define_field`
Direct Known Subclasses
Stream, Type::AFEmbeddedFileParameter, Type::AFFileSpecEF, Type::Action, Type::ActionSound, Type::AddActionCatalog, Type::AddActionFormField, Type::AddActionPageObject, Type::AddActionScreenAnnotation, Type::AddActionWidgetAnnotation, Type::AlternateImage, Type::Annotation, Type::AnnotationProjectionDict, Type::Appearance, Type::AppearanceCharacteristics, Type::AppearancePrinterMarkDict, Type::AppearanceSubDict, Type::AppearanceTrapNet, Type::AppearanceTrapNetSubDict, Type::AppleSupplementalText, Type::AuthCode, Type::Bead, Type::BorderEffect, Type::BorderStyle, Type::BorderStyling, Type::BoxColorInfo, Type::BoxStyle, Type::CCITTFaxDecodeParms, Type::CIDFontDescriptorMetrics, Type::CIDSystemInfo, Type::CalGray, Type::CalRGB, Type::Catalog, Type::CertSeedValue, Type::CharProcMap, Type::ClassMap, Type::Collection, Type::CollectionColors, Type::CollectionField, Type::CollectionFolder, Type::CollectionItem, Type::CollectionSchema, Type::CollectionSort, Type::CollectionSplit, Type::CollectionSubitem, Type::ColorSpaceMap, Type::ColorantsDict, Type::CryptDecodeParms, Type::CryptFilter, Type::CryptFilterMap, Type::CryptFilterPublicKey, Type::CryptFilterPublicKeyMap, Type::DCTDecodeParms, Type::DPMMetadataStream, Type::DPart, Type::DPartRoot, Type::Data, Type::DestOutputProfile, Type::DestinationDict, Type::DestsMap, Type::DevExtensions, Type::DeviceN, Type::DeviceNMixingHints, Type::DeviceNProcess, Type::DictionaryOfDictionaries, Type::DictionaryOfFunctions, Type::DocMDPTransformParameters, Type::DocTimeStamp, Type::DocumentSecurityStore, Type::Dss, Type::EmbeddedFileParameter, Type::EncryptedPayload, Type::EncryptionPublicKey, Type::EncryptionStandard, Type::ExData3DMarkup, Type::ExDataMarkupGeo, Type::ExDataProjection, Type::Extensions, Type::FDDict, Type::Field, Type::FieldMDPTransformParameters, Type::FileSpecEF, Type::FileSpecRF, Type::FileSpecification, Type::FileTrailer, Type::FixedPrint, Type::FlateDecodeParms, Type::FloatingWindowParameters, Type::Font, Type::FontDescriptor, Type::FontEncoding, Type::Function, Type::GTSProcStepsGroup, Type::GeographicCoordinateSystem, Type::GeospatialMeasure, Type::GraphicsStateParameter, Type::GraphicsStateParameterMap, Type::GroupAttributes, Type::Halftone, Type::IconFit, Type::Info, Type::InteractiveForm, Type::InteriorColor, Type::JBIG2DecodeParms, Type::Lab, Type::LegalAttestation, Type::LineEndingStyling, Type::LinearizationParameterDict, Type::MDPDict, Type::Mac, Type::MarkInformation, Type::MarkedContentReference, Type::Measure, Type::MediaClipDataMHBE, Type::MediaClipSectionMHBE, Type::MediaCriteria, Type::MediaDuration, Type::MediaOffsetFrame, Type::MediaOffsetMarker, Type::MediaOffsetTime, Type::MediaPermissions, Type::MediaPlayParameters, Type::MediaPlayParametersMH, Type::MediaPlayerInfo, Type::MediaPlayers, Type::MediaScreenParameters, Type::MediaScreenParametersMHBE, Type::MicrosoftWindowsLaunchParam, Type::MinimumBitDepth, Type::MinimumScreenSize, Type::Movie, Type::MovieActivation, Type::Names, Type::Namespace, Type::NavNode, Type::Navigator, Type::NumberFormat, Type::OPIVersion13Dict, Type::OPIVersion20Dict, Type::ObjectReference, Type::OptContentCreatorInfo, Type::OptContentExport, Type::OptContentLanguage, Type::OptContentPageElement, Type::OptContentPrint, Type::OptContentUsage, Type::OptContentUsageApplication, Type::OptContentUser, Type::OptContentView, Type::OptContentZoom, Type::OptionalContentConfiguration, Type::OptionalContentGroup, Type::OptionalContentMembership, Type::OptionalContentProperties, Type::Outline, Type::OutlineItem, Type::OutputIntent, Type::OutputIntentsContainer, Type::Page, Type::PageLabel, Type::PagePieceInfo, Type::PageTreeNode, Type::PaperMetaData, Type::Pattern, Type::PatternMap, Type::Permissions, Type::PointData, Type::PrinterMarkSubDict, Type::ProjectedCoordinateSystem, Type::Projection, Type::Rendition, Type::RenditionBE, Type::RenditionMH, Type::RequirementsHandler, Type::Resources, Type::RichMediaActivation, Type::RichMediaAnimation, Type::RichMediaCommand, Type::RichMediaConfiguration, Type::RichMediaContent, Type::RichMediaCuePoint, Type::RichMediaDeactivation, Type::RichMediaHeight, Type::RichMediaInstance, Type::RichMediaParams, Type::RichMediaPosition, Type::RichMediaPresentation, Type::RichMediaSettings, Type::RichMediaWidth, Type::RichMediaWindow, Type::RoleMap, Type::RoleMapNS, Type::Separation, Type::Shading, Type::ShadingMap, Type::SigFieldLock, Type::SigFieldSeedValue, Type::Signature, Type::SignatureBuildDataAppDict, Type::SignatureBuildDataDict, Type::SignatureBuildDataSigQDict, Type::SignatureBuildPropDict, Type::SignatureReferenceDocMDP, Type::SignatureReferenceFieldMDP, Type::SignatureReferenceIdentity, Type::SignatureReferenceUR, Type::SlideShow, Type::SoftMaskAlpha, Type::SoftMaskLuminosity, Type::SoftwareIdentifier, Type::Solidities, Type::SourceInformation, Type::SpectralData, Type::StreamDict, Type::StructElem, Type::StructTreeRoot, Type::StructureAttributes, Type::StructureElementKid, Type::StructureReference, Type::StyleDict, Type::SubjectDN, Type::Target, Type::Thread, Type::ThreeDActivation, Type::ThreeDAnimationStyle, Type::ThreeDBackground, Type::ThreeDCrossSection, Type::ThreeDLightingScheme, Type::ThreeDMeasure, Type::ThreeDNode, Type::ThreeDReference, Type::ThreeDRenderMode, Type::ThreeDUnits, Type::ThreeDView, Type::ThreeDViewAddEntries, Type::TimeStampDict, Type::Timespan, Type::Transition, Type::TrapRegion, Type::URIDict, Type::URLAlias, Type::URTransformParameters, Type::UniversalDictionary, Type::UserProperty, Type::VRIMap, Type::ViewParams, Type::ViewerPreferences, Type::Viewport, Type::Vri, Type::WebCaptureCommand, Type::WebCaptureCommandSettings, Type::WebCaptureInfo, Type::XObjectMap
Instance Attribute Summary
Attributes inherited from Object
#document, #gen, #oid, #value
Class Method Summary
collapse
-
.apply_arlington_definition(definition) ⇒ Object
Merge the TSV's field definitions into the class's field set (ArlingtonBacked#arlington_object hook).
-
.arlington_default(field_def) ⇒ Object
-
.arlington_key_to_symbol(key) ⇒ Object
-
.arlington_one_type_to_ruby(t) ⇒ Object
-
.arlington_required?(field_def) ⇒ Boolean
-
.arlington_scalar(token) ⇒ Object
TSV default cells are raw strings; convert per scalar shape so typed access returns Integer/Symbol/etc.
-
.arlington_types_to_ruby(field_def) ⇒ Object
-
.arlington_version(field_def) ⇒ Object
-
.define_field(pdf_name, type:, required: false, default: nil, indirect: nil, allowed_values: nil, version: "1.0", arlington: nil) ⇒ Object
Declare a field on this class.
-
.define_field_from_arlington(field_def) ⇒ Object
Merge Arlington field metadata with any hand-coded define_field declaration.
-
.each_field ⇒ Object
Iterate (name, Field) pairs across the inheritance chain.
-
.field(name) ⇒ Object
Look up a field by name; walks the inheritance chain.
-
.lookup_type(symbol) ⇒ Object
-
.merged_field(existing, field_def) ⇒ Object
-
.own_fields ⇒ Object
-
.register_type(symbol, klass = self) ⇒ Object
-
.type_map ⇒ Object
/Type-symbol -> Dictionary subclass.
Instance Method Summary
collapse
arlington_object
Methods inherited from Object
#==, define_type, #deref, #indirect?, #must_be_indirect?, pdf_type, #ref
Constructor Details
#initialize(value = {}, oid: 0, gen: 0, document: nil) ⇒ Dictionary
204
205
206
207
208
209
210
211
212
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 204
def initialize(value = {}, oid: 0, gen: 0, document: nil)
value ||= {}
unless value.is_a?(::Hash)
raise ArgumentError, "Dictionary value must be a Hash, got #{value.class}"
end
super(value, oid: oid, gen: gen, document: document)
apply_required_defaults
end
|
Class Method Details
.apply_arlington_definition(definition) ⇒ Object
Merge the TSV's field definitions into the class's field
set (ArlingtonBacked#arlington_object hook).
78
79
80
81
82
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 78
def apply_arlington_definition(definition)
definition.each_field do |field_def|
define_field_from_arlington(field_def)
end
end
|
.arlington_default(field_def) ⇒ Object
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 168
def arlington_default(field_def)
raw = field_def.default_value
return nil if raw.nil?
return raw unless raw.is_a?(::String)
if raw.start_with?("[") && raw.end_with?("]")
return raw[1..-2].split.then { |tokens| tokens.map { |t| arlington_scalar(t) } }
end
scalar = arlington_scalar(raw)
return scalar.to_sym if scalar.is_a?(::String) && field_def.types_raw.include?("name")
scalar
end
|
.arlington_key_to_symbol(key) ⇒ Object
158
159
160
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 158
def arlington_key_to_symbol(key)
key.to_sym
end
|
.arlington_one_type_to_ruby(t) ⇒ Object
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 137
def arlington_one_type_to_ruby(t)
case t
when :boolean then [TrueClass, FalseClass]
when :integer then Integer
when :number then [Integer, Float]
when :name then Symbol
when :string, :"string-ascii", :"string-text" then String
when :"string-byte" then Fields::PDFByteString
when :array then Pdfrb::Model::PdfArray
when :dictionary then Pdfrb::Model::Cos::Dictionary
when :stream then Pdfrb::Model::Cos::Stream
when :null then NilClass
when :date then Fields::PDFDate
when :rectangle then Pdfrb::Model::Rectangle
when :matrix then Pdfrb::Model::Matrix
when :bitmask then Integer
when :"name-tree", :"number-tree" then Pdfrb::Model::Cos::Dictionary
end
end
|
.arlington_required?(field_def) ⇒ Boolean
163
164
165
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 163
def arlington_required?(field_def)
field_def.required_literal == true
end
|
.arlington_scalar(token) ⇒ Object
TSV default cells are raw strings; convert per scalar
shape so typed access returns Integer/Symbol/etc.
186
187
188
189
190
191
192
193
194
195
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 186
def arlington_scalar(token)
case token
when "true" then true
when "false" then false
when "null" then nil
when /\A-?\d+\z/ then Integer(token, 10)
when /\A-?\d+\.\d+\z/ then Float(token)
else token
end
end
|
.arlington_types_to_ruby(field_def) ⇒ Object
132
133
134
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 132
def arlington_types_to_ruby(field_def)
field_def.types.map { |t| arlington_one_type_to_ruby(t) }.flatten.compact.uniq
end
|
.arlington_version(field_def) ⇒ Object
198
199
200
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 198
def arlington_version(field_def)
field_def.since_version.to_s
end
|
.define_field(pdf_name, type:, required: false, default: nil, indirect: nil, allowed_values: nil, version: "1.0", arlington: nil) ⇒ Object
Declare a field on this class. Mirrors HexaPDF's
define_field shape; we add an arlington: slot for the
source FieldDefinition.
46
47
48
49
50
51
52
53
54
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 46
def define_field(pdf_name, type:, required: false, default: nil,
indirect: nil, allowed_values: nil, version: "1.0",
arlington: nil)
own_fields[pdf_name] = Fields::Field.new(
pdf_name, type: type, required: required, default: default,
indirect: indirect, allowed_values: allowed_values,
version: version, arlington: arlington
)
end
|
.define_field_from_arlington(field_def) ⇒ Object
Merge Arlington field metadata with any hand-coded
define_field declaration. Hand-coded fields win: if the
class already declares this key explicitly (with a type),
we rebuild the Field preserving the hand-coded
type/default/required and only attach the Arlington def
for reference.
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 96
def define_field_from_arlington(field_def)
types = arlington_types_to_ruby(field_def)
return if types.empty?
key = arlington_key_to_symbol(field_def.key)
existing = own_fields[key]
if existing
own_fields[key] = merged_field(existing, field_def)
return
end
define_field(
key,
type: types.length == 1 ? types.first : types,
required: arlington_required?(field_def),
default: arlington_default(field_def),
version: arlington_version(field_def),
arlington: field_def
)
end
|
.each_field ⇒ Object
Iterate (name, Field) pairs across the inheritance chain.
A subclass field with the same name shadows (replaces) the
inherited one entirely.
67
68
69
70
71
72
73
74
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 67
def each_field
return enum_for(:each_field) unless block_given?
if superclass <= Pdfrb::Model::Cos::Dictionary
superclass.each_field { |n, f| yield n, f unless own_fields.key?(n) }
end
own_fields.each { |n, f| yield n, f }
end
|
.field(name) ⇒ Object
Look up a field by name; walks the inheritance chain.
57
58
59
60
61
62
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 57
def field(name)
return own_fields[name] if own_fields.key?(name)
return superclass.field(name) if superclass <= Pdfrb::Model::Cos::Dictionary
nil
end
|
.lookup_type(symbol) ⇒ Object
39
40
41
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 39
def lookup_type(symbol)
TYPE_MAP[symbol]
end
|
.merged_field(existing, field_def) ⇒ Object
118
119
120
121
122
123
124
125
126
127
128
129
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 118
def merged_field(existing, field_def)
Fields::Field.new(
existing.pdf_name,
type: existing.type,
required: existing.required,
default: existing.default,
indirect: existing.indirect,
allowed_values: existing.allowed_values,
version: arlington_version(field_def),
arlington: field_def
)
end
|
.own_fields ⇒ Object
85
86
87
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 85
def own_fields
@own_fields ||= {}
end
|
.register_type(symbol, klass = self) ⇒ Object
34
35
36
37
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 34
def register_type(symbol, klass = self)
TYPE_MAP[symbol] = klass
klass.define_type(symbol) unless klass.pdf_type
end
|
/Type-symbol -> Dictionary subclass. Populated by
register_type. Used by Document#wrap to dispatch.
30
31
32
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 30
def type_map
TYPE_MAP
end
|
Instance Method Details
Typed access. Resolves References, wraps in field-specific
subclass, applies default, runs converters.
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 216
def [](name)
name = name.to_sym unless name.is_a?(::Symbol)
field = self.class.field(name)
data = @value[name]
data = field.default if data.nil? && field&.default?
return nil if data.nil?
data = dereference(data)
data = data.value if unbox_object?(data)
return data unless field
converted = Fields.apply(field, data, document)
if converted
@value[name] = converted
converted
else
data
end
end
|
#[]=(name, value) ⇒ Object
237
238
239
240
241
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 237
def []=(name, value)
raise ArgumentError, "Dictionary keys must be Symbols" unless name.is_a?(::Symbol)
@value[name] = value
end
|
#delete(name) ⇒ Object
248
249
250
251
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 248
def delete(name)
name = name.to_sym unless name.is_a?(::Symbol)
@value.delete(name)
end
|
Iterate (Symbol, processed-value) pairs. Slower than #each_raw
because it runs the full accessor pipeline; use that when
you don't need wrapping.
256
257
258
259
260
261
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 256
def each
return enum_for(:each) unless block_given?
@value.each_key { |k| yield(k, self[k]) }
self
end
|
Iterate (Symbol, raw-value) pairs without accessor pipeline.
264
265
266
267
268
269
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 264
def each_raw
return enum_for(:each_raw) unless block_given?
@value.each { |k, v| yield(k, v) }
self
end
|
#empty? ⇒ Boolean
272
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 272
def empty?; @value.empty?; end
|
#key?(name) ⇒ Boolean
243
244
245
246
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 243
def key?(name)
name = name.to_sym unless name.is_a?(::Symbol)
!@value[name].nil?
end
|
271
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 271
def keys; @value.keys; end
|
274
275
276
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 274
def pdf_type
self.class.pdf_type || self[:Type]
end
|
Walk every declared field and yield (message, correctable)
for each violation. Returns an Enumerator if no block given.
280
281
282
283
284
285
286
|
# File 'lib/pdfrb/model/cos/dictionary.rb', line 280
def validate
return enum_for(:validate) unless block_given?
self.class.each_field do |name, field|
validate_one(name, field) { |*a| yield(*a) }
end
end
|