sistema_progs

Programas para customizar o meu entorno de traballo nos meus equipos persoais
Log | Files | Refs

generate_font.py (6011B)


      1 #!/usr/bin/env python3
      2 
      3 import string
      4 import os
      5 import sys
      6 import json
      7 import fontforge
      8 import psMat
      9 
     10 PUA_START = 0xE000
     11 PUA_END = 0xF8FF
     12 FONT_EM = 1024
     13 POWERLINE_START = 0xE0A0
     14 POWERLINE_END = 0xE0D5
     15 
     16 def read_map_names(filename):
     17     array = []
     18     with open(filename) as file_map:
     19         lines = file_map.readlines()
     20         lines = [x.strip() for x in lines]
     21         for line in lines:
     22             if len(line) == 0:
     23                 continue
     24             tab = line.split()
     25             if tab[0][0] == '@':
     26                 array.append((tab[0][1:], ord(tab[1][0])))
     27             else:
     28                 array.append((tab[0], int(tab[1], 16)))
     29     return array
     30 
     31 def lookup_map_name(map_names, codepoint, fallback_name):
     32     for name, code in map_names:
     33         if code == codepoint:
     34             return name
     35     return fallback_name
     36 
     37 # Insert the powerline glyphs at the same place that all the patched powerline fonts to make
     38 # our font compatible with most of plugins/modules that insert those glyphs
     39 def insert_powerline_extra(dest):
     40     codepoint = POWERLINE_START
     41     font = fontforge.open("./fonts/PowerlineExtraSymbols.otf")
     42     font.em = FONT_EM
     43     map_names = read_map_names("./fonts/PowerlineExtraSymbols-map")
     44     excludes = [ 0xE0A4, 0xE0A5, 0xE0A6, 0xE0A7, 0xE0A8, 0xE0A9, 0xE0AA, 0xE0AB,
     45                  0xE0AC, 0xE0AD, 0xE0AE, 0xE0AF, 0xE0C9, 0xE0CB, 0xE0D3 ]
     46     inserted = []
     47 
     48     while codepoint < POWERLINE_END:
     49         if codepoint in excludes:
     50             codepoint += 1
     51             continue
     52         font.selection.select(codepoint)
     53         font.copy()
     54         dest.selection.select(codepoint)
     55         dest.paste()
     56         inserted.append(codepoint)
     57         codepoint += 1
     58     print("#powerline-extras:" + str(len(inserted)))
     59     for x in inserted:
     60         number = hex(x).replace("0x", "")
     61         name = lookup_map_name(map_names, x, number)
     62         print("powerline_" + name + ":" + number, end=';')
     63     print("")
     64 
     65 # Return true if the format of the name is something like 'uniXXXX' where X are
     66 # hexadecimals
     67 def is_default_name(name):
     68     if (len(name) != 7 or
     69         not name.startswith("uni") or
     70         not all(c in string.hexdigits for c in name[-4:])):
     71         return False
     72     return True
     73 
     74 # Name the glyph according to the font name
     75 def make_name(name, name_font):
     76     name = name.lower()
     77     if is_default_name(name):
     78         return name_font + "_" + name[-4:]
     79     return name_font + "_" + name.replace("-", "_")
     80 
     81 if len(sys.argv) < 2:
     82     print("Give me a config file", file=sys.stderr)
     83     sys.exit(1)
     84 
     85 with open(sys.argv[1]) as config_file:
     86     config_data = json.load(config_file)
     87 
     88     dest = fontforge.font()
     89     dest.em = FONT_EM
     90 #    dest.encoding = "UnicodeFull"
     91     dest.encoding = "ISO10646"
     92 
     93     insert_powerline_extra(dest)
     94 
     95     codepoint = PUA_START
     96 
     97     for json_file in config_data:
     98 
     99         font = fontforge.open(json_file["path"])
    100         font.em = FONT_EM
    101 
    102         excludes = []
    103         if "excludes" in json_file:
    104             excludes = list(map(lambda x : int(x, 16), json_file["excludes"]))
    105 
    106         start_from = 0
    107         if "start-from" in json_file:
    108             start_from = int(json_file["start-from"], 16)
    109 
    110         until = -1
    111         if "until" in json_file:
    112             until = int(json_file["until"], 16)
    113 
    114         move_vertically = 0
    115         if "move-vertically" in json_file:
    116             move_vertically = int(json_file["move-vertically"])
    117 
    118         name_font = json_file["name"]
    119         if "short-name" in json_file:
    120             name_font = json_file["short-name"]
    121         name_font = name_font.replace("-", "_")
    122 
    123         map_names = []
    124         if "map-names" in json_file:
    125             map_names = read_map_names(json_file["map-names"])
    126 
    127         start = codepoint
    128         inserted = []
    129 
    130         for symbol in font.glyphs("encoding"):
    131             if codepoint == POWERLINE_START:
    132                 codepoint = POWERLINE_END
    133             if (symbol.encoding in excludes or
    134                 symbol.encoding < start_from or
    135                 (until > 0 and symbol.encoding >= until)):
    136                 continue
    137             if symbol.width > 0 and symbol.unicode > 0:
    138                 encoding = symbol.encoding
    139                 name = symbol.glyphname
    140                 font.selection.select(encoding)
    141                 font.copy()
    142                 if encoding == 0x20:
    143                     dest.selection.select(0x20)
    144                     dest.paste()
    145                     continue
    146                 dest.selection.select(codepoint)
    147                 dest.paste()
    148                 dest.transform(psMat.translate(0, move_vertically))
    149                 if len(map_names) > 0:
    150                     name = lookup_map_name(map_names, encoding, name)
    151                 new_name = make_name(name, name_font)
    152                 dest.createMappedChar(codepoint).glyphname = new_name
    153                 inserted.append((new_name ,codepoint))
    154                 codepoint += 1
    155 
    156         print("#" + json_file["name"] + ":" + str(len(inserted)))
    157         for (name, x) in inserted:
    158             print(name + ":" + str(hex(x)).replace("0x", ""), end=';')
    159         print("")
    160 
    161     ascent = dest.ascent
    162     descent = dest.descent
    163 
    164     dest.os2_winascent_add = 0
    165     dest.os2_windescent_add = 0
    166     dest.os2_typoascent_add = 0
    167     dest.os2_typodescent_add = 0
    168     dest.hhea_ascent_add = 0
    169     dest.hhea_descent_add = 0
    170 
    171     # print ("ASCENT: " + str(ascent))
    172     # print ("DESCENT: " + str(descent))
    173 
    174     dest.os2_winascent = ascent
    175     dest.os2_windescent = descent
    176     dest.os2_typoascent = ascent
    177     dest.os2_typodescent = -descent
    178     dest.hhea_ascent = ascent
    179     dest.hhea_descent = -descent
    180 
    181     dest.em = FONT_EM
    182     dest.fontname = "icons-in-terminal"
    183     dest.familyname = "icons-in-terminal"
    184     dest.fullname = "icons-in-terminal"
    185     dest.appendSFNTName('English (US)', 'Preferred Family', dest.familyname)
    186     dest.appendSFNTName('English (US)', 'Compatible Full', dest.fullname)
    187     dest.fontname= "icons-in-terminal"
    188     dest.generate("icons-in-terminal.ttf")
    189     sys.exit(0)
    190 
    191 sys.exit(1)