""" LucasArts Font parser. Author: Cyril Zorin Creation date: 1 January 2007 """ from hachoir.parser import Parser from hachoir.field import (FieldSet, UInt8, UInt16, UInt32, GenericVector) from hachoir.core.endian import LITTLE_ENDIAN class CharData(FieldSet): def __init__(self, chars, *args): FieldSet.__init__(self, *args) self.chars = chars def createFields(self): for char in self.chars: yield CharBitmap(char, self, "char_bitmap[]") class CharBitmap(FieldSet): def __init__(self, char, *args): FieldSet.__init__(self, *args) self.char = char def createFields(self): width = self.char["width_pixels"].value for line in range(self.char["height_pixels"].value): yield GenericVector(self, "line[]", width, UInt8, "pixel") class CharInfo(FieldSet): static_size = 16 * 8 def createFields(self): yield UInt32(self, "data_offset") yield UInt8(self, "logical_width") yield UInt8(self, "unknown[]") yield UInt8(self, "unknown[]") yield UInt8(self, "unknown[]") yield UInt32(self, "width_pixels") yield UInt32(self, "height_pixels") class LafFile(Parser): PARSER_TAGS = { "id": "lucasarts_font", "category": "game", "file_ext": ("laf",), "min_size": 32 * 8, "description": "LucasArts Font" } endian = LITTLE_ENDIAN def validate(self): if self["num_chars"].value != 256: return "Invalid number of characters (%u)" % self["num_chars"].value if self["first_char_code"].value != 0: return "Invalid of code of first character code (%u)" % self["first_char_code"].value if self["last_char_code"].value != 255: return "Invalid of code of last character code (%u)" % self["last_char_code"].value if self["char_codes/char[0]"].value != 0: return "Invalid character code #0 (%u)" % self["char_codes/char[0]"].value if self["chars/char[0]/data_offset"].value != 0: return "Invalid character #0 offset" return True def createFields(self): yield UInt32(self, "num_chars") yield UInt32(self, "raw_font_data_size") yield UInt32(self, "max_char_width") yield UInt32(self, "min_char_width") yield UInt32(self, "unknown[]", 4) yield UInt32(self, "unknown[]", 4) yield UInt32(self, "first_char_code") yield UInt32(self, "last_char_code") yield GenericVector(self, "char_codes", self["num_chars"].value, UInt16, "char") yield GenericVector(self, "chars", self["num_chars"].value, CharInfo, "char") # character data. we make an effort to provide # something more meaningful than "RawBytes: # character bitmap data" yield CharData(self["chars"], self, "char_data") # read to the end if self.current_size < self._size: yield self.seekBit(self._size, "unknown[]")