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_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
-
#encrypted_binary ⇒ String
Get encrypted hex as binary data.
-
#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_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).
40 41 42 |
# File 'lib/fontisan/type1/pfa_parser.rb', line 40 def trailing_text @trailing_text end |
Class Method Details
.pfa_file?(data) ⇒ Boolean
Check if this appears to be a PFA file
114 115 116 117 118 119 120 121 |
# File 'lib/fontisan/type1/pfa_parser.rb', line 114 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
#encrypted_binary ⇒ String
Get encrypted hex as binary data
Decodes the hexadecimal encrypted portion to binary.
128 129 130 131 132 133 |
# File 'lib/fontisan/type1/pfa_parser.rb', line 128 def encrypted_binary return "" if @encrypted_hex.nil? || @encrypted_hex.empty? # Convert hex string to binary [@encrypted_hex.gsub(/\s/, "")].pack("H*") end |
#parse(data) ⇒ PFAParser
Parse PFA format data
48 49 50 51 52 53 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 |
# File 'lib/fontisan/type1/pfa_parser.rb', line 48 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 = "" @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 zero_index = encrypted_data.index(ZERO_MARKER) if zero_index.nil? raise Fontisan::Error, "Invalid PFA: cannot find zero marker after eexec" end # Extract encrypted hex data (before zeros) @encrypted_hex = encrypted_data[0...zero_index].strip # 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 self end |
#parsed? ⇒ Boolean
Check if parser has parsed data
101 102 103 |
# File 'lib/fontisan/type1/pfa_parser.rb', line 101 def parsed? !@clear_text.nil? end |