@@ -42,6 +42,7 @@ def extractFontFromOpenType(
4242 doKerning = True ,
4343 customFunctions = [],
4444 doInstructions = True ,
45+ doColors = True ,
4546):
4647 source = TTFont (pathOrFile )
4748 if doInfo :
@@ -60,6 +61,8 @@ def extractFontFromOpenType(
6061 function (source , destination )
6162 if doInstructions :
6263 extractInstructions (source , destination )
64+ if doColors :
65+ extractColorsFromOpenType (source , destination )
6366 source .close ()
6467
6568
@@ -1046,3 +1049,44 @@ def _extractOpenTypeKerningFromKern(source):
10461049 # there are no minimum values.
10471050 kerning .update (subtable .kernTable )
10481051 return kerning
1052+
1053+ # -----
1054+ # Color
1055+ # -----
1056+
1057+ COLOR_LAYERS_KEY = "com.github.googlei18n.ufo2ft.colorLayers"
1058+ COLOR_PALETTES_KEY = "com.github.googlei18n.ufo2ft.colorPalettes"
1059+ COLOR_LAYER_MAPPING_KEY = "com.github.googlei18n.ufo2ft.colorLayerMapping"
1060+ UFO2FT_FILTER_KEY = "com.github.googlei18n.ufo2ft.filters"
1061+ def extractColorsFromOpenType (
1062+ source ,
1063+ destination ,
1064+ ):
1065+ if not "CPAL" in source or not "COLR" in source : return
1066+ destination .lib [UFO2FT_FILTER_KEY ] = [{"name" : "Explode Color Layer Glyphs" , "pre" : True }]
1067+ # UFO format only supports one palette. Others ignored.
1068+ firstPalette = source ["CPAL" ].palettes [0 ]
1069+ colorIDs = list ()
1070+ for i , color in enumerate (firstPalette ):
1071+ colorIDs .append ((color .red / 255.0 , color .green / 255.0 , color .blue / 255.0 , color .alpha / 255.0 ))
1072+
1073+ destination .lib [COLOR_PALETTES_KEY ] = [[(color .red / 255.0 , color .green / 255.0 , color .blue / 255.0 , color .alpha / 255.0 ) for color in firstPalette ]]
1074+
1075+ layerGlyphs = list ()
1076+ for (base_glyph , layer_records ) in source ["COLR" ].ColorLayers .items ():
1077+ for i , layer_record in enumerate (layer_records ):
1078+ (name , colorID ) = (layer_record .name , layer_record .colorID )
1079+ layer_name = "color{}_layer{}" .format (colorID , i )
1080+ if not layer_name in destination .layers :
1081+ layer = destination .newLayer (layer_name )
1082+ layer ._set_color (colorIDs [colorID ])
1083+ glyph = destination [name ]
1084+ destination .layers [layer_name ].insertGlyph (glyph , name = base_glyph )
1085+ layerGlyphs .append (name )
1086+
1087+ for (base_glyph , layer_records ) in source ["COLR" ].ColorLayers .items ():
1088+ destination [base_glyph ].lib [COLOR_LAYER_MAPPING_KEY ] = [("color{}_layer{}" .format (lr .colorID , i ), lr .colorID ) for i , lr in enumerate (layer_records )]
1089+
1090+ for name in layerGlyphs :
1091+ if name in destination .layers .defaultLayer :
1092+ del destination .layers .defaultLayer [name ]
0 commit comments