You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			109 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			109 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
from fontTools.varLib.models import normalizeValue
 | 
						|
 | 
						|
 | 
						|
def _denormalize(v, triplet):
 | 
						|
    if v >= 0:
 | 
						|
        return triplet[1] + v * (triplet[2] - triplet[1])
 | 
						|
    else:
 | 
						|
        return triplet[1] + v * (triplet[1] - triplet[0])
 | 
						|
 | 
						|
 | 
						|
def map(
 | 
						|
    font, location, *, inputNormalized=False, outputNormalized=False, dropZeroes=False
 | 
						|
):
 | 
						|
    if "fvar" not in font:
 | 
						|
        return None
 | 
						|
 | 
						|
    fvar = font["fvar"]
 | 
						|
    axes = {a.axisTag: (a.minValue, a.defaultValue, a.maxValue) for a in fvar.axes}
 | 
						|
 | 
						|
    if not inputNormalized:
 | 
						|
        location = {
 | 
						|
            tag: normalizeValue(value, axes[tag]) for tag, value in location.items()
 | 
						|
        }
 | 
						|
 | 
						|
    if "avar" in font:
 | 
						|
        location = font["avar"].renormalizeLocation(location, font, dropZeroes)
 | 
						|
 | 
						|
    if not outputNormalized:
 | 
						|
        location = {
 | 
						|
            tag: _denormalize(value, axes[tag]) for tag, value in location.items()
 | 
						|
        }
 | 
						|
 | 
						|
    return location
 | 
						|
 | 
						|
 | 
						|
def main(args=None):
 | 
						|
    """Map variation coordinates through the `avar` table."""
 | 
						|
 | 
						|
    from fontTools.ttLib import TTFont
 | 
						|
    import argparse
 | 
						|
 | 
						|
    if args is None:
 | 
						|
        import sys
 | 
						|
 | 
						|
        args = sys.argv[1:]
 | 
						|
 | 
						|
    parser = argparse.ArgumentParser(
 | 
						|
        "fonttools varLib.avar.map",
 | 
						|
        description="Map variation coordinates through the `avar` table.",
 | 
						|
    )
 | 
						|
    parser.add_argument("font", metavar="varfont.ttf", help="Variable-font file.")
 | 
						|
    parser.add_argument(
 | 
						|
        "coords",
 | 
						|
        metavar="[AXIS=value...]",
 | 
						|
        help="Coordinates to map, e.g. 'wght=700 wdth=75'.",
 | 
						|
        nargs="*",
 | 
						|
        default=None,
 | 
						|
    )
 | 
						|
    parser.add_argument(
 | 
						|
        "-f", action="store_true", help="Do not omit axes at default location."
 | 
						|
    )
 | 
						|
    parser.add_argument(
 | 
						|
        "-i", action="store_true", help="Input coordinates are normalized (-1..1)."
 | 
						|
    )
 | 
						|
    parser.add_argument(
 | 
						|
        "-o", action="store_true", help="Output coordinates as normalized (-1..1)."
 | 
						|
    )
 | 
						|
 | 
						|
    options = parser.parse_args(args)
 | 
						|
 | 
						|
    if not options.coords:
 | 
						|
        parser.error(
 | 
						|
            "No coordinates provided. Please specify at least one axis coordinate (e.g., wght=500)"
 | 
						|
        )
 | 
						|
 | 
						|
    if options.font.endswith(".designspace"):
 | 
						|
        from .build import build
 | 
						|
 | 
						|
        font = TTFont()
 | 
						|
        build(font, options.font)
 | 
						|
    else:
 | 
						|
        font = TTFont(options.font)
 | 
						|
        if "fvar" not in font:
 | 
						|
            parser.error(f"Font '{options.font}' does not contain an 'fvar' table.")
 | 
						|
 | 
						|
    location = {
 | 
						|
        tag: float(value) for tag, value in (item.split("=") for item in options.coords)
 | 
						|
    }
 | 
						|
 | 
						|
    mapped = map(
 | 
						|
        font,
 | 
						|
        location,
 | 
						|
        inputNormalized=options.i,
 | 
						|
        outputNormalized=options.o,
 | 
						|
        dropZeroes=not options.f,
 | 
						|
    )
 | 
						|
    assert mapped is not None
 | 
						|
 | 
						|
    for tag in mapped:
 | 
						|
        v = mapped[tag]
 | 
						|
        v = int(v) if v == int(v) else v
 | 
						|
        print(f"{tag}={v:g}")
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    import sys
 | 
						|
 | 
						|
    sys.exit(main())
 |