#!/usr/bin/python # Convert Font Awesome, Google Material Design and Kenney Game icon font # parameters to C++11 and C89 compatible formats. # #------------------------------------------------------------------------------ # 1 - Source material # # 1.1 - Font Awesome - https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/src/icons.yml # 1.2 - Material Design - https://raw.githubusercontent.com/google/material-design-icons/master/iconfont/codepoints # 1.3 - Kenney icons - https://raw.githubusercontent.com/SamBrishes/kenney-icon-font/master/css/kenney-icons.css # #------------------------------------------------------------------------------ # 2 - Data samples # # 2.1 - Font Awesome # - input: - name: Music # id: music # unicode: f001 # created: 1.0 # filter: # - note # - sound # categories: # - Web Application Icons # - output C++11: #define ICON_FA_MUSIC u8"\uf001" # - output C89: #define ICON_FA_MUSIC "\xEF\x80\x81" # # 2.2 - Google Material Design icons # - input: 3d_rotation e84d # - output C++11: #define ICON_MD_3D_ROTATION u8"\ue84d" # - output C89: #define ICON_MD_3D_ROTATION "\xEE\xA1\x8D" # # 2.3 - Kenney Game icons # - input: .ki-home:before{ content: "\e900"; } # - output C++11: #define ICON_KI_HOME u8"\ue900" # - output C89: #define ICON_KI_HOME "\xEE\xA4\x80" # # 2.4 - All fonts # - computed min and max unicode fonts ICON_MIN and ICON_MAX # - output: #define ICON_MIN_FA 0xf000 # #define ICON_MAX_FA 0xf295 # #------------------------------------------------------------------------------ # 3 - Script dependencies # # 3.1 - Python 2.7 - https://www.python.org/download/releases/2.7/ # 3.2 - Requests - http://docs.python-requests.org/ # 3.3 - PyYAML - http://pyyaml.org/ # #------------------------------------------------------------------------------ import requests import yaml LINE_FORMAT_MINMAX = '#define ICON_{!s}_{!s} 0x{!s}\n' UNICODE_MIN = 'ffff' UNICODE_MAX = '0' TIMEOUT = 2 MESSAGE_SUCCESS = '{!s} fonts - conversion success: {!s}' MESSAGE_ERROR = '{!s} fonts - error \n\t{!s}' def get_prelude( url ): prelude = '// Generated by GenerateIconFontCppHeaders.py \n// from {!s}\n#pragma once\n\n'.format( url ) return prelude def line_format( font_abbr, font, unicode, cpp11 = True ): if cpp11: result = '#define ICON_{!s}_{!s} u8"\u{!s}"\n'.format( font_abbr, font, unicode ) else: unicode_base = ''.join([ '{0:x}'.format( ord( x )) for x in unichr( int( unicode, 16 )).encode( 'utf-8' )]).upper() unicode = '\\x' + unicode_base[ :2 ] + '\\x' + unicode_base[ 2:4 ] + '\\x' + unicode_base[ 4: ] result = '#define ICON_{!s}_{!s} "{!s}"\n'.format( font_abbr, font, unicode ) return result def convert_font_awesome( font_name, font_abbr, source_url, output_file, cpp11 ): try: response = requests.get( source_url, timeout = TIMEOUT ) if response.status_code == 200: input = yaml.safe_load( response.content ) min = UNICODE_MIN max = UNICODE_MAX output_fonts = '' for item in input[ 'icons' ]: font = '' for char in item[ 'id' ]: font += '_' if ( char == '-' ) else str.upper( char ) unicode = item[ 'unicode' ] if unicode < min: min = unicode elif unicode >= max: max = unicode output_fonts += line_format( font_abbr, font, unicode, cpp11 ) output = get_prelude( source_url ) + \ LINE_FORMAT_MINMAX.format( 'MIN', font_abbr, min ) + \ LINE_FORMAT_MINMAX.format( 'MAX', font_abbr, max ) + \ output_fonts with open( output_file, 'w' ) as f: f.write( output ) print( MESSAGE_SUCCESS.format( font_name, output_file )) except Exception as e: print( MESSAGE_ERROR.format( font_name, e )) def convert_material_design( font_name, font_abbr, source_url, output_file, cpp11 ): try: response = requests.get( source_url, timeout = TIMEOUT ) if response.status_code == 200: input = str.split( response.content, '\n' ) min = UNICODE_MIN max = UNICODE_MAX output_fonts = '' for line in input: words = str.split( line ) if words: font = '' for char in words[ 0 ]: font += '_' if ( char == '-' ) else str.upper( char ) unicode = words[ 1 ] if unicode < min: min = unicode elif unicode >= max: max = unicode output_fonts += line_format( font_abbr, font, unicode, cpp11 ) output = get_prelude( source_url ) + \ LINE_FORMAT_MINMAX.format( 'MIN', font_abbr, min ) + \ LINE_FORMAT_MINMAX.format( 'MAX', font_abbr, max ) + \ output_fonts with open( output_file, 'w' ) as f: f.write( output ) print( MESSAGE_SUCCESS.format( font_name, output_file )) except Exception as e: print( MESSAGE_ERROR.format( font_name, e )) def convert_kenney( font_name, font_abbr, source_url, output_file, cpp11 ): try: response = requests.get( source_url, timeout = TIMEOUT ) if response.status_code == 200: input = str.split( response.content, '\n' ) min = UNICODE_MIN max = UNICODE_MAX output_fonts = '' font_begin= '.ki-' font_end = ':before' unicode_begin = '"\\' unicode_end = '";' for line in input: words = str.split( line ) if words: if font_begin in words[ 0 ]: font = '' word = words[ 0 ][( words[ 0 ].find( font_begin ) + len( font_begin )) : ( words[ 0 ].find( font_end ))] for char in word: font += '_' if ( char == '-' ) else str.upper( char ) unicode = str( words[ 2 ][( words[ 2 ].find( unicode_begin ) + len( unicode_begin )) : words[ 2 ].find( unicode_end )]) if unicode < min: min = unicode elif unicode >= max: max = unicode output_fonts += line_format( font_abbr, font, unicode, cpp11 ) output = get_prelude( source_url ) + \ LINE_FORMAT_MINMAX.format( 'MIN', font_abbr, min ) + \ LINE_FORMAT_MINMAX.format( 'MAX', font_abbr, max ) + \ output_fonts with open( output_file, 'w' ) as f: f.write( output ) print( MESSAGE_SUCCESS.format( font_name, output_file )) except Exception as e: print( MESSAGE_ERROR.format( font_name, e )) # Main convert_font_awesome( 'Font Awesome', 'FA', 'https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/src/icons.yml', 'icons_font_awesome.h', False ) convert_material_design( 'Material Design', 'MD', 'https://raw.githubusercontent.com/google/material-design-icons/master/iconfont/codepoints', 'icons_material_design.h', False ) convert_kenney( 'Kenney', 'KI', 'https://raw.githubusercontent.com/SamBrishes/kenney-icon-font/master/css/kenney-icons.css', 'icons_kenney.h', False )