<s> from fontTools . ttLib import TTFont <EOL> from fontTools import cffLib <EOL> from fontTools . misc import psCharStrings <EOL> from fontTools . pens import basePen <EOL> import matplotlib . pyplot as plt <EOL> import functools <EOL> import itertools <EOL> import os <EOL> import argparse <EOL> """<STR_LIT>""" <EOL> SINGLE_BYTE_OPS = set ( [ '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' ] ) <EOL> def tokenCost ( token ) : <EOL> """<STR_LIT>""" <EOL> tp = type ( token ) <EOL> if issubclass ( tp , basestring ) : <EOL> if token [ : <NUM_LIT:8> ] in ( "<STR_LIT>" , "<STR_LIT>" ) : <EOL> return <NUM_LIT:1> + len ( token [ <NUM_LIT:9> : ] ) <EOL> elif token in SINGLE_BYTE_OPS : <EOL> return <NUM_LIT:1> <EOL> else : <EOL> return <NUM_LIT:2> <EOL> elif tp == tuple : <EOL> assert token [ <NUM_LIT:0> ] in ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> return <NUM_LIT:1> + len ( token [ <NUM_LIT:1> ] ) <EOL> elif tp == int : <EOL> if - <NUM_LIT> <= token <= <NUM_LIT> : <EOL> return <NUM_LIT:1> <EOL> elif <NUM_LIT> <= token <= <NUM_LIT> or - <NUM_LIT> <= token <= - <NUM_LIT> : <EOL> return <NUM_LIT:2> <EOL> else : <EOL> return <NUM_LIT:3> <EOL> elif tp == float : <EOL> return <NUM_LIT:5> <EOL> assert <NUM_LIT:0> <EOL> def get_cff ( filename ) : <EOL> if os . path . splitext ( filename ) [ <NUM_LIT:1> ] == '<STR_LIT>' : <EOL> res = cffLib . CFFFontSet ( ) <EOL> res . decompile ( open ( filename ) , None ) <EOL> return res <EOL> else : <EOL> return TTFont ( filename ) [ '<STR_LIT>' ] . cff <EOL> def get_cs_bytes ( td , fds ) : <EOL> count = <NUM_LIT:0> <EOL> for cs in td . GlobalSubrs : <EOL> count += len ( cs . bytecode ) <EOL> for fd in fds : <EOL> try : <EOL> for cs in fd . Private . Subrs : <EOL> count += len ( cs . bytecode ) <EOL> except AttributeError : <EOL> pass <EOL> for cs in td . CharStrings . values ( ) : <EOL> count += len ( cs . bytecode ) <EOL> return count <EOL> def print_n_subroutines ( name , td , fds ) : <EOL> print ( "<STR_LIT>" % ( name , len ( td . GlobalSubrs ) ) ) <EOL> for i , fd in enumerate ( fds ) : <EOL> try : <EOL> x = len ( fd . Private . Subrs ) <EOL> except AttributeError : <EOL> x = <NUM_LIT:0> <EOL> print ( "<STR_LIT>" % ( i , x ) ) <EOL> def get_savings ( td , fds ) : <EOL> gsavings = [ - ( s . subr_cost + <NUM_LIT:2> ) if s . program else <NUM_LIT:0> for s in td . GlobalSubrs ] <EOL> lsavings = [ [ - ( s . subr_cost + <NUM_LIT:2> ) if s . program else <NUM_LIT:0> for s in fd . Private . Subrs ] for fd in fds ] <EOL> gusages = [ <NUM_LIT:0> for _ in td . GlobalSubrs ] <EOL> lusages = [ [ <NUM_LIT:0> for _ in fd . Private . Subrs ] for fd in fds ] <EOL> gbias = psCharStrings . calcSubrBias ( td . GlobalSubrs ) <EOL> lbias = map ( lambda fd : psCharStrings . calcSubrBias ( fd . Private . Subrs ) <EOL> if hasattr ( fd . Private , '<STR_LIT>' ) else <NUM_LIT:0> , <EOL> fds ) <EOL> def count_subr ( idx , is_global , fdidx = - <NUM_LIT:1> ) : <EOL> if is_global : <EOL> gsavings [ idx + gbias ] += ( td . GlobalSubrs [ idx + gbias ] . subr_saving - tokenCost ( idx ) - <NUM_LIT:1> ) <EOL> gusages [ idx + gbias ] += <NUM_LIT:1> <EOL> subr = td . GlobalSubrs [ idx + gbias ] <EOL> else : <EOL> assert fdidx >= <NUM_LIT:0> <EOL> lsavings [ fdidx ] [ idx + lbias [ fdidx ] ] += ( fds [ fdidx ] . Private . Subrs [ idx + lbias [ fdidx ] ] . subr_saving - tokenCost ( idx ) - <NUM_LIT:1> ) <EOL> lusages [ fdidx ] [ idx + lbias [ fdidx ] ] += <NUM_LIT:1> <EOL> subr = fds [ fdidx ] . Private . Subrs [ idx + lbias [ fdidx ] ] <EOL> for before , tok in zip ( subr . program , subr . program [ <NUM_LIT:1> : ] ) : <EOL> if tok == '<STR_LIT>' : <EOL> count_subr ( before , True , fdidx ) <EOL> elif tok == '<STR_LIT>' : <EOL> count_subr ( before , False , fdidx ) <EOL> for g in td . charset : <EOL> cs , sel = td . CharStrings . getItemAndSelector ( g ) <EOL> for before , tok in zip ( cs . program , cs . program [ <NUM_LIT:1> : ] ) : <EOL> if tok == '<STR_LIT>' : <EOL> count_subr ( before , True , sel ) <EOL> elif tok == '<STR_LIT>' : <EOL> count_subr ( before , False , sel ) <EOL> return ( ( gsavings , lsavings ) , ( gusages , lusages ) ) <EOL> def decompile_charstrings ( td , fds ) : <EOL> for cs in td . GlobalSubrs : <EOL> cs . subr_cost = cs . subr_saving = len ( cs . bytecode ) <EOL> for fd in fds : <EOL> try : <EOL> for cs in fd . Private . Subrs : <EOL> cs . subr_cost = cs . subr_saving = len ( cs . bytecode ) <EOL> except AttributeError : <EOL> pass <EOL> for g in td . charset : <EOL> cs , sel = td . CharStrings . getItemAndSelector ( g ) <EOL> cs . decompile ( ) <EOL> for cs in td . GlobalSubrs : <EOL> if cs . program and cs . program [ - <NUM_LIT:1> ] == '<STR_LIT>' : <EOL> cs . subr_saving -= <NUM_LIT:1> <EOL> for fd in fds : <EOL> try : <EOL> for cs in fd . Private . Subrs : <EOL> if cs . program and cs . program [ - <NUM_LIT:1> ] == '<STR_LIT>' : <EOL> cs . subr_saving -= <NUM_LIT:1> <EOL> except AttributeError : <EOL> pass <EOL> def get_raw_usages ( td , fds ) : <EOL> gusages = [ <NUM_LIT:0> for _ in td . GlobalSubrs ] <EOL> lusages = [ [ <NUM_LIT:0> for _ in fd . Private . Subrs ] for fd in fds ] <EOL> gbias = psCharStrings . calcSubrBias ( td . GlobalSubrs ) <EOL> lbias = map ( lambda fd : psCharStrings . calcSubrBias ( fd . Private . Subrs ) <EOL> if hasattr ( fd . Private , '<STR_LIT>' ) else <NUM_LIT:0> , <EOL> fds ) <EOL> gsels = [ None for _ in td . GlobalSubrs ] <EOL> for g in td . charset : <EOL> cs , sel = td . CharStrings . getItemAndSelector ( g ) <EOL> for before , tok in zip ( cs . program , cs . program [ <NUM_LIT:1> : ] ) : <EOL> if tok == '<STR_LIT>' : <EOL> gusages [ before + gbias ] += <NUM_LIT:1> <EOL> gsels [ before + gbias ] = sel <EOL> elif tok == '<STR_LIT>' : <EOL> lusages [ sel ] [ before + lbias [ sel ] ] += <NUM_LIT:1> <EOL> for cs , sel in zip ( td . GlobalSubrs , gsels ) : <EOL> for before , tok in zip ( cs . program , cs . program [ <NUM_LIT:1> : ] ) : <EOL> if tok == '<STR_LIT>' : <EOL> gusages [ before + gbias ] += <NUM_LIT:1> <EOL> elif tok == '<STR_LIT>' : <EOL> lusages [ sel ] [ before + lbias [ sel ] ] += <NUM_LIT:1> <EOL> for sel , fd in enumerate ( fds ) : <EOL> if hasattr ( fd . Private , '<STR_LIT>' ) : <EOL> for cs in fd . Private . Subrs : <EOL> for before , tok in zip ( cs . program , cs . program [ <NUM_LIT:1> : ] ) : <EOL> if tok == '<STR_LIT>' : <EOL> gusages [ before + gbias ] += <NUM_LIT:1> <EOL> elif tok == '<STR_LIT>' : <EOL> lusages [ sel ] [ before + lbias [ sel ] ] += <NUM_LIT:1> <EOL> return ( gusages , lusages ) <EOL> def main ( filenames , show_graphs ) : <EOL> names = map ( os . path . basename , filenames ) <EOL> cffs = map ( get_cff , filenames ) <EOL> tds = map ( lambda f : f . topDictIndex [ <NUM_LIT:0> ] , cffs ) <EOL> fds = map ( lambda td : td . FDArray if hasattr ( td , '<STR_LIT>' ) else [ ] , tds ) <EOL> n_bytes = map ( get_cs_bytes , tds , fds ) <EOL> for name , b in zip ( names , n_bytes ) : <EOL> print ( "<STR_LIT>" % ( name , b ) ) <EOL> map ( decompile_charstrings , tds , fds ) <EOL> map ( print_n_subroutines , names , tds , fds ) <EOL> sav_usag = map ( get_savings , tds , fds ) <EOL> for name , ( savings , usages ) in zip ( names , sav_usag ) : <EOL> tot_savings = savings [ <NUM_LIT:0> ] + list ( itertools . chain . from_iterable ( savings [ <NUM_LIT:1> ] ) ) <EOL> tot_usages = usages [ <NUM_LIT:0> ] + list ( itertools . chain . from_iterable ( usages [ <NUM_LIT:1> ] ) ) <EOL> avg = float ( sum ( tot_savings ) ) / len ( tot_savings ) <EOL> print ( "<STR_LIT>" % ( name , avg , max ( tot_savings ) , max ( tot_usages ) ) ) <EOL> if show_graphs : <EOL> SHOW_START = <NUM_LIT:0> <EOL> SHOW_LEN = <NUM_LIT:200> <EOL> mins = [ ] <EOL> maxes = [ ] <EOL> plt . figure ( <NUM_LIT:0> ) <EOL> for savings , usages in sav_usag : <EOL> tot_savings = savings [ <NUM_LIT:0> ] + list ( itertools . chain . from_iterable ( savings [ <NUM_LIT:1> ] ) ) <EOL> plot_savings = sorted ( tot_savings , reverse = True ) [ SHOW_START : SHOW_START + SHOW_LEN ] <EOL> plt . plot ( range ( len ( plot_savings ) ) , plot_savings ) <EOL> mins . append ( min ( plot_savings ) ) <EOL> maxes . append ( max ( plot_savings ) ) <EOL> plt . ylim ( [ min ( mins ) - <NUM_LIT:1> , max ( maxes ) + <NUM_LIT:1> ] ) <EOL> plt . title ( "<STR_LIT>" ) <EOL> plt . xlabel ( "<STR_LIT>" ) <EOL> plt . ylabel ( "<STR_LIT>" ) <EOL> raw_usages = map ( get_raw_usages , tds , fds ) <EOL> fig = <NUM_LIT:1> <EOL> for gusages , lusages in raw_usages : <EOL> for idx , usages in zip ( [ '<STR_LIT>' ] + range ( len ( lusages ) ) , [ gusages ] + lusages ) : <EOL> if usages : <EOL> bias = psCharStrings . calcSubrBias ( usages ) <EOL> if bias == <NUM_LIT> : <EOL> orig_order_usages = usages [ <NUM_LIT> : <NUM_LIT> ] + usages [ <NUM_LIT:0> : <NUM_LIT> ] + usages [ <NUM_LIT> : ] <EOL> elif bias == <NUM_LIT> : <EOL> orig_order_usages = ( usages [ <NUM_LIT> : <NUM_LIT> ] + usages [ <NUM_LIT> : <NUM_LIT> ] + <EOL> usages [ <NUM_LIT> : <NUM_LIT> ] + usages [ <NUM_LIT:0> : <NUM_LIT> ] + <EOL> usages [ <NUM_LIT> : ] ) <EOL> else : <EOL> orig_order_usages = usages <EOL> plt . figure ( fig ) <EOL> plt . plot ( range ( len ( orig_order_usages ) ) , orig_order_usages , color = '<STR_LIT:b>' ) <EOL> plt . title ( "<STR_LIT>" % idx ) <EOL> plt . axvline ( <NUM_LIT> , <NUM_LIT:0> , max ( orig_order_usages ) , color = '<STR_LIT:r>' ) <EOL> plt . axvline ( <NUM_LIT> , <NUM_LIT:0> , max ( orig_order_usages ) , color = '<STR_LIT:r>' ) <EOL> plt . ylim ( [ <NUM_LIT:0> , max ( orig_order_usages ) ] ) <EOL> plt . xlim ( [ <NUM_LIT:0> , len ( orig_order_usages ) ] ) <EOL> fig += <NUM_LIT:1> <EOL> plt . show ( ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> parser = argparse . ArgumentParser ( <EOL> description = """<STR_LIT>""" ) <EOL> parser . add_argument ( '<STR_LIT>' , help = "<STR_LIT>" , nargs = '<STR_LIT:+>' ) <EOL> parser . add_argument ( '<STR_LIT>' , '<STR_LIT>' , help = "<STR_LIT>" , action = '<STR_LIT:store_true>' , <EOL> default = False ) <EOL> kwargs = vars ( parser . parse_args ( ) ) <EOL> main ( ** kwargs ) </s>
