Skip to content

Instantly share code, notes, and snippets.

@ksherlock
Created October 11, 2018 23:17
Show Gist options
  • Save ksherlock/c4dedae279e3c2f17a67e6c17120595b to your computer and use it in GitHub Desktop.
Save ksherlock/c4dedae279e3c2f17a67e6c17120595b to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby -w
def to_b(x, width = 16)
tmp = x.to_s(2)
tmp = ("0" * (width - tmp.length)) + tmp
tmp.tr!('01',' #')
tmp
end
def extract_bits(location, count)
rv = []
@bitmap.each {|line|
tmp = ""
count.times {|i|
loc = location + i
byte = line[loc / 8]
loc &= 0x07
bit = byte & (1 << (7-loc))
tmp += bit == 0 ? ' ' : '#'
}
rv.push(tmp)
}
return rv
end
def print_char(c)
return if c < @mac.firstChar || c > @mac.lastChar
c -= @mac.firstChar
x = @owTable[c];
return if x == 0xffff
width = x & 0xff
offset = x >> 8
location = @locTable[c]
bits = @locTable[c+1] - location
tmp = extract_bits(location, bits)
# puts "image width: #{bits}"
# puts "location: #{location}"
printf "%c\n", c + @mac.firstChar
tmp.each {|xx| puts xx }
end
Signal.trap("PIPE", "EXIT")
Struct.new('Header', :offsetToMF, :family, :style, :size, :version, :fbrExtent)
Struct.new('Macintosh', :fontType, :firstChar, :lastChar, :widthMax, :kernMax, :nDescent, :fRectWidth, :fRectHeight,
:owTLoc, :ascent, :descent, :leading, :rowWords)
fontfile = "APPLE.M.08"
#fontfile = "Geneva.9"
#fontfile = "3.2/SHASTON.16"
fontfile = ARGV[0] if ARGV.size == 1
data = IO.read(fontfile, {:encoding => "BINARY"})
# C = uint8_t
# v = uint16_t (little endian)
# V = uint32_t (little endian)
# pascal string, followed by actual font data.
offset = data[0].ord
family = data[1,offset]
offset = offset + 1
tmp = data.unpack("x#{offset}vvvvvv")
header = Struct::Header.new(*tmp)
header.offsetToMF *= 2
extra = data[offset + 12..header.offsetToMF]
highOwTLoc = 0
if header.version == 0x0105 and extra.length >= 2 then
highOwTLoc = unpack(extra, "v").first
end
puts " Family: #{family}"
header.each_pair {|name, value| printf("%-12s: %04x\n", name, value) }
offset = offset + header.offsetToMF
tmp = data.unpack("x#{offset}vvvvvvvvvvvvv")
@mac = mac = Struct::Macintosh.new(*tmp)
mac.rowWords *= 2
# make relative to file
mac.owTLoc += highOwTLoc * 16
mac.owTLoc *= 2
mac.owTLoc += offset + 16
puts
mac.each_pair {|name, value| printf("%-12s: %04x\n", name, value) }
offset = offset + 13 * 2
# x bytes of font data (1..rowWords, 1 .. fRectHeight)
# x bytes of location table (firstChar...lastChar + 2)
# x bytes of offset/width table (firstChar...lastChar + 2)
tmp = (mac.lastChar - mac.firstChar + 3) * 2
owTable = data[mac.owTLoc, tmp]
locTable = data[mac.owTLoc - tmp, tmp]
puts "Location Table:"
@locTable = locTable.unpack("v*")
# puts @locTable.length
# @locTable.each{|x| printf "%04x\n", x}
puts "Offset/Width Table:"
@owTable = owTable.unpack("v*")
# puts @owTable.length
# @owTable.each{|x| printf "%04x\n", x}
#puts "Bitmap Image:"
bitImage = data[offset, mac.rowWords * mac.fRectHeight]
tmp = bitImage.unpack('C*')
@bitmap = []
tmp.each_slice(mac.rowWords) {|xx| @bitmap.push(xx) }
# @bitmap.each {|line|
# line.first(20).each{|x| printf to_b(x,8) }
# puts
# }
# let's try an A...
(@mac.firstChar ... @mac.lastChar).each {|i| print_char(i) }
exit
char = 65 - mac.firstChar
printf "offset: %04x\n", owTable[char]
printf "location: %04x\n", locTable[char]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment