515 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			515 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
								 | 
							
								# Convert Font Awesome, Fork Awesome, Google Material Design, Kenney Game and Fontaudio
							 | 
						||
| 
								 | 
							
								# icon font parameters to C89, C++11 and C# compatible formats.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								# 1 - Source material
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#   1.1 - Font Awesome
							 | 
						||
| 
								 | 
							
								#       1.1.1 - version 4
							 | 
						||
| 
								 | 
							
								#           https://raw.githubusercontent.com/FortAwesome/Font-Awesome/fa-4/src/icons.yml
							 | 
						||
| 
								 | 
							
								#           https://github.com/FortAwesome/Font-Awesome/blob/fa-4/fonts/fontawesome-webfont.ttf
							 | 
						||
| 
								 | 
							
								#       1.1.2 - version 5
							 | 
						||
| 
								 | 
							
								#           https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/metadata/icons.yml
							 | 
						||
| 
								 | 
							
								#           https://github.com/FortAwesome/Font-Awesome/blob/master/webfonts/fa-brands-400.ttf
							 | 
						||
| 
								 | 
							
								#           https://github.com/FortAwesome/Font-Awesome/blob/master/webfonts/fa-regular-400.ttf
							 | 
						||
| 
								 | 
							
								#           https://github.com/FortAwesome/Font-Awesome/blob/master/webfonts/fa-solid-900.ttf
							 | 
						||
| 
								 | 
							
								#       1.1.3 - version 5 Pro
							 | 
						||
| 
								 | 
							
								#           Download files from https://fontawesome.com
							 | 
						||
| 
								 | 
							
								#           \fontawesome-pro-n.n.n-web\metadata\icons.yml
							 | 
						||
| 
								 | 
							
								#           \fontawesome-pro-n.n.n-web\webfonts\fa-brands-400.ttf
							 | 
						||
| 
								 | 
							
								#           \fontawesome-pro-n.n.n-web\webfonts\fa-light-300.ttf
							 | 
						||
| 
								 | 
							
								#           \fontawesome-pro-n.n.n-web\webfonts\fa-regular-400.ttf
							 | 
						||
| 
								 | 
							
								#           \fontawesome-pro-n.n.n-web\webfonts\fa-solid-900.ttf
							 | 
						||
| 
								 | 
							
								#   1.2 - Fork Awesome
							 | 
						||
| 
								 | 
							
								#           https://raw.githubusercontent.com/ForkAwesome/Fork-Awesome/master/src/icons/icons.yml
							 | 
						||
| 
								 | 
							
								#           https://github.com/ForkAwesome/Fork-Awesome/blob/master/fonts/forkawesome-webfont.ttf
							 | 
						||
| 
								 | 
							
								#   1.3 - Google Material Design
							 | 
						||
| 
								 | 
							
								#           https://raw.githubusercontent.com/google/material-design-icons/master/iconfont/codepoints
							 | 
						||
| 
								 | 
							
								#           https://github.com/google/material-design-icons/blob/master/iconfont/MaterialIcons-Regular.ttf
							 | 
						||
| 
								 | 
							
								#   1.4 - Kenney Game icons
							 | 
						||
| 
								 | 
							
								#           https://raw.githubusercontent.com/nicodinh/kenney-icon-font/master/css/kenney-icons.css
							 | 
						||
| 
								 | 
							
								#           https://github.com/nicodinh/kenney-icon-font/blob/master/fonts/kenney-icon-font.ttf
							 | 
						||
| 
								 | 
							
								#   1.5 - Fontaudio
							 | 
						||
| 
								 | 
							
								#           https://raw.githubusercontent.com/fefanto/fontaudio/master/font/fontaudio.css
							 | 
						||
| 
								 | 
							
								#           https://github.com/fefanto/fontaudio/blob/master/font/fontaudio.ttf
							 | 
						||
| 
								 | 
							
								#------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								# 2 - Data sample
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#   Font Awesome example:
							 | 
						||
| 
								 | 
							
								#           - input:            music:
							 | 
						||
| 
								 | 
							
								#                                 changes:
							 | 
						||
| 
								 | 
							
								#                                   - '1'
							 | 
						||
| 
								 | 
							
								#                                   - 5.0.0
							 | 
						||
| 
								 | 
							
								#                                 label: Music
							 | 
						||
| 
								 | 
							
								#                                 search:
							 | 
						||
| 
								 | 
							
								#                                   terms:
							 | 
						||
| 
								 | 
							
								#                                     - note
							 | 
						||
| 
								 | 
							
								#                                     - sound
							 | 
						||
| 
								 | 
							
								#                                 styles:
							 | 
						||
| 
								 | 
							
								#                                   - solid
							 | 
						||
| 
								 | 
							
								#                                 unicode: f001
							 | 
						||
| 
								 | 
							
								#           - output C++11:     #define ICON_FA_MUSIC u8"\uf001"
							 | 
						||
| 
								 | 
							
								#           - output C89:       #define ICON_FA_MUSIC "\xEF\x80\x81"
							 | 
						||
| 
								 | 
							
								#           - output C#:        public const string Music = "\uf001";
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#   All fonts have computed min and max unicode fonts ICON_MIN and ICON_MAX
							 | 
						||
| 
								 | 
							
								#           - output C89, C++11:    #define ICON_MIN_FA 0xf000
							 | 
						||
| 
								 | 
							
								#                                   #define ICON_MAX_FA 0xf2e0
							 | 
						||
| 
								 | 
							
								#               Exception for Font Awesome brands: we use ICON_MIN_FAB and ICON_MAX_FAB
							 | 
						||
| 
								 | 
							
								#               to differentiate between brand and non-brand icons so they can be used together
							 | 
						||
| 
								 | 
							
								#               (the defines must be unique in C and C++).
							 | 
						||
| 
								 | 
							
								#           - output C#:            public const int IconMin = 0xf000;
							 | 
						||
| 
								 | 
							
								#                                   public const int IconMax = 0xf2e0;
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								# 3 - Script dependencies
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#   3.1 - Fonts source material online
							 | 
						||
| 
								 | 
							
								#   3.2 - Python 3 - https://www.python.org/downloads/
							 | 
						||
| 
								 | 
							
								#   3.3 - Requests - https://pypi.org/project/requests/
							 | 
						||
| 
								 | 
							
								#   3.4 - PyYAML - https://pypi.org/project/PyYAML/
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								# 4 - References
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#   GitHub repository: https://github.com/juliettef/IconFontCppHeaders/
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import requests
							 | 
						||
| 
								 | 
							
								import yaml
							 | 
						||
| 
								 | 
							
								import os
							 | 
						||
| 
								 | 
							
								import sys
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if sys.version_info[0] < 3:
							 | 
						||
| 
								 | 
							
								    raise Exception( "Python 3 or a more recent version is required." )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Fonts
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Font:
							 | 
						||
| 
								 | 
							
								    font_name = '[ ERROR - missing font name ]'
							 | 
						||
| 
								 | 
							
								    font_abbr = '[ ERROR - missing font abbreviation ]'
							 | 
						||
| 
								 | 
							
								    font_minmax_abbr = ''   # optional - use if min and max defines must be differentiated. See Font Awesome Brand for example.
							 | 
						||
| 
								 | 
							
								    font_data = '[ ERROR - missing font data file or url ]'
							 | 
						||
| 
								 | 
							
								    font_ttf = '[ ERROR - missing ttf file or url ]'
							 | 
						||
| 
								 | 
							
								    font_file_name_ttf = '[ ERROR - missing ttf file name ]'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def get_icons( cls, input ):
							 | 
						||
| 
								 | 
							
								        # intermediate representation of the fonts data, identify the min and max
							 | 
						||
| 
								 | 
							
								        print( '[ ERROR - missing implementation of class method get_icons for {!s} ]'.format( cls.font_name ))
							 | 
						||
| 
								 | 
							
								        icons_data = {}
							 | 
						||
| 
								 | 
							
								        icons_data.update({ 'font_min' : '[ ERROR - missing font min ]',
							 | 
						||
| 
								 | 
							
								                            'font_max' : '[ ERROR - missing font max ]',
							 | 
						||
| 
								 | 
							
								                            'icons' : '[ ERROR - missing list of pairs [ font icon name, code ]]' })
							 | 
						||
| 
								 | 
							
								        return icons_data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def get_intermediate_representation( cls ):
							 | 
						||
| 
								 | 
							
								        font_ir = {}
							 | 
						||
| 
								 | 
							
								        input_raw = ''
							 | 
						||
| 
								 | 
							
								        if 'http' in cls.font_data:  # if url, download data
							 | 
						||
| 
								 | 
							
								            response = requests.get( cls.font_data, timeout = 2 )
							 | 
						||
| 
								 | 
							
								            if response.status_code == 200:
							 | 
						||
| 
								 | 
							
								                input_raw = response.text
							 | 
						||
| 
								 | 
							
								                print( 'Downloaded - ' + cls.font_name )
							 | 
						||
| 
								 | 
							
								            else:
							 | 
						||
| 
								 | 
							
								                raise Exception( 'Download failed - ' + cls.font_name )
							 | 
						||
| 
								 | 
							
								        else:   # read data from file if present
							 | 
						||
| 
								 | 
							
								            if os.path.isfile( cls.font_data ):
							 | 
						||
| 
								 | 
							
								                with open( cls.font_data, 'r' ) as f:
							 | 
						||
| 
								 | 
							
								                    input_raw = f.read()
							 | 
						||
| 
								 | 
							
								                    print( 'File read - ' + cls.font_name )
							 | 
						||
| 
								 | 
							
								            else:
							 | 
						||
