import base64 import json import PIL.Image def create_zeroed_array(length): output=[] for _ in range(length): output.append(0) return output class Project: def __init__(self): self.chars={} self.char_res=(0,0) self.path=None self.export_path=None self.loaded=False self.modified=False def load(self,path): with open(path, "r") as f: project_data = json.load(f) if not "char_width" in project_data or not "char_height" in project_data: raise AttributeError("Character metrics information not found") if not isinstance(project_data["char_width"],int) or not isinstance(project_data["char_height"],int): raise AttributeError("Invalid character metrics type, expected int") if not "chars" in project_data: raise AttributeError("Character data not found") if not isinstance(project_data["chars"],dict): raise AttributeError("Invalid character data type, expected object") self.chars=project_data["chars"] self.char_res=(project_data["char_width"],project_data["char_height"]) self.path=path self.loaded=True def save(self,path): # save project data to file with open(path, "w") as f: json.dump({ "char_width": self.char_res[0], "char_height": self.char_res[1], "chars": self.chars }, f, indent=4) self.path=path self.loaded=True def export(self,path): chars = tuple(self.chars.items()) # there will be 256 characters per page last_char_idx = len(chars) - 1 page_res = (self.char_res[0] * 16,self.char_res[1] * 16) page = 0 page_char_x = 0 page_char_y = 0 for char_idx, char in enumerate(chars): if page_char_x == 0 and page_char_y == 0: page_arr = create_zeroed_array(page_res[0]*page_res[1]) char_map_string = "" char_bitmap=self.decode_char(char[0]) # put char_bitmap onto page_img at correct position for i in range(len(char_bitmap)): x=i//self.char_res[1]+page_char_x*self.char_res[0] y=i%self.char_res[1]+page_char_y*self.char_res[1] page_arr[y*page_res[0]+x]=char_bitmap[i] char_map_string += char[0] page_char_x += 1 if page_char_x == 16: page_char_x = 0 page_char_y += 1 if page_char_y == 16 or char_idx == last_char_idx: ## save page for x in range(len(page_arr)): page_arr[x]*=255 page_img = PIL.Image.frombytes("L",page_res,bytes(page_arr)) # save page page_img.save(f"{path}/page_{page}.png") # save char map with open(f"{path}/page_{page}.txt", "w", encoding="utf-8") as f: f.write(char_map_string) page += 1 page_char_y = 0 self.export_path=path def decode_char(self,char): result=[0 for _ in range(self.char_res[0]*self.char_res[1])] pixels=base64.b64decode(self.chars[char].encode("ascii")) pixel_index=0 for pixel in pixels: if pixel_index>=len(result): break for x in range(8): if pixel_index>=len(result): break result[pixel_index]=(pixel>>(7-x))&1 pixel_index+=1 return result def does_char_exist(self,c): return chr(c) in self.chars