#!/usr/bin/python3 # convert X-GLCD font format to Peter Hinch font format # U. Raich 13.7.2020 # import sys, os from math import floor if len(sys.argv) != 6: print("usage: %s X-GLCD_filename fontWidth fontHeight startLetter letterCount"%sys.argv[0]) sys.exit(-1) width=int(sys.argv[2]) height=int(sys.argv[3]) start_letter=int(sys.argv[4]) letter_count=int(sys.argv[5]) bytes_per_letter = (floor((height - 1) / 8) + 1) * width + 1 bytes_per_row = (bytes_per_letter-1)//width #print("bytes per letter: ",bytes_per_letter) #print("bytes per row: ",bytes_per_row) letters = bytearray(((bytes_per_letter+1) +1)* (letter_count+1)) #print("size of letter array: ",len(letters)) indexTab = bytearray(2*(letter_count+1)+4) indexTab[0:1] = b'\0' mv = memoryview(letters) # print the file header print("#!/usr/bin/python3") print("""#WARNING: This Font Require X-GLCD Lib. # You can not use it with MikroE GLCD Lib. #Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 #MikroElektronika 2011 #http://www.mikroe.com #GLCD FontName : """,end="") fontType = os.path.splitext(sys.argv[1])[0]+'.c' print("%s"%fontType[0]) print("""#Based on a font created by Reekee of Dimenzioned - reekee@00.co.uk # GLCD FontSize : """,end="") print(width,"x",height) print(""" def height(): return """,end="") print(height) print("""def width(): return """,end="") print(width) print("""def hmap(): return True def reverse(): return False def monospaced(): return false def min_ch(): return """,end="") print(start_letter) print("""def max_ch(): return """,end="") print(start_letter + letter_count-1) print("\n") offset = 0 index=0 # # open the font file (C code) # linecount = 0x20 count = 0 with open(sys.argv[1], 'r',encoding = "ISO-8859-1") as f: for line in f: # Skip lines that do not start with hex values line = line.strip() if len(line) == 0 or line[0:2] != '0x': continue # Remove comments comment = line.find('//') if comment != -1: line = line[0:comment].strip() # Remove trailing commas if line.endswith(','): line = line[0:len(line) - 1] # Convert hex strings to bytearray and insert in to letters # The format from the font file is # 1 byte font width font_width pixel_data which can be bytes or shorts depending on glyph size # The Peter Hinch file format uses 2 bytes for width and I have to add a zero msb letter = bytearray(int(b, 16) for b in line.split(',')) #if chr(linecount) != '"' and chr(linecount) != "'": # print("Treating letter: ",chr(linecount)) #print("glyph length: ",letter[0]) #print("letter: ") #for i in range(len(letter)): # print("0x{:02x} ".format(letter[i]),end="") #print("") # add 1 row of letter spacing increasing the font width by 1 # print("table entry before writing: 0x{:02x}".format(mv[index])) ##print("index: ",index) mv[index]=letter[0] #letter width mv[index+1]=0 mv[index+2: index + bytes_per_row*letter[0]+2] = letter[1:bytes_per_row*letter[0]+1] #print("new letter:") #for i in range(bytes_per_row*letter[0]+2+bytes_per_row): # print("0x{:02x} ".format(mv[index+i]),end="") #print("") index += bytes_per_row*letter[0] + 2 # 2 for length #print("pos in index table: %d, next index: %d"%(count,index)) indexTab[2*count+2]=index & 0xff indexTab[2*count+3]=(index >> 8) & 0xff linecount += 1 count += 1 #print("_font: ") #for i in range(16): # print("0x{:02x} ".format(mv[i]),end=""); #print("") #for i in range(16): # print("0x{:02x} ".format(mv[16+i]),end=""); #print("") #for i in range(16): # print("0x{:02x} ".format(mv[32+i]),end=""); #print("") #print("_index: ") #for i in range(16): # print("0x{:02x} ".format(indexTab[i]),end=""); #print("") offset = 2 * ord('?') - 2*start_letter #print("offset(!)", offset) #print("indexTab(!): ",end="") #for i in range(4): # print(hex(indexTab[offset+i])," ",end="") #print("") startQ = indexTab[offset+1] << 8 | indexTab[offset] stopQ = indexTab[offset+3] << 8 | indexTab[offset+2] #print("start(!): ",hex(startQ)) #print("stop(!): ",hex(stopQ)) defaultCharSize=bytes_per_row*(mv[startQ] | (mv[startQ+1] << 8))+2 # start writing the font table with the default glyph print("_font = \\") print("b'",end="") for i in range(stopQ-startQ): print("\\x{:02x}".format(mv[startQ+i]),end="") print("'\\") #for i in range(stopQ-startQ): # print(hex(mv[startQ+i])," ",end="") #print("") noOfRows = mv[startQ] | (mv[startQ+1] << 8) #print("no of rows: ",noOfRows) #print("character rows:") #for i in range(noOfRows): # ch = mv[startQ+2*i+2] | (mv[startQ+2*i+3] << 8) # print("{:04x}".format(ch)) ##print("noOfRows: ", noOfRows) ''' for i in range(noOfRows): mask = 0x80 << (bytes_per_row-1)*8 #print("mask: ",hex(mask)) ch = mv[startQ+bytes_per_row*i+2] for j in range(bytes_per_row-1): ch |= (mv[startQ+2*i+3+j] << 8*(j+1)) #print("pixel row",hex(ch)) for k in range(8*bytes_per_row): if (mask & ch): print('x ',end="") else: print('. ',end="") mask >>=1 print("") ''' # print the font data for i in range(letter_count): index = indexTab[2*i] | (indexTab[2*i+1] << 8) #print("index: ",index) glyphSize = mv[index] | mv[index+1] << 8 #print("glyphSize :", glyphSize) print("b'",end="") for j in range(bytes_per_row*glyphSize+2): print("\\x{:02x}".format(mv[index+j]),end="") print("'\\") print("\n") #for i in range(len(indexTab)//2): # index = indexTab[2*i] | (indexTab[2*i+1] << 8) # print("0x{:04x} ".format(index)) #print("") sum = indexTab[2] | (indexTab[3] << 8) #print("tmp: ",tmp) indexTab[2] = defaultCharSize & 0xff indexTab[3] = (defaultCharSize >> 8) & 0xff # indexTab[0] = 0 # indexTab[2] = size ArcadePix9x11.pyof ? # indexTab[4] = indexTab[2] + size of ? #print("tmp({:d}): {:04x}".format(0,0)) #print("tmp({:d}): {:04x}".format(2,sum)) for i in range(len(indexTab)//2-4): sum += defaultCharSize #print("sum: ",sum) tmp = indexTab[4+2*i] | (indexTab[4+2*i+1] << 8) #print("tmp: ",tmp) #print("tmp({:d}): {:04x}".format(4+2*i,tmp)) indexTab[4+2*i] = sum & 0xff indexTab[4+2*i+1] = (sum >> 8) & 0xff sum = tmp indexTab[6+2*i] = sum & 0xff indexTab[6+2*i+1] = (sum >> 8) & 0xff #print("length of index table: ",len(indexTab)) print("_index = \\") # print the index table for i in range(len(indexTab)//16): print("b'",end="") for j in range(16): # print("index: ",16*i+j) print("\\x{:02x}".format(indexTab[16*i+j]),end="") print("'\\") print("b'",end="") #print("rest: ",len(indexTab)%16) for i in range(len(indexTab)%16): print("\\x{:02x}".format(indexTab[16*(len(indexTab)//16)+i]),end="") print("'") print(""" _mvfont = memoryview(_font) _mvi = memoryview(_index) ifb = lambda l : l[0] | (l[1] << 8) def get_ch(ch): oc = ord(ch) ioff = 2 * (oc - min_ch() + 1) if oc >= min_ch() and oc <= max_ch() else 0 doff = ifb(_mvi[ioff : ]) # print("ioff: %d, doff: %d"%(ioff,doff)) width = ifb(_mvfont[doff : ]) next_offs = doff + 2 + ((height() - 1)//8 + 1) * width # print("next_offs: ",next_offs) return _mvfont[doff + 2:next_offs], height(), width if __name__ == "__main__": pixels,height,width=get_ch('A') print("width: {:d} height: {:d}".format(width,height)) bytes_per_row = (height-1)//8 +1 print("bytes_per_row: ",bytes_per_row) for i in range(width): ch = pixels[bytes_per_row*i] for j in range(bytes_per_row-1): ch |= pixels[2*i+j+1] << 8*(j+1) print("{:x}".format(ch)) #print(hex(pixels[2*i])," ",hex(pixels[2*i+1]),end=" ") #print(hex(row)," ",end="") print("") for i in range(width): mask = 0x80 << (bytes_per_row-1)*8 ch = pixels[bytes_per_row*i] for j in range(bytes_per_row-1): ch |= pixels[bytes_per_row*i+j+1] << 8*(j+1) #print("pixel row",hex(ch)) for k in range(8*bytes_per_row): if (mask & ch): print('x ',end="") else: print('. ',end="") mask >>=1 print("") """) ''' for i in range(noOfRows): mask=0x8000 ch = mv[startQ+2*i+2] | (mv[startQ+2*i+3] << 8) for j in range(16): if (mask & ch): print('x ',end="") else: print('. ',end="") mask >>=1 print("") '''