| 
								 | 
							
								                raise Exception( 'File ' + cls.font_data + ' missing - ' +  cls.font_name )
							 | 
						||
| 
								 | 
							
								        if input_raw:
							 | 
						||
| 
								 | 
							
								            icons_data = cls.get_icons( input_raw )
							 | 
						||
| 
								 | 
							
								            font_ir.update( icons_data )
							 | 
						||
| 
								 | 
							
								            font_ir.update({ 'font_ttf' : cls.font_ttf,
							 | 
						||
| 
								 | 
							
								                             'font_data' : cls.font_data,
							 | 
						||
| 
								 | 
							
								                             'font_file_name_ttf' : cls.font_file_name_ttf,
							 | 
						||
| 
								 | 
							
								                             'font_name' : cls.font_name,
							 | 
						||
| 
								 | 
							
								                             'font_abbr' : cls.font_abbr,
							 | 
						||
| 
								 | 
							
								                             'font_minmax_abbr' : cls.font_minmax_abbr })
							 | 
						||
| 
								 | 
							
								            print( 'Generated intermediate data - ' + cls.font_name )
							 | 
						||
| 
								 | 
							
								        return font_ir
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class FontFA4( Font ):              # legacy Font Awesome version 4
							 | 
						||
| 
								 | 
							
								    font_name = 'Font Awesome 4'
							 | 
						||
| 
								 | 
							
								    font_abbr = 'FA'
							 | 
						||
| 
								 | 
							
								    font_data = 'https://raw.githubusercontent.com/FortAwesome/Font-Awesome/fa-4/src/icons.yml'
							 | 
						||
| 
								 | 
							
								    font_ttf = 'https://github.com/FortAwesome/Font-Awesome/blob/fa-4/fonts/fontawesome-webfont.ttf'
							 | 
						||
