Class: Fontisan::Type1::PFBParser

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/type1/pfb_parser.rb

Overview

Parser for PFB (Printer Font Binary) format

[‘PFBParser`](lib/fontisan/type1/pfb_parser.rb) parses the binary PFB format used for storing Adobe Type 1 fonts, primarily on Windows systems.

The PFB format consists of binary chunks marked with special codes:

  • 0x8001: ASCII text chunk

  • 0x8002: Binary data chunk (usually encrypted)

  • 0x8003: End of file marker

Each chunk (except EOF) has a 4-byte little-endian length prefix.

Examples:

Parse a PFB file

parser = Fontisan::Type1::PFBParser.new
result = parser.parse(File.binread('font.pfb'))
puts result.ascii_parts    # => ["%!PS-AdobeFont-1.0...", ...]
puts result.binary_parts   # => [encrypted_binary_data, ...]

See Also:

Constant Summary collapse

ASCII_CHUNK =

PFB chunk markers

0x8001
BINARY_CHUNK =
0x8002
EOF_CHUNK =
0x8003

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#ascii_partsArray<String> (readonly)

Returns ASCII text parts.

Returns:

  • (Array<String>)

    ASCII text parts



31
32
33
# File 'lib/fontisan/type1/pfb_parser.rb', line 31

def ascii_parts
  @ascii_parts
end

#binary_partsArray<String> (readonly)

Returns Binary data parts.

Returns:

  • (Array<String>)

    Binary data parts



34
35
36
# File 'lib/fontisan/type1/pfb_parser.rb', line 34

def binary_parts
  @binary_parts
end

Class Method Details

.pfb_file?(data) ⇒ Boolean

Check if this appears to be a PFB file

Examples:

Check if file is PFB format

if Fontisan::Type1::PFBParser.pfb_file?(data)
  # Handle PFB format
end

Parameters:

  • data (String)

    Binary data to check

Returns:

  • (Boolean)

    True if data starts with PFB marker



120
121
122
123
124
125
126
# File 'lib/fontisan/type1/pfb_parser.rb', line 120

def self.pfb_file?(data)
  return false if data.nil? || data.length < 2

  # PFB marker is big-endian (first byte is high byte)
  marker = (data.getbyte(0) << 8) | data.getbyte(1)
  [ASCII_CHUNK, BINARY_CHUNK].include?(marker)
end

Instance Method Details

#ascii_textString

Get all ASCII parts concatenated

Returns:

  • (String)

    All ASCII parts joined together



93
94
95
# File 'lib/fontisan/type1/pfb_parser.rb', line 93

def ascii_text
  @ascii_parts.join
end

#binary_dataString

Get all binary parts concatenated

Returns:

  • (String)

    All binary parts joined together



100
101
102
# File 'lib/fontisan/type1/pfb_parser.rb', line 100

def binary_data
  @binary_parts.join
end

#parse(data) ⇒ PFBParser

Parse PFB format data

Parameters:

  • data (String)

    Binary PFB data

Returns:

Raises:

  • (ArgumentError)

    If data is nil or empty

  • (Fontisan::Error)

    If PFB format is invalid



42
43
44
45
46
47
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
# File 'lib/fontisan/type1/pfb_parser.rb', line 42

def parse(data)
  raise ArgumentError, "Data cannot be nil" if data.nil?
  raise ArgumentError, "Data cannot be empty" if data.empty?

  @ascii_parts = []
  @binary_parts = []

  offset = 0
  chunk_index = 0

  while offset < data.length
    # Check for chunk marker (must have at least 2 bytes)
    if offset + 2 > data.length
      raise Fontisan::Error,
            "Invalid PFB: incomplete chunk header at offset #{offset}"
    end

    # Read chunk marker (big-endian)
    marker = (data.getbyte(offset) << 8) |
      data.getbyte(offset + 1)
    offset += 2

    case marker
    when ASCII_CHUNK
      chunk = read_chunk(data, offset, chunk_index, "ASCII")
      @ascii_parts << chunk[:data]
      offset = chunk[:next_offset]
      chunk_index += 1

    when BINARY_CHUNK
      chunk = read_chunk(data, offset, chunk_index, "binary")
      @binary_parts << chunk[:data]
      offset = chunk[:next_offset]
      chunk_index += 1

    when EOF_CHUNK
      # End of file - no more chunks
      break

    else
      raise Fontisan::Error,
            "Invalid PFB: unknown chunk marker 0x#{marker.to_s(16).upcase} at offset #{offset - 2}"
    end
  end

  self
end

#parsed?Boolean

Check if parser has parsed data

Returns:

  • (Boolean)

    True if data has been parsed



107
108
109
# File 'lib/fontisan/type1/pfb_parser.rb', line 107

def parsed?
  !@ascii_parts.nil? && !@binary_parts.nil?
end