From 277f742514e6837f05d66cc7e387470a8618c1c7 Mon Sep 17 00:00:00 2001 From: Vojtech Bocek Date: Thu, 8 May 2014 23:05:13 +0200 Subject: Add script to convert TrueTypeFonts to TWRP's .dat format Change-Id: I3d6cc65a83b7da9428adf37804cf9cbd0df99492 Signed-off-by: Vojtech Bocek --- prebuilt/twrp_fonts.py | 198 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100755 prebuilt/twrp_fonts.py (limited to 'prebuilt') diff --git a/prebuilt/twrp_fonts.py b/prebuilt/twrp_fonts.py new file mode 100755 index 000000000..439240978 --- /dev/null +++ b/prebuilt/twrp_fonts.py @@ -0,0 +1,198 @@ +#!/usr/bin/env python +# -*- coding: utf8 -*- +import codecs,os,gzip,ctypes,ctypes.util,sys +from struct import * +from PIL import Image, ImageDraw, ImageFont + +# ====== Python script to convert TrueTypeFonts to TWRP's .dat format ====== +# This script was originally made by https://github.com/suky for his chinese version of TWRP +# and then translated to English by feilplane at #twrp of irc.freenode.net. +# However, it was not compatible with vanilla TWRP, so https://github.com/Tasssadar rewrote +# most of it and it now has very little in common with the original script. + +class Reference(): + def __init__(self, val): + self.__value = val + + def get(self): + return self.__value + + def set(self, val): + self.__value = val + +quiet = Reference(False) + +def log(text): + if not quiet.get(): + sys.stdout.write(text) + +def write_data(f, width, height, offsets, data): + f.write(pack(" cheight: + cheight = h + ichr = Image.new('L', (w, cheight*2)) + ichr_draw = ImageDraw.Draw(ichr) + ichr_draw.text((padding.get(), 0), chr(i), 255, font) + renders.append(ichr) + + # Twice the height to account for under-the-baseline characters + cheight *= 2 + + # Create the result bitmap + log("Creating result bitmap...\n") + res = Image.new('L', (cwidth, cheight), 0) + res_draw = ImageDraw.Draw(res) + + # Paste all characters into result bitmap + for i in range(len(renders)): + res.paste(renders[i], (offsets[i], 0)) + # uncomment to draw lines separating each character (for debug) + #res_draw.rectangle([offsets[i], 0, offsets[i], cheight], outline="blue") + + # crop the blank areas on top and bottom + (_, start_y, _, end_y) = res.getbbox() + res = res.crop((0, start_y, cwidth, end_y)) + cheight = (end_y - start_y) + voffset.get() + new_res = Image.new('L', (cwidth, cheight)) + new_res.paste(res, (0, voffset.get())) + res = new_res + + # save the preview + if preview.get(): + log("Saving preview to %s...\n" % preview.get()) + res.save(preview.get()) + + # Pack the data. + # The "data" is a B/W bitmap with all 96 characters next to each other + # on one line. It is as wide as all the characters combined and as + # high as the tallest character, plus padding. + # Each byte contains info about eight pixels, starting from + # highest to lowest bit: + # bits: | 7 6 5 4 3 2 1 0 | 15 14 13 12 11 10 9 8 | ... + # pixels: | 0 1 2 3 4 5 6 7 | 8 9 10 11 12 13 14 15 | ... + log("Packing data...\n") + bit = 0 + bit_itr = 0 + for c in res.tostring(): + # FIXME: How to handle antialiasing? + # if c != '\x00': + # In Python3, c is int, in Python2, c is string. Because of reasons. + try: + fill = (ord(c) >= 127) + except TypeError: + fill = (c >= 127) + if fill: + bit |= (1 << (7-bit_itr)) + bit_itr += 1 + if bit_itr >= 8: + data += pack("