| 
								 | 
							
								    font_file_name_ttf = [[ font_abbr, font_ttf[ font_ttf.rfind('/')+1: ]]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def get_icons( self, input ):
							 | 
						||
| 
								 | 
							
								        icons_data = { }
							 | 
						||
| 
								 | 
							
								        data = yaml.safe_load(input)
							 | 
						||
| 
								 | 
							
								        font_min = 'ffff'
							 | 
						||
| 
								 | 
							
								        font_max = '0'
							 | 
						||
| 
								 | 
							
								        icons = []
							 | 
						||
| 
								 | 
							
								        for item in data[ 'icons' ]:
							 | 
						||
| 
								 | 
							
								            if item[ 'unicode' ] < font_min:
							 | 
						||
| 
								 | 
							
								                font_min = item[ 'unicode' ]
							 | 
						||
| 
								 | 
							
								            if item[ 'unicode' ] >= font_max:
							 | 
						||
| 
								 | 
							
								                font_max = item[ 'unicode' ]
							 | 
						||
| 
								 | 
							
								            icons.append([ item[ 'id' ], item[ 'unicode' ]])
							 | 
						||
| 
								 | 
							
								        icons_data.update({ 'font_min' : font_min,
							 | 
						||
| 
								 | 
							
								                        'font_max' : font_max,
							 | 
						||
| 
								 | 
							
								                        'icons' : icons })
							 | 
						||
| 
								 | 
							
								        return icons_data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class FontFK( FontFA4 ):            # Fork Awesome, based on Font Awesome 4
							 | 
						||
| 
								 | 
							
								    font_name = 'Fork Awesome'
							 | 
						||
| 
								 | 
							
								    font_abbr = 'FK'
							 | 
						||
| 
								 | 
							
								    font_data = 'https://raw.githubusercontent.com/ForkAwesome/Fork-Awesome/master/src/icons/icons.yml'
							 | 
						||
| 
								 | 
							
								    font_ttf = 'https://github.com/ForkAwesome/Fork-Awesome/blob/master/fonts/forkawesome-webfont.ttf'
							 | 
						||
| 
								 | 
							
								    font_file_name_ttf = [[ font_abbr, font_ttf[ font_ttf.rfind('/')+1: ]]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class FontFA5( Font ):              # Font Awesome version 5 - Regular and Solid styles
							 | 
						||
| 
								 | 
							
								    font_name = 'Font Awesome 5'
							 | 
						||
| 
								 | 
							
								    font_abbr = 'FA'
							 | 
						||
| 
								 | 
							
								    font_data = 'https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/metadata/icons.yml'
							 | 
						||
| 
								 | 
							
								    font_ttf = 'https://github.com/FortAwesome/Font-Awesome/blob/master/webfonts/fa-solid-900.ttf, ' +\
							 | 
						||
| 
								 | 
							
								        'https://github.com/FortAwesome/Font-Awesome/blob/master/webfonts/fa-regular-400.ttf, '
							 | 
						||
| 
								 | 
							
								    font_file_name_ttf = [[ 'FAR', 'fa-regular-400.ttf' ], [ 'FAS', 'fa-solid-900.ttf' ]]
							 | 
						||
| 
								 | 
							
								    font_fa_style = [ 'regular', 'solid' ]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def get_icons( self, input ):
							 | 
						||
| 
								 | 
							
								        icons_data = { }
							 | 
						||
| 
								 | 
							
								        data = yaml.safe_load(input)
							 | 
						||
| 
								 | 
							
								        if data:
							 | 
						||
| 
								 | 
							
								            font_min = 'ffff'
							 | 
						||
| 
								 | 
							
								            font_max = '0'
							 | 
						||
| 
								 | 
							
								            icons = []
							 | 
						||
| 
								 | 
							
								            for key in data:
							 | 
						||
| 
								 | 
							
								                item = data[ key ]
							 | 
						||
| 
								 | 
							
								                for style in item[ 'styles' ]:
							 | 
						||
| 
								 | 
							
								                    if style in self.font_fa_style:
							 | 
						||
| 
								 | 
							
								                        if [ key, item[ 'unicode' ]] not in icons:
							 | 
						||
| 
								 | 
							
								                            if item[ 'unicode' ] < font_min:
							 | 
						||
| 
								 | 
							
								                                font_min = item[ 'unicode' ]
							 | 
						||
| 
								 | 
							
								                            if item[ 'unicode' ] >= font_max:
							 | 
						||
| 
								 | 
							
								                                font_max = item[ 'unicode' ]
							 | 
						||
| 
								 | 
							
								                            icons.append([ key, item[ 'unicode' ] ])
							 | 
						||
| 
								 | 
							
								            icons_data.update({ 'font_min':font_min, 'font_max':font_max, 'icons':icons })
							 | 
						||
| 
								 | 
							
								        return icons_data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class FontFA5Brands( FontFA5 ):     # Font Awesome version 5 - Brand style
							 | 
						||
| 
								 | 
							
								    font_name = 'Font Awesome 5 Brands'
							 | 
						||
| 
								 | 
							
								    font_minmax_abbr = 'FAB'
							 | 
						||
| 
								 | 
							
								    font_ttf = 'https://github.com/FortAwesome/Font-Awesome/blob/master/webfonts/fa-brands-400.ttf'
							 | 
						||
| 
								 | 
							
								    font_file_name_ttf = [[ 'FAB', 'fa-brands-400.ttf' ]]
							 | 
						||
| 
								 | 
							
								    font_fa_style = [ 'brands' ]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class FontFA5Pro( FontFA5 ):        # Font Awesome version 5 Pro - Light, Regular and Solid styles
							 | 
						||
| 
								 | 
							
								    font_name = 'Font Awesome 5 Pro'
							 | 
						||
| 
								 | 
							
								    font_data = 'icons.yml'
							 | 
						||
| 
								 | 
							
								    font_ttf = 'fa-light-300.ttf, fa-regular-400.ttf, fa-solid-900.ttf'
							 | 
						||
| 
								 | 
							
								    font_file_name_ttf = [[ 'FAL', 'fa-light-300.ttf' ], [ 'FAR', 'fa-regular-400.ttf' ], [ 'FAS', 'fa-solid-900.ttf' ]]
							 | 
						||
| 
								 | 
							
								    font_fa_style = [ 'light', 'regular', 'solid' ]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class FontFA5ProBrands( FontFA5 ):  # Font Awesome version 5 Pro - Brand style
							 | 
						||
| 
								 | 
							
								    font_name = 'Font Awesome 5 Pro Brands'
							 | 
						||
| 
								 | 
							
								    font_minmax_abbr = 'FAB'
							 | 
						||
| 
								 | 
							
								    font_data = 'icons.yml'
							 | 
						||
| 
								 | 
							
								    font_ttf = 'fa-brands-400.ttf'
							 | 
						||
| 
								 | 
							
								    font_file_name_ttf = [[ 'FAB', 'fa-brands-400.ttf' ]]
							 | 
						||
| 
								 | 
							
								    font_fa_style = [ 'brands' ]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class FontMD( Font ):               # Material Design
							 | 
						||
| 
								 | 
							
								    font_name = 'Material Design'
							 | 
						||
| 
								 | 
							
								    font_abbr = 'MD'
							 | 
						||
| 
								 | 
							
								    font_data = 'https://raw.githubusercontent.com/google/material-design-icons/master/iconfont/codepoints'
							 | 
						||
| 
								 | 
							
								    font_ttf = 'https://github.com/google/material-design-icons/blob/master/iconfont/MaterialIcons-Regular.ttf'
							 | 
						||
| 
								 | 
							
								    font_file_name_ttf = [[ font_abbr, font_ttf[ font_ttf.rfind('/')+1: ]]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def get_icons( self, input ):
							 | 
						||
| 
								 | 
							
								        icons_data = {}
							 | 
						||
| 
								 | 
							
								        lines = str.split( input, '\n' )
							 | 
						||
| 
								 | 
							
								        if lines:
							 | 
						||
| 
								 | 
							
								            font_min = 'ffff'
							 | 
						||
| 
								 | 
							
								            font_max = '0'
							 | 
						||
| 
								 | 
							
								            icons = []
							 | 
						||
| 
								 | 
							
								            for line in lines :
							 | 
						||
| 
								 | 
							
								                words = str.split(line)
							 | 
						||
| 
								 | 
							
								                if words and len( words ) >= 2:
							 | 
						||
| 
								 | 
							
								                    if words[ 1 ] < font_min:
							 | 
						||
| 
								 | 
							
								                        font_min = words[ 1 ]
							 | 
						||
| 
								 | 
							
								                    if words[ 1 ] >= font_max:
							 | 
						||
| 
								 | 
							
								                        font_max = words[ 1 ]
							 | 
						||
| 
								 | 
							
								                    icons.append( words )
							 | 
						||
| 
								 | 
							
								            icons_data.update({ 'font_min' : font_min,
							 | 
						||
| 
								 | 
							
								                                'font_max' : font_max,
							 | 
						||
| 
								 | 
							
								                                'icons' : icons })
							 | 
						||
| 
								 | 
							
								        return icons_data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class FontKI( Font ):               # Kenney Game icons
							 | 
						||
| 
								 | 
							
								    font_name = 'Kenney'
							 | 
						||
| 
								 | 
							
								    font_abbr = 'KI'
							 | 
						||
| 
								 | 
							
								    font_data = 'https://raw.githubusercontent.com/nicodinh/kenney-icon-font/master/css/kenney-icons.css'
							 | 
						||
| 
								 | 
							
								    font_ttf = 'https://github.com/nicodinh/kenney-icon-font/blob/master/fonts/kenney-icon-font.ttf'
							 | 
						||
| 
								 | 
							
								    font_file_name_ttf = [[ font_abbr, font_ttf[ font_ttf.rfind('/')+1: ]]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def get_icons( self, input ):
							 | 
						||
| 
								 | 
							
								        icons_data = {}
							 | 
						||
| 
								 | 
							
								        lines = str.split( input, '\n' )
							 | 
						||
| 
								 | 
							
								        if lines:
							 | 
						||
| 
								 | 
							
								            font_min = 'ffff'
							 | 
						||
| 
								 | 
							
								            font_max = '0'
							 | 
						||
| 
								 | 
							
								            icons = []
							 | 
						||
| 
								 | 
							
								            for line in lines :
							 | 
						||
| 
								 | 
							
								                if '.ki-' in line:
							 | 
						||
| 
								 | 
							
								                    words = str.split(line)
							 | 
						||
| 
								 | 
							
								                    if words and '.ki-' in words[ 0 ]:
							 | 
						||
| 
								 | 
							
								                        font_id = words[ 0 ].partition( '.ki-' )[2].partition( ':before' )[0]
							 | 
						||
| 
								 | 
							
								                        font_code = words[ 2 ].partition( '"\\' )[2].partition( '";' )[0]
							 | 
						||
| 
								 | 
							
								                        if font_code < font_min:
							 | 
						||
| 
								 | 
							
								                            font_min = font_code
							 | 
						||
| 
								 | 
							
								                        if font_code >= font_max:
							 | 
						||
| 
								 | 
							
								                            font_max = font_code
							 | 
						||
| 
								 | 
							
								                        icons.append([ font_id, font_code ])
							 | 
						||
| 
								 | 
							
								            icons_data.update({ 'font_min' : font_min,
							 | 
						||
| 
								 | 
							
								                                'font_max' : font_max,
							 | 
						||
| 
								 | 
							
								                                'icons' : icons  })
							 | 
						||
| 
								 | 
							
								        return icons_data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class FontFAD( Font ):               # Fontaudio
							 | 
						||
| 
								 | 
							
								    font_name = 'Fontaudio'
							 | 
						||
| 
								 | 
							
								    font_abbr = 'FAD'
							 | 
						||
| 
								 | 
							
								    font_data = 'https://raw.githubusercontent.com/fefanto/fontaudio/master/font/fontaudio.css'
							 | 
						||
| 
								 | 
							
								    font_ttf = 'https://github.com/fefanto/fontaudio/raw/master/font/fontaudio.ttf'
							 | 
						||
| 
								 | 
							
								    font_file_name_ttf = [[ font_abbr, font_ttf[ font_ttf.rfind('/') + 1: ]]]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def get_icons( self, input ):
							 | 
						||
| 
								 | 
							
								        icons_data = {}
							 | 
						||
| 
								 | 
							
								        lines = str.split( input, '}\n' )
							 | 
						||
| 
								 | 
							
								        if lines:
							 | 
						||
| 
								 | 
							
								            font_min = 'ffff'
							 | 
						||
| 
								 | 
							
								            font_max = '0'
							 | 
						||
| 
								 | 
							
								            icons = []
							 | 
						||
| 
								 | 
							
								            for line in lines :
							 | 
						||
| 
								 | 
							
								                if '.icon-fad-' in line:
							 | 
						||
| 
								 | 
							
								                    words = str.split( line )
							 | 
						||
| 
								 | 
							
								                    if words and '.icon-fad-' in words[ 0 ]:
							 | 
						||
| 
								 | 
							
								                        font_id = words[ 0 ].partition( '.icon-fad-' )[2].partition( ':before' )[0]
							 | 
						||
| 
								 | 
							
								                        font_code = words[ 3 ].partition( '"\\' )[2].partition( '";' )[0]
							 | 
						||
| 
								 | 
							
								                        if font_code < font_min:
							 | 
						||
| 
								 | 
							
								                            font_min = font_code
							 | 
						||
| 
								 | 
							
								                        if font_code >= font_max:
							 | 
						||
| 
								 | 
							
								                            font_max = font_code
							 | 
						||
| 
								 | 
							
								                        icons.append([ font_id, font_code ])
							 | 
						||
| 
								 | 
							
								            icons_data.update({ 'font_min' : font_min,
							 | 
						||
| 
								 | 
							
								                                'font_max' : font_max,
							 | 
						||
| 
								 | 
							
								                                'icons' : icons  })
							 | 
						||
| 
								 | 
							
								        return icons_data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Languages
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Language:
							 | 
						||
| 
								 | 
							
								    language_name = '[ ERROR - missing language name ]'
							 | 
						||
| 
								 | 
							
								    file_name = '[ ERROR - missing file name ]'
							 | 
						||
| 
								 | 
							
								    intermediate = {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __init__( self, intermediate ):
							 | 
						||
| 
								 | 
							
								        self.intermediate = intermediate
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def prelude( cls ):
							 | 
						||
| 
								 | 
							
								        print( '[ ERROR - missing implementation of class method prelude for {!s} ]'.format( cls.language_name ))
							 | 
						||
| 
								 | 
							
								        result = '[ ERROR - missing prelude ]'
							 | 
						||
| 
								 | 
							
								        return result
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def lines_minmax( cls ):
							 | 
						||
| 
								 | 
							
								        print( '[ ERROR - missing implementation of class method lines_minmax for {!s} ]'.format( cls.language_name ))
							 | 
						||
| 
								 | 
							
								        result = '[ ERROR - missing min and max ]'
							 | 
						||
| 
								 | 
							
								        return result
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def line_icon( cls, icon ):
							 | 
						||
| 
								 | 
							
								        print( '[ ERROR - missing implementation of class method line_icon for {!s} ]'.format( cls.language_name ))
							 | 
						||
| 
								 | 
							
								        result = '[ ERROR - missing icon line ]'
							 | 
						||
| 
								 | 
							
								        return result
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def epilogue( cls ):
							 | 
						||
| 
								 | 
							
								        return ''
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def convert( cls ):
							 | 
						||
| 
								 | 
							
								        result = cls.prelude() + cls.lines_minmax()
							 | 
						||
| 
								 | 
							
								        for icon in cls.intermediate.get( 'icons' ):
							 | 
						||
| 
								 | 
							
								            line_icon = cls.line_icon( icon )
							 | 
						||
| 
								 | 
							
								            result += line_icon
							 | 
						||
| 
								 | 
							
								        result += cls.epilogue()
							 | 
						||
| 
								 | 
							
								        print(( 'Converted - {!s} for {!s}' ).format( cls.intermediate.get( 'font_name' ), cls.language_name ))
							 | 
						||
| 
								 | 
							
								        return result
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def save_to_file( cls ):
							 | 
						||
| 
								 | 
							
								        filename = cls.file_name.format( name = str(cls.intermediate.get( 'font_name' )).replace( ' ', '' ))
							 | 
						||
| 
								 | 
							
								        converted = cls.convert()
							 | 
						||
| 
								 | 
							
								        with open( filename, 'w' ) as f:
							 | 
						||
| 
								 | 
							
								            f.write( converted )
							 | 
						||
| 
								 | 
							
								        print(( 'Saved - {!s}' ).format( filename ))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LanguageC89( Language ):
							 | 
						||
| 
								 | 
							
								    language_name = 'C89'
							 | 
						||
| 
								 | 
							
								    file_name = 'Icons{name}_c.h'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def prelude( cls ):
							 | 
						||
| 
								 | 
							
								        tmpl_prelude = '// Generated by https://github.com/juliettef/IconFontCppHeaders script GenerateIconFontCppHeaders.py for language {lang}\n' + \
							 | 
						||
| 
								 | 
							
								            '// from {font_data}\n' + \
							 | 
						||
| 
								 | 
							
								            '// for use with {font_ttf}\n' + \
							 | 
						||
| 
								 | 
							
								            '#pragma once\n\n'
							 | 
						||
| 
								 | 
							
								        result = tmpl_prelude.format(lang = cls.language_name,
							 | 
						||
| 
								 | 
							
								                                     font_data = cls.intermediate.get( 'font_data' ),
							 | 
						||
| 
								 | 
							
								                                     font_ttf = cls.intermediate.get( 'font_ttf' ))
							 | 
						||
| 
								 | 
							
								        tmpl_prelude_define_file_name = '#define FONT_ICON_FILE_NAME_{font_abbr} "{file_name_ttf}"\n'
							 | 
						||
| 
								 | 
							
								        file_names_ttf = cls.intermediate.get( 'font_file_name_ttf' )
							 | 
						||
| 
								 | 
							
								        for file_name_ttf in file_names_ttf:
							 | 
						||
| 
								 | 
							
								            result += tmpl_prelude_define_file_name.format( font_abbr = file_name_ttf[ 0 ], file_name_ttf = file_name_ttf[ 1 ])
							 | 
						||
| 
								 | 
							
								        return result + '\n'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def lines_minmax( cls ):
							 | 
						||
| 
								 | 
							
								        tmpl_line_minmax = '#define ICON_{minmax}_{abbr} 0x{val}\n'
							 | 
						||
| 
								 | 
							
								        result = tmpl_line_minmax.format( minmax = 'MIN',
							 | 
						||
| 
								 | 
							
								                                          abbr = cls.intermediate.get( 'font_minmax_abbr' ) if cls.intermediate.get( 'font_minmax_abbr' ) else cls.intermediate.get('font_abbr'),
							 | 
						||
| 
								 | 
							
								                                          val = cls.intermediate.get( 'font_min' )) + \
							 | 
						||
| 
								 | 
							
								                 tmpl_line_minmax.format( minmax = 'MAX',
							 | 
						||
| 
								 | 
							
								                                          abbr = cls.intermediate.get( 'font_minmax_abbr' ) if cls.intermediate.get( 'font_minmax_abbr' ) else cls.intermediate.get('font_abbr'),
							 | 
						||
| 
								 | 
							
								                                          val = cls.intermediate.get( 'font_max' ))
							 | 
						||
| 
								 | 
							
								        return result
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def line_icon( cls, icon ):
							 | 
						||
| 
								 | 
							
								        tmpl_line_icon = '#define ICON_{abbr}_{icon} "{code}"\n'
							 | 
						||
| 
								 | 
							
								        icon_name = str.upper( icon[ 0 ]).replace( '-', '_' )
							 | 
						||
| 
								 | 
							
								        icon_code = repr( chr( int( icon[ 1 ], 16 )).encode( 'utf-8' ))[ 2:-1 ]
							 | 
						||
| 
								 | 
							
								        result = tmpl_line_icon.format( abbr = cls.intermediate.get( 'font_abbr' ),
							 | 
						||
| 
								 | 
							
								                                        icon = icon_name,
							 | 
						||
| 
								 | 
							
								                                        code = icon_code )
							 | 
						||
| 
								 | 
							
								        return result
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LanguageCpp11( LanguageC89 ):
							 | 
						||
| 
								 | 
							
								    language_name = 'C++11'
							 | 
						||
| 
								 | 
							
								    file_name = 'Icons{name}.h'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def line_icon( cls, icon ):
							 | 
						||
| 
								 | 
							
								        tmpl_line_icon = '#define ICON_{abbr}_{icon} u8"\\u{code}"\n'
							 | 
						||
| 
								 | 
							
								        icon_name = str.upper( icon[ 0 ]).replace( '-', '_' )
							 | 
						||
| 
								 | 
							
								        icon_code = icon[ 1 ]
							 | 
						||
| 
								 | 
							
								        result = tmpl_line_icon.format( abbr = cls.intermediate.get( 'font_abbr' ),
							 | 
						||
| 
								 | 
							
								                                        icon = icon_name,
							 | 
						||
| 
								 | 
							
								                                        code = icon_code)
							 | 
						||
| 
								 | 
							
								        return result
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LanguageCSharp( Language ):
							 | 
						||
| 
								 | 
							
								    language_name = "C#"
							 | 
						||
| 
								 | 
							
								    file_name = 'Icons{name}.cs'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def prelude( cls ):
							 | 
						||
| 
								 | 
							
								        tmpl_prelude = '// Generated by https://github.com/juliettef/IconFontCppHeaders script GenerateIconFontCppHeaders.py for language {lang}\n' + \
							 | 
						||
| 
								 | 
							
								            '// from {font_data}\n' + \
							 | 
						||
| 
								 | 
							
								            '// for use with {font_ttf}\n' + \
							 | 
						||
| 
								 | 
							
								            'namespace IconFonts\n' + \
							 | 
						||
| 
								 | 
							
								            '{{\n' + \
							 | 
						||
| 
								 | 
							
								            '    public class {font_name}\n' + \
							 | 
						||
| 
								 | 
							
								            '    {{\n'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        result = tmpl_prelude.format(lang = cls.language_name,
							 | 
						||
| 
								 | 
							
								                                     font_data = cls.intermediate.get( 'font_data' ),
							 | 
						||
| 
								 | 
							
								                                     font_ttf = cls.intermediate.get( 'font_ttf' ),
							 | 
						||
| 
								 | 
							
								                                     font_name = cls.intermediate.get( 'font_name' ).replace( ' ', '' )
							 | 
						||
| 
								 | 
							
								                                     )
							 | 
						||
| 
								 | 
							
								        tmpl_prelude_define_file_name = '        public const string FontIconFileName = "{file_name_ttf}";\n'
							 | 
						||
| 
								 | 
							
								        file_names_ttf = cls.intermediate.get( 'font_file_name_ttf' )
							 | 
						||
| 
								 | 
							
								        for file_name_ttf in file_names_ttf:
							 | 
						||
| 
								 | 
							
								            result += tmpl_prelude_define_file_name.format( file_name_ttf = file_name_ttf[ 1 ])
							 | 
						||
| 
								 | 
							
								        return result + '\n'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def epilogue( cls ):
							 | 
						||
| 
								 | 
							
								        return '    }\n' + \
							 | 
						||
| 
								 | 
							
								            '}\n'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def lines_minmax( cls ):
							 | 
						||
| 
								 | 
							
								        tmpl_line_minmax = '        public const int Icon{minmax} = 0x{val};\n'
							 | 
						||
| 
								 | 
							
								        result = tmpl_line_minmax.format(minmax = 'Min',
							 | 
						||
| 
								 | 
							
								                                         val = cls.intermediate.get( 'font_min' )) + \
							 | 
						||
| 
								 | 
							
								                 tmpl_line_minmax.format(minmax = 'Max',
							 | 
						||
| 
								 | 
							
								                                         val = cls.intermediate.get( 'font_max' ))
							 | 
						||
| 
								 | 
							
								        return result
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def line_icon( cls, icon ):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        tmpl_line_icon = '        public const string {icon} = "\\u{code}";\n'
							 | 
						||
| 
								 | 
							
								        icon_name = cls.to_camelcase(icon[ 0 ])
							 | 
						||
| 
								 | 
							
								        icon_code = icon[ 1 ]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if icon_name[ 0 ].isdigit():
							 | 
						||
| 
								 | 
							
								            # Variable may not start with a digit
							 | 
						||
| 
								 | 
							
								            icon_name = 'The' + icon_name
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if icon_name == cls.intermediate.get( 'font_name' ).replace( ' ', '' ):
							 | 
						||
| 
								 | 
							
								            # Member may not have same name as enclosing class
							 | 
						||
| 
								 | 
							
								            icon_name += 'Icon'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        result = tmpl_line_icon.format( icon = icon_name,
							 | 
						||
| 
								 | 
							
								                                        code = icon_code)
							 | 
						||
| 
								 | 
							
								        return result
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def to_camelcase( cls, text ):
							 | 
						||
| 
								 | 
							
								        parts = text.split( '-' )
							 | 
						||
| 
								 | 
							
								        for i in range( len( parts ) ):
							 | 
						||
| 
								 | 
							
								            p = parts[i]
							 | 
						||
| 
								 | 
							
								            parts[ i ] = p[ 0 ].upper() + p[ 1: ].lower()
							 | 
						||
| 
								 | 
							
								        return ''.join( parts )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Main
							 | 
						||
| 
								 | 
							
								fonts = [ FontFA4, FontFA5, FontFA5Brands, FontFA5Pro, FontFA5ProBrands, FontFK, FontMD, FontKI, FontFAD ]
							 | 
						||
| 
								 | 
							
								languages = [ LanguageC89, LanguageCpp11, LanguageCSharp ]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								intermediates = []
							 | 
						||
| 
								 | 
							
								for font in fonts:
							 | 
						||
| 
								 | 
							
								    try:
							 | 
						||
| 
								 | 
							
								        font_intermediate = font.get_intermediate_representation()
							 | 
						||
| 
								 | 
							
								        if font_intermediate:
							 | 
						||
| 
								 | 
							
								            intermediates.append( font_intermediate )
							 | 
						||
| 
								 | 
							
								    except Exception as e:
							 | 
						||
| 
								 | 
							
								        print( '[ ERROR: {!s} ]'.format( e ))
							 | 
						||
| 
								 | 
							
								if intermediates:
							 | 
						||
| 
								 | 
							
								    for interm in intermediates:
							 | 
						||
| 
								 | 
							
								        Language.intermediate = interm
							 | 
						||
| 
								 | 
							
								        for lang in languages:
							 | 
						||
| 
								 | 
							
								            if lang:
							 | 
						||
| 
								 | 
							
								                lang.save_to_file()
							 |