@@ -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,41 @@ 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+ for i , color in enumerate (firstPalette ):
1070+ layer = destination .newLayer ("color{}" .format (i ))
1071+ layer ._set_color ((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 layer_record in layer_records :
1078+ (name , colorID ) = (layer_record .name , layer_record .colorID )
1079+ layer_name = "color{}" .format (colorID )
1080+ glyph = destination [name ]
1081+ destination .layers [layer_name ].insertGlyph (glyph , name = base_glyph )
1082+ layerGlyphs .append (name )
1083+
1084+ for (base_glyph , layer_records ) in source ["COLR" ].ColorLayers .items ():
1085+ destination [base_glyph ].lib [COLOR_LAYER_MAPPING_KEY ] = [("color{}" .format (lr .colorID ), lr .colorID ) for lr in layer_records ]
1086+
1087+ for name in layerGlyphs :
1088+ if name in destination .layers .defaultLayer :
1089+ del destination .layers .defaultLayer [name ]
0 commit comments