<s> """<STR_LIT>""" <EOL> import argparse <EOL> import collections <EOL> import os <EOL> from os import path <EOL> import struct <EOL> import subprocess <EOL> from fontTools . ttLib . tables . _n_a_m_e import table__n_a_m_e as NameTable <EOL> from nototools import tool_utils <EOL> _ttcHeader = '<STR_LIT>' <EOL> _ttcHeaderSize = struct . calcsize ( _ttcHeader ) <EOL> _sfntHeader = '<STR_LIT>' <EOL> _sfntHeaderSize = struct . calcsize ( _sfntHeader ) <EOL> _sfntHeaderEntry = '<STR_LIT>' <EOL> _sfntHeaderEntrySize = struct . calcsize ( _sfntHeaderEntry ) <EOL> FontEntry = collections . namedtuple ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> TableEntry = collections . namedtuple ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> class TTCFile ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , data = None ) : <EOL> if data : <EOL> self . _build ( data ) <EOL> else : <EOL> self . fonts = [ ] <EOL> self . tables = [ ] <EOL> def _build ( self , data ) : <EOL> tag , version , font_count = struct . unpack ( _ttcHeader , data [ : _ttcHeaderSize ] ) <EOL> if tag not in [ '<STR_LIT>' ] : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if version not in [ <NUM_LIT> , <NUM_LIT> ] : <EOL> raise ValueError ( '<STR_LIT>' % version ) <EOL> self . fonts = [ ] <EOL> self . tables = [ ] <EOL> for i in range ( font_count ) : <EOL> pos = _ttcHeaderSize + i * <NUM_LIT:4> <EOL> offset = struct . unpack ( '<STR_LIT>' , data [ pos : pos + <NUM_LIT:4> ] ) [ <NUM_LIT:0> ] <EOL> self . _build_font_entry ( data , offset ) <EOL> def _build_font_entry ( self , data , offset ) : <EOL> limit = offset + _sfntHeaderSize <EOL> version , num_tables = struct . unpack ( _sfntHeader , data [ offset : limit ] ) [ : <NUM_LIT:2> ] <EOL> if version == <NUM_LIT> : <EOL> version_str = '<STR_LIT:1.0>' <EOL> font_fmt = '<STR_LIT>' <EOL> elif version == <NUM_LIT> : <EOL> version_str = '<STR_LIT>' <EOL> font_fmt = '<STR_LIT>' <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' % version ) <EOL> font_table_indices = [ ] <EOL> for j in range ( num_tables ) : <EOL> entry_pos = limit + j * _sfntHeaderEntrySize <EOL> font_table_indices . append ( self . _build_table_entry ( data , entry_pos ) ) <EOL> self . fonts . append ( FontEntry ( font_fmt , font_table_indices ) ) <EOL> def _build_table_entry ( self , data , offset ) : <EOL> limit = offset + _sfntHeaderEntrySize <EOL> tag , checksum , offset , length = struct . unpack ( <EOL> _sfntHeaderEntry , data [ offset : limit ] ) <EOL> entry = TableEntry ( tag , offset , length ) <EOL> for i , e in enumerate ( self . tables ) : <EOL> if e == entry : <EOL> return i <EOL> self . tables . append ( entry ) <EOL> return len ( self . tables ) - <NUM_LIT:1> <EOL> def ttcfile_dump ( ttcfile ) : <EOL> """<STR_LIT>""" <EOL> with open ( ttcfile , '<STR_LIT:rb>' ) as f : <EOL> data = f . read ( ) <EOL> ttc = TTCFile ( data = data ) <EOL> ttc_dump ( ttc , data ) <EOL> def ttc_dump ( ttc , data ) : <EOL> """<STR_LIT>""" <EOL> names = ttc_filenames ( ttc , data ) <EOL> table_map = { } <EOL> for font_index , font_entry in enumerate ( ttc . fonts ) : <EOL> print '<STR_LIT>' % ( font_index , names [ font_index ] ) <EOL> for table_index , table_entry in enumerate ( font_entry . tables ) : <EOL> table = ttc . tables [ table_entry ] <EOL> if table_entry not in table_map : <EOL> table_map [ table_entry ] = ( font_index , table_index ) <EOL> print '<STR_LIT>' % ( <EOL> table_index , table . tag , table . offset , table . length ) <EOL> else : <EOL> table_from = table_map [ table_entry ] <EOL> print '<STR_LIT>' % ( <EOL> table_index , table . tag , table_from [ <NUM_LIT:0> ] , table_from [ <NUM_LIT:1> ] ) <EOL> def ttcfile_filenames ( ttcfile ) : <EOL> """<STR_LIT>""" <EOL> with open ( ttcfile , '<STR_LIT:rb>' ) as f : <EOL> data = f . read ( ) <EOL> ttc = TTCFile ( data = data ) <EOL> return ttc_filenames ( ttc , data ) <EOL> def ttc_filenames ( ttc , data ) : <EOL> """<STR_LIT>""" <EOL> names = [ ] <EOL> for font_entry in ttc . fonts : <EOL> name_entry = None <EOL> file_name = None <EOL> for ix in font_entry . tables : <EOL> if ttc . tables [ ix ] . tag == '<STR_LIT:name>' : <EOL> name_entry = ttc . tables [ ix ] <EOL> break <EOL> if name_entry : <EOL> offset = name_entry . offset <EOL> limit = offset + name_entry . length <EOL> name_table = NameTable ( ) <EOL> name_table . decompile ( data [ offset : limit ] , None ) <EOL> ps_name = None <EOL> for r in name_table . names : <EOL> if ( r . nameID , r . platformID , r . platEncID , r . langID ) == ( <NUM_LIT:6> , <NUM_LIT:3> , <NUM_LIT:1> , <NUM_LIT> ) : <EOL> ps_name = unicode ( r . string , '<STR_LIT>' ) <EOL> break <EOL> if ps_name : <EOL> file_name = ps_name <EOL> if '<STR_LIT:->' not in ps_name : <EOL> file_name += '<STR_LIT>' <EOL> file_name += '<STR_LIT:.>' + font_entry . fmt <EOL> names . append ( file_name or ( '<STR_LIT>' % font_entry . fmt ) ) <EOL> return names <EOL> def build_ttc ( output_path , file_list , <EOL> tool_path = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> otf2otc = tool_utils . resolve_path ( tool_path ) <EOL> if not otf2otc : <EOL> raise ValueError ( '<STR_LIT>' % tool_path ) <EOL> subprocess . check_output ( [ '<STR_LIT>' , otf2otc , '<STR_LIT>' , output_path ] + file_list ) <EOL> def main ( ) : <EOL> parser = argparse . ArgumentParser ( ) <EOL> parser . add_argument ( '<STR_LIT>' , dest = '<STR_LIT>' , help = '<STR_LIT>' , <EOL> metavar = '<STR_LIT>' , required = True ) <EOL> parser . add_argument ( '<STR_LIT>' , dest = '<STR_LIT>' , help = '<STR_LIT>' , <EOL> metavar = '<STR_LIT>' , choices = [ '<STR_LIT>' , '<STR_LIT>' ] , default = '<STR_LIT>' ) <EOL> args = parser . parse_args ( ) <EOL> if args . op == '<STR_LIT>' : <EOL> ttcfile_dump ( args . ttcfile ) <EOL> elif args . op == '<STR_LIT>' : <EOL> print '<STR_LIT:\n>' . join ( ttcfile_filenames ( args . ttcfile ) ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> main ( ) </s>
