Class: Fontisan::Type1::PFAParser
- Inherits:
-
Object
- Object
- Fontisan::Type1::PFAParser
- Defined in:
- lib/fontisan/type1/pfa_parser.rb
Overview
Parser for PFA (Printer Font ASCII) format
[‘PFAparser`](lib/fontisan/type1/pfa_parser.rb) parses the ASCII PFA format used for storing Adobe Type 1 fonts, primarily on Unix/Linux systems.
The PFA format is pure ASCII text with encrypted portions marked by ‘currentfile eexec` and terminated by 512 ASCII zeros.
Format structure:
-
Clear text: Font dictionary and initial data
-
Encrypted portion: Starts with ‘currentfile eexec`
-
Encrypted data: Binary data encoded as hexadecimal
-
End marker: 512 ASCII zeros (‘0’)
-
Cleartext again: Font dictionary closing
Constant Summary collapse
- EEXEC_MARKER =
Markers in PFA format
"currentfile eexec"- ZERO_MARKER =
512 ASCII zeros mark the end of encrypted portion
"0" * 512
Instance Attribute Summary collapse
-
#clear_text ⇒ String
readonly
Clear text portion (before eexec).
-
#encrypted_binary ⇒ String
readonly
Encrypted portion as binary data.
-
#encrypted_hex ⇒ String
readonly
Encrypted portion as hex string.
-
#trailing_text ⇒ String
readonly
Trailing text after zeros (if any).
Class Method Summary collapse
-
.pfa_file?(data) ⇒ Boolean
Check if this appears to be a PFA file.
Instance Method Summary collapse
-
#parse(data) ⇒ PFAParser
Parse PFA format data.
-
#parsed? ⇒ Boolean
Check if parser has parsed data.
Instance Attribute Details
#clear_text ⇒ String (readonly)
Returns Clear text portion (before eexec).
34 35 36 |
# File 'lib/fontisan/type1/pfa_parser.rb', line 34 def clear_text @clear_text end |
#encrypted_binary ⇒ String (readonly)
Returns Encrypted portion as binary data.
40 41 42 |
# File 'lib/fontisan/type1/pfa_parser.rb', line 40 def encrypted_binary @encrypted_binary end |
#encrypted_hex ⇒ String (readonly)
Returns Encrypted portion as hex string.
37 38 39 |
# File 'lib/fontisan/type1/pfa_parser.rb', line 37 def encrypted_hex @encrypted_hex end |
#trailing_text ⇒ String (readonly)
Returns Trailing text after zeros (if any).
43 44 45 |
# File 'lib/fontisan/type1/pfa_parser.rb', line 43 def trailing_text @trailing_text end |
Class Method Details
.pfa_file?(data) ⇒ Boolean
Check if this appears to be a PFA file
127 128 129 130 131 132 133 134 |
# File 'lib/fontisan/type1/pfa_parser.rb', line 127 def self.pfa_file?(data) return false if data.nil? return false if data.length < 15 # Check for Adobe Type 1 font header data.include?("%!PS-AdobeFont-1.0") || data.include?("%!PS-Adobe-3.0 Resource-Font") end |
Instance Method Details
#parse(data) ⇒ PFAParser
Parse PFA format data
Handles both standard PFA (hex-encoded encrypted data with zero marker) and .t1 format (binary encrypted data without zero marker).
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/fontisan/type1/pfa_parser.rb', line 54 def parse(data) raise ArgumentError, "Data cannot be nil" if data.nil? raise ArgumentError, "Data cannot be empty" if data.empty? # Normalize line endings data = normalize_line_endings(data) # Find eexec marker eexec_index = data.index(EEXEC_MARKER) if eexec_index.nil? # No eexec marker - entire file is clear text @clear_text = data @encrypted_hex = "" @encrypted_binary = "" @trailing_text = "" return self end # Clear text is everything before and including eexec marker @clear_text = data[0...eexec_index + EEXEC_MARKER.length] # Look for zeros after eexec marker after_eexec = data[eexec_index + EEXEC_MARKER.length..] # Skip whitespace after eexec marker encrypted_start = skip_whitespace(after_eexec, 0) encrypted_data = after_eexec[encrypted_start..] # Find zero marker (optional for .t1 format) zero_index = encrypted_data.index(ZERO_MARKER) if zero_index # Standard PFA format with zero marker # Extract encrypted hex data (before zeros) @encrypted_hex = encrypted_data[0...zero_index].strip @encrypted_binary = [@encrypted_hex.gsub(/\s/, "")].pack("H*") # Extract trailing text (after zeros) trailing_start = zero_index + ZERO_MARKER.length trailing_start = skip_whitespace(encrypted_data, trailing_start) @trailing_text = if trailing_start < encrypted_data.length encrypted_data[trailing_start..] else "" end else # .t1 format - binary encrypted data without zero marker # Treat everything after eexec as binary encrypted data @encrypted_binary = encrypted_data.lstrip @encrypted_hex = @encrypted_binary.unpack1("H*") @trailing_text = "" end self end |
#parsed? ⇒ Boolean
Check if parser has parsed data
114 115 116 |
# File 'lib/fontisan/type1/pfa_parser.rb', line 114 def parsed? !@clear_text.nil? end |