55
66from fontTools .cu2qu .ufo import fonts_to_quadratic
77from fontTools import varLib
8+ from fontTools .ttLib import TTFont
89
910from fontPens .transformPointPen import TransformPointPen
1011
1718from batchGenerators .batchTools import postProcessCollector , WOFF2Builder , buildTree , removeTree , BatchEditorOperator
1819
1920
20- class VarLibMasterFinder (dict ):
21-
22- """
23- VarLib needs an argument mapping source UFOs to binary fonts.
24- A simple dict which is callable with an source UFO path returning
25- the binary font path.
26- """
27-
28- def __call__ (self , arg ):
29- return self .get (arg )
30-
3121
3222class GenerateVariableFont :
3323
@@ -46,18 +36,29 @@ def __init__(self, operator, destinationPath, autohint=False, fitToExtremes=Fals
4636 self .build ()
4737
4838 def build (self ):
39+ self .generatedFiles = set ()
40+
4941 self .operator .loadFonts (reload = True )
5042
5143 self .makeMasterGlyphsCompatible ()
5244 self .decomposedMixedGlyphs ()
53- if self .binaryFormat == "ttf" :
54- self .makeMasterGlyphsQuadractic ()
5545 self .makeMasterKerningCompatible ()
5646 self .makeMasterOnDefaultLocation ()
5747 self .makeLayerMaster ()
48+ if self .binaryFormat == "ttf" :
49+ self .makeMasterGlyphsQuadractic ()
5850
5951 self .generate ()
6052
53+ if not self .debug :
54+ # remove generated files
55+ for path in self .generatedFiles :
56+ if os .path .exists (path ):
57+ if os .path .isdir (path ):
58+ shutil .rmtree (path )
59+ else :
60+ os .remove (path )
61+
6162 def makeMasterGlyphsCompatible (self ):
6263 """
6364 Update all masters with missing glyphs.
@@ -285,15 +286,23 @@ def makeLayerMaster(self):
285286 """
286287 for sourceDescriptor in self .operator .sources :
287288 if sourceDescriptor .layerName is not None :
289+ layerName = sourceDescriptor .layerName
290+
288291 path , ext = os .path .splitext (sourceDescriptor .path )
289- sourceDescriptor .path = "%s-%s%s" % (path , sourceDescriptor .layerName , ext )
290- sourceDescriptor .styleName = "%s %s" % (sourceDescriptor .styleName , sourceDescriptor .layerName )
292+
293+ sourceDescriptor .path = os .path .join (os .path .dirname (self .destinationPath ), f"{ path } -{ layerName } { ext } " )
294+ sourceDescriptor .styleName = f"{ sourceDescriptor .styleName } { layerName } "
291295 sourceDescriptor .filename = None
292296 sourceDescriptor .layerName = None
293- if self .debug :
294- sourceFont = self .operator .fonts [sourceDescriptor .name ]
295- layerPath = os .path .join (os .path .dirname (self .destinationPath ), sourceDescriptor .path )
296- sourceFont .save (layerPath )
297+
298+ layeredSource = self .operator ._instantiateFont (sourceDescriptor .path )
299+ layeredSource .layers .defaultLayer = layeredSource .layers [layerName ]
300+ layeredSource .save (sourceDescriptor .path )
301+
302+ self .operator .fonts [sourceDescriptor .name ] = layeredSource
303+
304+ self .generatedFiles .add (sourceDescriptor .path )
305+
297306
298307 def generate (self ):
299308 dirname = os .path .dirname (self .destinationPath )
@@ -320,25 +329,34 @@ def generate(self):
320329 self .report .writeTitle (f"Generate { self .binaryFormat .upper ()} " , "'" )
321330 self .report .indent ()
322331
323- # map all master ufo paths to generated binaries
324- masterBinaryPaths = VarLibMasterFinder ()
325- generatedFiles = set ()
326-
327332 for sourceCount , sourceDescriptor in enumerate (self .operator .sources ):
328333 source = self .operator .fonts [sourceDescriptor .name ]
329334 # get the output path
330- outputPath = os .path .join (dirname , f"temp_{ sourceCount } _{ source .info .familyName } -{ source .info .styleName } .{ self .binaryFormat } " )
331- masterBinaryPaths [sourceDescriptor .path ] = outputPath
332- generatedFiles .add (outputPath )
335+ familyName = sourceDescriptor .familyName
336+ if not familyName :
337+ familyName = source .info .familyName
338+ styleName = sourceDescriptor .styleName
339+ if not styleName :
340+ styleName = source .info .styleName
341+ outputPath = os .path .join (dirname , f"temp_{ sourceCount } _{ familyName } -{ styleName } .{ self .binaryFormat } " )
342+ self .generatedFiles .add (outputPath )
333343 # set the output path
334344 options .outputPath = outputPath
345+ options .layerName = None
335346 if sourceDescriptor .layerName :
336347 options .layerName = sourceDescriptor .layerName
337348 # generate the font
338349 try :
339350 result = generateFont (source , options = options )
351+ sourceDescriptor .font = TTFont (outputPath )
352+ if sourceDescriptor .layerName :
353+ # https://github.com/googlefonts/ufo2ft/blob/150c2d6a00da9d5854173c8457a553ce03b89cf7/Lib/ufo2ft/_compilers/interpolatableTTFCompiler.py#L58-L66
354+ if "post" in sourceDescriptor .font :
355+ sourceDescriptor .font ["post" ].underlinePosition = - 0x8000
356+ sourceDescriptor .font ["post" ].underlineThickness = - 0x8000
357+
340358 if self .debug :
341- tempSavePath = os .path .join (dirname , f"temp_{ sourceCount } _{ source . info . familyName } -{ source . info . styleName } .ufo" )
359+ tempSavePath = os .path .join (dirname , f"temp_{ sourceCount } _{ familyName } -{ styleName } .ufo" )
342360 source .save (tempSavePath )
343361 if source .layers .defaultLayer .name != sourceDescriptor .layerName :
344362 tempFont = defcon .Font (tempSavePath )
@@ -350,41 +368,31 @@ def generate(self):
350368 result = f"Faild to generate: { e } :\n { tracebackResult } "
351369 print (tracebackResult )
352370 self .report .newLine ()
353- self .report .write (f"Generate failed { source . info . familyName } -{ source . info . styleName } " )
371+ self .report .write (f"Generate failed { familyName } -{ styleName } " )
354372 self .report .indent ()
355373 self .report .write (tracebackResult )
356374 self .report .dedent ()
357375
358376 self .report .newLine ()
359- self .report .write (f"Generate { source . info . familyName } -{ source . info . styleName } " )
377+ self .report .write (f"Generate { familyName } -{ styleName } " )
360378 self .report .write (result )
361379 self .report .dedent ()
362380
363381 # optimize the design space for varlib
364382 designSpacePath = os .path .join (dirname , f"{ self .destinationPath } .designspace" )
365383 self .operator .write (designSpacePath )
366- generatedFiles .add (designSpacePath )
384+ self .generatedFiles .add (designSpacePath )
385+
367386 try :
368387 # let varLib build the variation font
369- varFont , _ , _ = varLib .build (designSpacePath , master_finder = masterBinaryPaths )
388+ varFont , _ , _ = varLib .build (self . operator . doc )
370389 # save the variation font
371390 varFont .save (self .destinationPath )
372391 except Exception :
373- if self .debug :
374- print ("masterBinaryPaths:" , masterBinaryPaths )
375392 import traceback
376393 result = traceback .format_exc ()
377394 print (result )
378395
379- if not self .debug :
380- # remove generated files
381- for path in generatedFiles :
382- if os .path .exists (path ):
383- if os .path .isdir (path ):
384- shutil .rmtree (path )
385- else :
386- os .remove (path )
387-
388396
389397def build (root , generateOptions , settings , progress , report ):
390398
0 commit comments