1*e1fe3e4aSElliott Hughesimport re 2*e1fe3e4aSElliott Hughesimport shutil 3*e1fe3e4aSElliott Hughesfrom pathlib import Path 4*e1fe3e4aSElliott Hughes 5*e1fe3e4aSElliott Hughesimport pytest 6*e1fe3e4aSElliott Hughesfrom fontTools.designspaceLib import ( 7*e1fe3e4aSElliott Hughes AxisDescriptor, 8*e1fe3e4aSElliott Hughes AxisLabelDescriptor, 9*e1fe3e4aSElliott Hughes DesignSpaceDocument, 10*e1fe3e4aSElliott Hughes DiscreteAxisDescriptor, 11*e1fe3e4aSElliott Hughes InstanceDescriptor, 12*e1fe3e4aSElliott Hughes LocationLabelDescriptor, 13*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor, 14*e1fe3e4aSElliott Hughes SourceDescriptor, 15*e1fe3e4aSElliott Hughes ValueAxisSubsetDescriptor, 16*e1fe3e4aSElliott Hughes VariableFontDescriptor, 17*e1fe3e4aSElliott Hughes posix, 18*e1fe3e4aSElliott Hughes) 19*e1fe3e4aSElliott Hughes 20*e1fe3e4aSElliott Hughesfrom .fixtures import datadir 21*e1fe3e4aSElliott Hughes 22*e1fe3e4aSElliott Hughes 23*e1fe3e4aSElliott Hughesdef assert_descriptors_equal(actual, expected): 24*e1fe3e4aSElliott Hughes assert len(actual) == len(expected) 25*e1fe3e4aSElliott Hughes for a, e in zip(actual, expected): 26*e1fe3e4aSElliott Hughes assert a.asdict() == e.asdict() 27*e1fe3e4aSElliott Hughes 28*e1fe3e4aSElliott Hughes 29*e1fe3e4aSElliott Hughesdef test_read_v5_document_simple(datadir): 30*e1fe3e4aSElliott Hughes doc = DesignSpaceDocument.fromfile(datadir / "test_v5.designspace") 31*e1fe3e4aSElliott Hughes 32*e1fe3e4aSElliott Hughes assert_descriptors_equal( 33*e1fe3e4aSElliott Hughes doc.axes, 34*e1fe3e4aSElliott Hughes [ 35*e1fe3e4aSElliott Hughes AxisDescriptor( 36*e1fe3e4aSElliott Hughes tag="wght", 37*e1fe3e4aSElliott Hughes name="Weight", 38*e1fe3e4aSElliott Hughes minimum=200, 39*e1fe3e4aSElliott Hughes maximum=1000, 40*e1fe3e4aSElliott Hughes default=200, 41*e1fe3e4aSElliott Hughes labelNames={"en": "Wéíght", "fa-IR": "قطر"}, 42*e1fe3e4aSElliott Hughes map=[ 43*e1fe3e4aSElliott Hughes (200, 0), 44*e1fe3e4aSElliott Hughes (300, 100), 45*e1fe3e4aSElliott Hughes (400, 368), 46*e1fe3e4aSElliott Hughes (600, 600), 47*e1fe3e4aSElliott Hughes (700, 824), 48*e1fe3e4aSElliott Hughes (900, 1000), 49*e1fe3e4aSElliott Hughes ], 50*e1fe3e4aSElliott Hughes axisOrdering=None, 51*e1fe3e4aSElliott Hughes axisLabels=[ 52*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 53*e1fe3e4aSElliott Hughes name="Extra Light", 54*e1fe3e4aSElliott Hughes userMinimum=200, 55*e1fe3e4aSElliott Hughes userValue=200, 56*e1fe3e4aSElliott Hughes userMaximum=250, 57*e1fe3e4aSElliott Hughes labelNames={"de": "Extraleicht", "fr": "Extra léger"}, 58*e1fe3e4aSElliott Hughes ), 59*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 60*e1fe3e4aSElliott Hughes name="Light", userMinimum=250, userValue=300, userMaximum=350 61*e1fe3e4aSElliott Hughes ), 62*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 63*e1fe3e4aSElliott Hughes name="Regular", 64*e1fe3e4aSElliott Hughes userMinimum=350, 65*e1fe3e4aSElliott Hughes userValue=400, 66*e1fe3e4aSElliott Hughes userMaximum=450, 67*e1fe3e4aSElliott Hughes elidable=True, 68*e1fe3e4aSElliott Hughes ), 69*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 70*e1fe3e4aSElliott Hughes name="Semi Bold", 71*e1fe3e4aSElliott Hughes userMinimum=450, 72*e1fe3e4aSElliott Hughes userValue=600, 73*e1fe3e4aSElliott Hughes userMaximum=650, 74*e1fe3e4aSElliott Hughes ), 75*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 76*e1fe3e4aSElliott Hughes name="Bold", userMinimum=650, userValue=700, userMaximum=850 77*e1fe3e4aSElliott Hughes ), 78*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 79*e1fe3e4aSElliott Hughes name="Black", userMinimum=850, userValue=900, userMaximum=900 80*e1fe3e4aSElliott Hughes ), 81*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 82*e1fe3e4aSElliott Hughes name="Regular", 83*e1fe3e4aSElliott Hughes userValue=400, 84*e1fe3e4aSElliott Hughes linkedUserValue=700, 85*e1fe3e4aSElliott Hughes elidable=True, 86*e1fe3e4aSElliott Hughes ), 87*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 88*e1fe3e4aSElliott Hughes name="Bold", userValue=700, linkedUserValue=400 89*e1fe3e4aSElliott Hughes ), 90*e1fe3e4aSElliott Hughes ], 91*e1fe3e4aSElliott Hughes ), 92*e1fe3e4aSElliott Hughes AxisDescriptor( 93*e1fe3e4aSElliott Hughes tag="wdth", 94*e1fe3e4aSElliott Hughes name="Width", 95*e1fe3e4aSElliott Hughes minimum=50, 96*e1fe3e4aSElliott Hughes maximum=150, 97*e1fe3e4aSElliott Hughes default=100, 98*e1fe3e4aSElliott Hughes hidden=True, 99*e1fe3e4aSElliott Hughes labelNames={"fr": "Chasse"}, 100*e1fe3e4aSElliott Hughes map=[(50, 10), (100, 20), (125, 66), (150, 990)], 101*e1fe3e4aSElliott Hughes axisOrdering=1, 102*e1fe3e4aSElliott Hughes axisLabels=[ 103*e1fe3e4aSElliott Hughes AxisLabelDescriptor(name="Condensed", userValue=50), 104*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 105*e1fe3e4aSElliott Hughes name="Normal", elidable=True, olderSibling=True, userValue=100 106*e1fe3e4aSElliott Hughes ), 107*e1fe3e4aSElliott Hughes AxisLabelDescriptor(name="Wide", userValue=125), 108*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 109*e1fe3e4aSElliott Hughes name="Extra Wide", userValue=150, userMinimum=150 110*e1fe3e4aSElliott Hughes ), 111*e1fe3e4aSElliott Hughes ], 112*e1fe3e4aSElliott Hughes ), 113*e1fe3e4aSElliott Hughes DiscreteAxisDescriptor( 114*e1fe3e4aSElliott Hughes tag="ital", 115*e1fe3e4aSElliott Hughes name="Italic", 116*e1fe3e4aSElliott Hughes values=[0, 1], 117*e1fe3e4aSElliott Hughes default=0, 118*e1fe3e4aSElliott Hughes axisOrdering=None, 119*e1fe3e4aSElliott Hughes axisLabels=[ 120*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 121*e1fe3e4aSElliott Hughes name="Roman", userValue=0, elidable=True, linkedUserValue=1 122*e1fe3e4aSElliott Hughes ), 123*e1fe3e4aSElliott Hughes AxisLabelDescriptor(name="Italic", userValue=1), 124*e1fe3e4aSElliott Hughes ], 125*e1fe3e4aSElliott Hughes ), 126*e1fe3e4aSElliott Hughes ], 127*e1fe3e4aSElliott Hughes ) 128*e1fe3e4aSElliott Hughes 129*e1fe3e4aSElliott Hughes assert_descriptors_equal( 130*e1fe3e4aSElliott Hughes doc.locationLabels, 131*e1fe3e4aSElliott Hughes [ 132*e1fe3e4aSElliott Hughes LocationLabelDescriptor( 133*e1fe3e4aSElliott Hughes name="Some Style", 134*e1fe3e4aSElliott Hughes labelNames={"fr": "Un Style"}, 135*e1fe3e4aSElliott Hughes userLocation={"Weight": 300, "Width": 50, "Italic": 0}, 136*e1fe3e4aSElliott Hughes ), 137*e1fe3e4aSElliott Hughes LocationLabelDescriptor( 138*e1fe3e4aSElliott Hughes name="Other", userLocation={"Weight": 700, "Width": 100, "Italic": 1} 139*e1fe3e4aSElliott Hughes ), 140*e1fe3e4aSElliott Hughes ], 141*e1fe3e4aSElliott Hughes ) 142*e1fe3e4aSElliott Hughes 143*e1fe3e4aSElliott Hughes assert_descriptors_equal( 144*e1fe3e4aSElliott Hughes doc.sources, 145*e1fe3e4aSElliott Hughes [ 146*e1fe3e4aSElliott Hughes SourceDescriptor( 147*e1fe3e4aSElliott Hughes filename="masters/masterTest1.ufo", 148*e1fe3e4aSElliott Hughes path=posix(str((datadir / "masters/masterTest1.ufo").resolve())), 149*e1fe3e4aSElliott Hughes name="master.ufo1", 150*e1fe3e4aSElliott Hughes layerName=None, 151*e1fe3e4aSElliott Hughes location={"Italic": 0.0, "Weight": 0.0, "Width": 20.0}, 152*e1fe3e4aSElliott Hughes copyLib=True, 153*e1fe3e4aSElliott Hughes copyInfo=True, 154*e1fe3e4aSElliott Hughes copyGroups=False, 155*e1fe3e4aSElliott Hughes copyFeatures=True, 156*e1fe3e4aSElliott Hughes muteKerning=False, 157*e1fe3e4aSElliott Hughes muteInfo=False, 158*e1fe3e4aSElliott Hughes mutedGlyphNames=["A", "Z"], 159*e1fe3e4aSElliott Hughes familyName="MasterFamilyName", 160*e1fe3e4aSElliott Hughes styleName="MasterStyleNameOne", 161*e1fe3e4aSElliott Hughes localisedFamilyName={"fr": "Montserrat", "ja": "モンセラート"}, 162*e1fe3e4aSElliott Hughes ), 163*e1fe3e4aSElliott Hughes SourceDescriptor( 164*e1fe3e4aSElliott Hughes filename="masters/masterTest2.ufo", 165*e1fe3e4aSElliott Hughes path=posix(str((datadir / "masters/masterTest2.ufo").resolve())), 166*e1fe3e4aSElliott Hughes name="master.ufo2", 167*e1fe3e4aSElliott Hughes layerName=None, 168*e1fe3e4aSElliott Hughes location={"Italic": 0.0, "Weight": 1000.0, "Width": 20.0}, 169*e1fe3e4aSElliott Hughes copyLib=False, 170*e1fe3e4aSElliott Hughes copyInfo=False, 171*e1fe3e4aSElliott Hughes copyGroups=False, 172*e1fe3e4aSElliott Hughes copyFeatures=False, 173*e1fe3e4aSElliott Hughes muteKerning=True, 174*e1fe3e4aSElliott Hughes muteInfo=False, 175*e1fe3e4aSElliott Hughes mutedGlyphNames=[], 176*e1fe3e4aSElliott Hughes familyName="MasterFamilyName", 177*e1fe3e4aSElliott Hughes styleName="MasterStyleNameTwo", 178*e1fe3e4aSElliott Hughes localisedFamilyName={}, 179*e1fe3e4aSElliott Hughes ), 180*e1fe3e4aSElliott Hughes SourceDescriptor( 181*e1fe3e4aSElliott Hughes filename="masters/masterTest2.ufo", 182*e1fe3e4aSElliott Hughes path=posix(str((datadir / "masters/masterTest2.ufo").resolve())), 183*e1fe3e4aSElliott Hughes name="master.ufo2", 184*e1fe3e4aSElliott Hughes layerName="supports", 185*e1fe3e4aSElliott Hughes location={"Italic": 0.0, "Weight": 1000.0, "Width": 20.0}, 186*e1fe3e4aSElliott Hughes copyLib=False, 187*e1fe3e4aSElliott Hughes copyInfo=False, 188*e1fe3e4aSElliott Hughes copyGroups=False, 189*e1fe3e4aSElliott Hughes copyFeatures=False, 190*e1fe3e4aSElliott Hughes muteKerning=False, 191*e1fe3e4aSElliott Hughes muteInfo=False, 192*e1fe3e4aSElliott Hughes mutedGlyphNames=[], 193*e1fe3e4aSElliott Hughes familyName="MasterFamilyName", 194*e1fe3e4aSElliott Hughes styleName="Supports", 195*e1fe3e4aSElliott Hughes localisedFamilyName={}, 196*e1fe3e4aSElliott Hughes ), 197*e1fe3e4aSElliott Hughes SourceDescriptor( 198*e1fe3e4aSElliott Hughes filename="masters/masterTest2.ufo", 199*e1fe3e4aSElliott Hughes path=posix(str((datadir / "masters/masterTest2.ufo").resolve())), 200*e1fe3e4aSElliott Hughes name="master.ufo3", 201*e1fe3e4aSElliott Hughes layerName=None, 202*e1fe3e4aSElliott Hughes location={"Italic": 1.0, "Weight": 0.0, "Width": 100.0}, 203*e1fe3e4aSElliott Hughes copyLib=False, 204*e1fe3e4aSElliott Hughes copyGroups=False, 205*e1fe3e4aSElliott Hughes copyFeatures=False, 206*e1fe3e4aSElliott Hughes muteKerning=False, 207*e1fe3e4aSElliott Hughes muteInfo=False, 208*e1fe3e4aSElliott Hughes mutedGlyphNames=[], 209*e1fe3e4aSElliott Hughes familyName="MasterFamilyName", 210*e1fe3e4aSElliott Hughes styleName="FauxItalic", 211*e1fe3e4aSElliott Hughes localisedFamilyName={}, 212*e1fe3e4aSElliott Hughes ), 213*e1fe3e4aSElliott Hughes ], 214*e1fe3e4aSElliott Hughes ) 215*e1fe3e4aSElliott Hughes 216*e1fe3e4aSElliott Hughes assert_descriptors_equal( 217*e1fe3e4aSElliott Hughes doc.variableFonts, 218*e1fe3e4aSElliott Hughes [ 219*e1fe3e4aSElliott Hughes VariableFontDescriptor( 220*e1fe3e4aSElliott Hughes name="Test_WghtWdth", 221*e1fe3e4aSElliott Hughes filename="Test_WghtWdth_different_from_name.ttf", 222*e1fe3e4aSElliott Hughes axisSubsets=[ 223*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor(name="Weight"), 224*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor(name="Width"), 225*e1fe3e4aSElliott Hughes ], 226*e1fe3e4aSElliott Hughes lib={"com.vtt.source": "sources/vtt/Test_WghtWdth.vtt"}, 227*e1fe3e4aSElliott Hughes ), 228*e1fe3e4aSElliott Hughes VariableFontDescriptor( 229*e1fe3e4aSElliott Hughes name="Test_Wght", 230*e1fe3e4aSElliott Hughes axisSubsets=[RangeAxisSubsetDescriptor(name="Weight")], 231*e1fe3e4aSElliott Hughes lib={"com.vtt.source": "sources/vtt/Test_Wght.vtt"}, 232*e1fe3e4aSElliott Hughes ), 233*e1fe3e4aSElliott Hughes VariableFontDescriptor( 234*e1fe3e4aSElliott Hughes name="TestCd_Wght", 235*e1fe3e4aSElliott Hughes axisSubsets=[ 236*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor(name="Weight"), 237*e1fe3e4aSElliott Hughes ValueAxisSubsetDescriptor(name="Width", userValue=0), 238*e1fe3e4aSElliott Hughes ], 239*e1fe3e4aSElliott Hughes ), 240*e1fe3e4aSElliott Hughes VariableFontDescriptor( 241*e1fe3e4aSElliott Hughes name="TestWd_Wght", 242*e1fe3e4aSElliott Hughes axisSubsets=[ 243*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor(name="Weight"), 244*e1fe3e4aSElliott Hughes ValueAxisSubsetDescriptor(name="Width", userValue=1000), 245*e1fe3e4aSElliott Hughes ], 246*e1fe3e4aSElliott Hughes ), 247*e1fe3e4aSElliott Hughes VariableFontDescriptor( 248*e1fe3e4aSElliott Hughes name="TestItalic_Wght", 249*e1fe3e4aSElliott Hughes axisSubsets=[ 250*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor(name="Weight"), 251*e1fe3e4aSElliott Hughes ValueAxisSubsetDescriptor(name="Italic", userValue=1), 252*e1fe3e4aSElliott Hughes ], 253*e1fe3e4aSElliott Hughes ), 254*e1fe3e4aSElliott Hughes VariableFontDescriptor( 255*e1fe3e4aSElliott Hughes name="TestRB_Wght", 256*e1fe3e4aSElliott Hughes axisSubsets=[ 257*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor( 258*e1fe3e4aSElliott Hughes name="Weight", userMinimum=400, userDefault=400, userMaximum=700 259*e1fe3e4aSElliott Hughes ), 260*e1fe3e4aSElliott Hughes ValueAxisSubsetDescriptor(name="Italic", userValue=0), 261*e1fe3e4aSElliott Hughes ], 262*e1fe3e4aSElliott Hughes ), 263*e1fe3e4aSElliott Hughes ], 264*e1fe3e4aSElliott Hughes ) 265*e1fe3e4aSElliott Hughes 266*e1fe3e4aSElliott Hughes assert_descriptors_equal( 267*e1fe3e4aSElliott Hughes doc.instances, 268*e1fe3e4aSElliott Hughes [ 269*e1fe3e4aSElliott Hughes InstanceDescriptor( 270*e1fe3e4aSElliott Hughes filename="instances/instanceTest1.ufo", 271*e1fe3e4aSElliott Hughes path=posix(str((datadir / "instances/instanceTest1.ufo").resolve())), 272*e1fe3e4aSElliott Hughes name="instance.ufo1", 273*e1fe3e4aSElliott Hughes designLocation={"Weight": 500.0, "Width": 20.0}, 274*e1fe3e4aSElliott Hughes familyName="InstanceFamilyName", 275*e1fe3e4aSElliott Hughes styleName="InstanceStyleName", 276*e1fe3e4aSElliott Hughes postScriptFontName="InstancePostscriptName", 277*e1fe3e4aSElliott Hughes styleMapFamilyName="InstanceStyleMapFamilyName", 278*e1fe3e4aSElliott Hughes styleMapStyleName="InstanceStyleMapStyleName", 279*e1fe3e4aSElliott Hughes localisedFamilyName={"fr": "Montserrat", "ja": "モンセラート"}, 280*e1fe3e4aSElliott Hughes localisedStyleName={"fr": "Demigras", "ja": "半ば"}, 281*e1fe3e4aSElliott Hughes localisedStyleMapFamilyName={ 282*e1fe3e4aSElliott Hughes "de": "Montserrat Halbfett", 283*e1fe3e4aSElliott Hughes "ja": "モンセラート SemiBold", 284*e1fe3e4aSElliott Hughes }, 285*e1fe3e4aSElliott Hughes localisedStyleMapStyleName={"de": "Standard"}, 286*e1fe3e4aSElliott Hughes glyphs={"arrow": {"mute": True, "unicodes": [291, 292, 293]}}, 287*e1fe3e4aSElliott Hughes lib={ 288*e1fe3e4aSElliott Hughes "com.coolDesignspaceApp.binaryData": b"<binary gunk>", 289*e1fe3e4aSElliott Hughes "com.coolDesignspaceApp.specimenText": "Hamburgerwhatever", 290*e1fe3e4aSElliott Hughes }, 291*e1fe3e4aSElliott Hughes ), 292*e1fe3e4aSElliott Hughes InstanceDescriptor( 293*e1fe3e4aSElliott Hughes filename="instances/instanceTest2.ufo", 294*e1fe3e4aSElliott Hughes path=posix(str((datadir / "instances/instanceTest2.ufo").resolve())), 295*e1fe3e4aSElliott Hughes name="instance.ufo2", 296*e1fe3e4aSElliott Hughes designLocation={"Weight": 500.0, "Width": (400.0, 300.0)}, 297*e1fe3e4aSElliott Hughes familyName="InstanceFamilyName", 298*e1fe3e4aSElliott Hughes styleName="InstanceStyleName", 299*e1fe3e4aSElliott Hughes postScriptFontName="InstancePostscriptName", 300*e1fe3e4aSElliott Hughes styleMapFamilyName="InstanceStyleMapFamilyName", 301*e1fe3e4aSElliott Hughes styleMapStyleName="InstanceStyleMapStyleName", 302*e1fe3e4aSElliott Hughes glyphs={ 303*e1fe3e4aSElliott Hughes "arrow": { 304*e1fe3e4aSElliott Hughes "unicodes": [101, 201, 301], 305*e1fe3e4aSElliott Hughes "note": "A note about this glyph", 306*e1fe3e4aSElliott Hughes "instanceLocation": {"Weight": 120.0, "Width": 100.0}, 307*e1fe3e4aSElliott Hughes "masters": [ 308*e1fe3e4aSElliott Hughes { 309*e1fe3e4aSElliott Hughes "font": "master.ufo1", 310*e1fe3e4aSElliott Hughes "location": {"Weight": 20.0, "Width": 20.0}, 311*e1fe3e4aSElliott Hughes "glyphName": "BB", 312*e1fe3e4aSElliott Hughes }, 313*e1fe3e4aSElliott Hughes { 314*e1fe3e4aSElliott Hughes "font": "master.ufo2", 315*e1fe3e4aSElliott Hughes "location": {"Weight": 900.0, "Width": 900.0}, 316*e1fe3e4aSElliott Hughes "glyphName": "CC", 317*e1fe3e4aSElliott Hughes }, 318*e1fe3e4aSElliott Hughes ], 319*e1fe3e4aSElliott Hughes }, 320*e1fe3e4aSElliott Hughes "arrow2": {}, 321*e1fe3e4aSElliott Hughes }, 322*e1fe3e4aSElliott Hughes ), 323*e1fe3e4aSElliott Hughes InstanceDescriptor( 324*e1fe3e4aSElliott Hughes locationLabel="Some Style", 325*e1fe3e4aSElliott Hughes ), 326*e1fe3e4aSElliott Hughes InstanceDescriptor( 327*e1fe3e4aSElliott Hughes designLocation={"Weight": 600.0, "Width": (401.0, 420.0)}, 328*e1fe3e4aSElliott Hughes ), 329*e1fe3e4aSElliott Hughes InstanceDescriptor( 330*e1fe3e4aSElliott Hughes designLocation={"Weight": 10.0, "Italic": 0.0}, 331*e1fe3e4aSElliott Hughes userLocation={"Width": 100.0}, 332*e1fe3e4aSElliott Hughes ), 333*e1fe3e4aSElliott Hughes InstanceDescriptor( 334*e1fe3e4aSElliott Hughes userLocation={"Weight": 300.0, "Width": 130.0, "Italic": 1.0}, 335*e1fe3e4aSElliott Hughes ), 336*e1fe3e4aSElliott Hughes ], 337*e1fe3e4aSElliott Hughes ) 338*e1fe3e4aSElliott Hughes 339*e1fe3e4aSElliott Hughes 340*e1fe3e4aSElliott Hughesdef test_read_v5_document_decovar(datadir): 341*e1fe3e4aSElliott Hughes doc = DesignSpaceDocument.fromfile(datadir / "test_v5_decovar.designspace") 342*e1fe3e4aSElliott Hughes 343*e1fe3e4aSElliott Hughes assert not doc.variableFonts 344*e1fe3e4aSElliott Hughes 345*e1fe3e4aSElliott Hughes assert_descriptors_equal( 346*e1fe3e4aSElliott Hughes doc.axes, 347*e1fe3e4aSElliott Hughes [ 348*e1fe3e4aSElliott Hughes AxisDescriptor( 349*e1fe3e4aSElliott Hughes default=0, maximum=1000, minimum=0, name="Inline", tag="BLDA" 350*e1fe3e4aSElliott Hughes ), 351*e1fe3e4aSElliott Hughes AxisDescriptor( 352*e1fe3e4aSElliott Hughes default=0, maximum=1000, minimum=0, name="Shearded", tag="TRMD" 353*e1fe3e4aSElliott Hughes ), 354*e1fe3e4aSElliott Hughes AxisDescriptor( 355*e1fe3e4aSElliott Hughes default=0, maximum=1000, minimum=0, name="Rounded Slab", tag="TRMC" 356*e1fe3e4aSElliott Hughes ), 357*e1fe3e4aSElliott Hughes AxisDescriptor( 358*e1fe3e4aSElliott Hughes default=0, maximum=1000, minimum=0, name="Stripes", tag="SKLD" 359*e1fe3e4aSElliott Hughes ), 360*e1fe3e4aSElliott Hughes AxisDescriptor( 361*e1fe3e4aSElliott Hughes default=0, maximum=1000, minimum=0, name="Worm Terminal", tag="TRML" 362*e1fe3e4aSElliott Hughes ), 363*e1fe3e4aSElliott Hughes AxisDescriptor( 364*e1fe3e4aSElliott Hughes default=0, maximum=1000, minimum=0, name="Inline Skeleton", tag="SKLA" 365*e1fe3e4aSElliott Hughes ), 366*e1fe3e4aSElliott Hughes AxisDescriptor( 367*e1fe3e4aSElliott Hughes default=0, 368*e1fe3e4aSElliott Hughes maximum=1000, 369*e1fe3e4aSElliott Hughes minimum=0, 370*e1fe3e4aSElliott Hughes name="Open Inline Terminal", 371*e1fe3e4aSElliott Hughes tag="TRMF", 372*e1fe3e4aSElliott Hughes ), 373*e1fe3e4aSElliott Hughes AxisDescriptor( 374*e1fe3e4aSElliott Hughes default=0, maximum=1000, minimum=0, name="Inline Terminal", tag="TRMK" 375*e1fe3e4aSElliott Hughes ), 376*e1fe3e4aSElliott Hughes AxisDescriptor(default=0, maximum=1000, minimum=0, name="Worm", tag="BLDB"), 377*e1fe3e4aSElliott Hughes AxisDescriptor( 378*e1fe3e4aSElliott Hughes default=0, maximum=1000, minimum=0, name="Weight", tag="WMX2" 379*e1fe3e4aSElliott Hughes ), 380*e1fe3e4aSElliott Hughes AxisDescriptor( 381*e1fe3e4aSElliott Hughes default=0, maximum=1000, minimum=0, name="Flared", tag="TRMB" 382*e1fe3e4aSElliott Hughes ), 383*e1fe3e4aSElliott Hughes AxisDescriptor( 384*e1fe3e4aSElliott Hughes default=0, maximum=1000, minimum=0, name="Rounded", tag="TRMA" 385*e1fe3e4aSElliott Hughes ), 386*e1fe3e4aSElliott Hughes AxisDescriptor( 387*e1fe3e4aSElliott Hughes default=0, maximum=1000, minimum=0, name="Worm Skeleton", tag="SKLB" 388*e1fe3e4aSElliott Hughes ), 389*e1fe3e4aSElliott Hughes AxisDescriptor(default=0, maximum=1000, minimum=0, name="Slab", tag="TRMG"), 390*e1fe3e4aSElliott Hughes AxisDescriptor( 391*e1fe3e4aSElliott Hughes default=0, maximum=1000, minimum=0, name="Bifurcated", tag="TRME" 392*e1fe3e4aSElliott Hughes ), 393*e1fe3e4aSElliott Hughes ], 394*e1fe3e4aSElliott Hughes ) 395*e1fe3e4aSElliott Hughes 396*e1fe3e4aSElliott Hughes assert_descriptors_equal( 397*e1fe3e4aSElliott Hughes doc.locationLabels, 398*e1fe3e4aSElliott Hughes [ 399*e1fe3e4aSElliott Hughes LocationLabelDescriptor(name="Default", elidable=True, userLocation={}), 400*e1fe3e4aSElliott Hughes LocationLabelDescriptor( 401*e1fe3e4aSElliott Hughes name="Open", userLocation={"Inline": 1000}, labelNames={"de": "Offen"} 402*e1fe3e4aSElliott Hughes ), 403*e1fe3e4aSElliott Hughes LocationLabelDescriptor(name="Worm", userLocation={"Worm": 1000}), 404*e1fe3e4aSElliott Hughes LocationLabelDescriptor( 405*e1fe3e4aSElliott Hughes name="Checkered", userLocation={"Inline Skeleton": 1000} 406*e1fe3e4aSElliott Hughes ), 407*e1fe3e4aSElliott Hughes LocationLabelDescriptor( 408*e1fe3e4aSElliott Hughes name="Checkered Reverse", userLocation={"Inline Terminal": 1000} 409*e1fe3e4aSElliott Hughes ), 410*e1fe3e4aSElliott Hughes LocationLabelDescriptor(name="Striped", userLocation={"Stripes": 500}), 411*e1fe3e4aSElliott Hughes LocationLabelDescriptor(name="Rounded", userLocation={"Rounded": 1000}), 412*e1fe3e4aSElliott Hughes LocationLabelDescriptor(name="Flared", userLocation={"Flared": 1000}), 413*e1fe3e4aSElliott Hughes LocationLabelDescriptor( 414*e1fe3e4aSElliott Hughes name="Flared Open", 415*e1fe3e4aSElliott Hughes userLocation={"Inline Skeleton": 1000, "Flared": 1000}, 416*e1fe3e4aSElliott Hughes ), 417*e1fe3e4aSElliott Hughes LocationLabelDescriptor( 418*e1fe3e4aSElliott Hughes name="Rounded Slab", userLocation={"Rounded Slab": 1000} 419*e1fe3e4aSElliott Hughes ), 420*e1fe3e4aSElliott Hughes LocationLabelDescriptor(name="Sheared", userLocation={"Shearded": 1000}), 421*e1fe3e4aSElliott Hughes LocationLabelDescriptor( 422*e1fe3e4aSElliott Hughes name="Bifurcated", userLocation={"Bifurcated": 1000} 423*e1fe3e4aSElliott Hughes ), 424*e1fe3e4aSElliott Hughes LocationLabelDescriptor( 425*e1fe3e4aSElliott Hughes name="Inline", 426*e1fe3e4aSElliott Hughes userLocation={"Inline Skeleton": 500, "Open Inline Terminal": 500}, 427*e1fe3e4aSElliott Hughes ), 428*e1fe3e4aSElliott Hughes LocationLabelDescriptor(name="Slab", userLocation={"Slab": 1000}), 429*e1fe3e4aSElliott Hughes LocationLabelDescriptor(name="Contrast", userLocation={"Weight": 1000}), 430*e1fe3e4aSElliott Hughes LocationLabelDescriptor( 431*e1fe3e4aSElliott Hughes name="Fancy", 432*e1fe3e4aSElliott Hughes userLocation={"Inline Skeleton": 1000, "Flared": 1000, "Weight": 1000}, 433*e1fe3e4aSElliott Hughes ), 434*e1fe3e4aSElliott Hughes LocationLabelDescriptor( 435*e1fe3e4aSElliott Hughes name="Mayhem", 436*e1fe3e4aSElliott Hughes userLocation={ 437*e1fe3e4aSElliott Hughes "Inline Skeleton": 1000, 438*e1fe3e4aSElliott Hughes "Worm Skeleton": 1000, 439*e1fe3e4aSElliott Hughes "Rounded": 500, 440*e1fe3e4aSElliott Hughes "Flared": 500, 441*e1fe3e4aSElliott Hughes "Rounded Slab": 750, 442*e1fe3e4aSElliott Hughes "Bifurcated": 500, 443*e1fe3e4aSElliott Hughes "Open Inline Terminal": 250, 444*e1fe3e4aSElliott Hughes "Slab": 750, 445*e1fe3e4aSElliott Hughes "Inline Terminal": 250, 446*e1fe3e4aSElliott Hughes "Worm Terminal": 250, 447*e1fe3e4aSElliott Hughes "Weight": 750, 448*e1fe3e4aSElliott Hughes "Worm": 1000, 449*e1fe3e4aSElliott Hughes }, 450*e1fe3e4aSElliott Hughes ), 451*e1fe3e4aSElliott Hughes ], 452*e1fe3e4aSElliott Hughes ) 453*e1fe3e4aSElliott Hughes 454*e1fe3e4aSElliott Hughes assert [i.locationLabel for i in doc.instances] == [ 455*e1fe3e4aSElliott Hughes "Default", 456*e1fe3e4aSElliott Hughes "Open", 457*e1fe3e4aSElliott Hughes "Worm", 458*e1fe3e4aSElliott Hughes "Checkered", 459*e1fe3e4aSElliott Hughes "Checkered Reverse", 460*e1fe3e4aSElliott Hughes "Striped", 461*e1fe3e4aSElliott Hughes "Rounded", 462*e1fe3e4aSElliott Hughes "Flared", 463*e1fe3e4aSElliott Hughes "Flared Open", 464*e1fe3e4aSElliott Hughes "Rounded Slab", 465*e1fe3e4aSElliott Hughes "Sheared", 466*e1fe3e4aSElliott Hughes "Bifurcated", 467*e1fe3e4aSElliott Hughes "Inline", 468*e1fe3e4aSElliott Hughes "Slab", 469*e1fe3e4aSElliott Hughes "Contrast", 470*e1fe3e4aSElliott Hughes "Fancy", 471*e1fe3e4aSElliott Hughes "Mayhem", 472*e1fe3e4aSElliott Hughes ] 473*e1fe3e4aSElliott Hughes 474*e1fe3e4aSElliott Hughes 475*e1fe3e4aSElliott Hughesdef test_read_v5_document_discrete(datadir): 476*e1fe3e4aSElliott Hughes doc = DesignSpaceDocument.fromfile(datadir / "test_v5_discrete.designspace") 477*e1fe3e4aSElliott Hughes 478*e1fe3e4aSElliott Hughes assert not doc.locationLabels 479*e1fe3e4aSElliott Hughes assert not doc.variableFonts 480*e1fe3e4aSElliott Hughes 481*e1fe3e4aSElliott Hughes assert_descriptors_equal( 482*e1fe3e4aSElliott Hughes doc.axes, 483*e1fe3e4aSElliott Hughes [ 484*e1fe3e4aSElliott Hughes DiscreteAxisDescriptor( 485*e1fe3e4aSElliott Hughes default=400, 486*e1fe3e4aSElliott Hughes values=[400, 700, 900], 487*e1fe3e4aSElliott Hughes name="Weight", 488*e1fe3e4aSElliott Hughes tag="wght", 489*e1fe3e4aSElliott Hughes axisLabels=[ 490*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 491*e1fe3e4aSElliott Hughes name="Regular", 492*e1fe3e4aSElliott Hughes userValue=400, 493*e1fe3e4aSElliott Hughes elidable=True, 494*e1fe3e4aSElliott Hughes linkedUserValue=700, 495*e1fe3e4aSElliott Hughes ), 496*e1fe3e4aSElliott Hughes AxisLabelDescriptor(name="Bold", userValue=700), 497*e1fe3e4aSElliott Hughes AxisLabelDescriptor(name="Black", userValue=900), 498*e1fe3e4aSElliott Hughes ], 499*e1fe3e4aSElliott Hughes ), 500*e1fe3e4aSElliott Hughes DiscreteAxisDescriptor( 501*e1fe3e4aSElliott Hughes default=100, 502*e1fe3e4aSElliott Hughes values=[75, 100], 503*e1fe3e4aSElliott Hughes name="Width", 504*e1fe3e4aSElliott Hughes tag="wdth", 505*e1fe3e4aSElliott Hughes axisLabels=[ 506*e1fe3e4aSElliott Hughes AxisLabelDescriptor(name="Narrow", userValue=75), 507*e1fe3e4aSElliott Hughes AxisLabelDescriptor(name="Normal", userValue=100, elidable=True), 508*e1fe3e4aSElliott Hughes ], 509*e1fe3e4aSElliott Hughes ), 510*e1fe3e4aSElliott Hughes DiscreteAxisDescriptor( 511*e1fe3e4aSElliott Hughes default=0, 512*e1fe3e4aSElliott Hughes values=[0, 1], 513*e1fe3e4aSElliott Hughes name="Italic", 514*e1fe3e4aSElliott Hughes tag="ital", 515*e1fe3e4aSElliott Hughes axisLabels=[ 516*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 517*e1fe3e4aSElliott Hughes name="Roman", userValue=0, elidable=True, linkedUserValue=1 518*e1fe3e4aSElliott Hughes ), 519*e1fe3e4aSElliott Hughes AxisLabelDescriptor(name="Italic", userValue=1), 520*e1fe3e4aSElliott Hughes ], 521*e1fe3e4aSElliott Hughes ), 522*e1fe3e4aSElliott Hughes ], 523*e1fe3e4aSElliott Hughes ) 524*e1fe3e4aSElliott Hughes 525*e1fe3e4aSElliott Hughes 526*e1fe3e4aSElliott Hughesdef test_read_v5_document_aktiv(datadir): 527*e1fe3e4aSElliott Hughes doc = DesignSpaceDocument.fromfile(datadir / "test_v5_aktiv.designspace") 528*e1fe3e4aSElliott Hughes 529*e1fe3e4aSElliott Hughes assert not doc.locationLabels 530*e1fe3e4aSElliott Hughes 531*e1fe3e4aSElliott Hughes assert_descriptors_equal( 532*e1fe3e4aSElliott Hughes doc.axes, 533*e1fe3e4aSElliott Hughes [ 534*e1fe3e4aSElliott Hughes AxisDescriptor( 535*e1fe3e4aSElliott Hughes tag="wght", 536*e1fe3e4aSElliott Hughes name="Weight", 537*e1fe3e4aSElliott Hughes minimum=100, 538*e1fe3e4aSElliott Hughes default=400, 539*e1fe3e4aSElliott Hughes maximum=900, 540*e1fe3e4aSElliott Hughes map=[ 541*e1fe3e4aSElliott Hughes (100, 22), 542*e1fe3e4aSElliott Hughes (200, 38), 543*e1fe3e4aSElliott Hughes (300, 57), 544*e1fe3e4aSElliott Hughes (400, 84), 545*e1fe3e4aSElliott Hughes (500, 98), 546*e1fe3e4aSElliott Hughes (600, 115), 547*e1fe3e4aSElliott Hughes (700, 133), 548*e1fe3e4aSElliott Hughes (800, 158), 549*e1fe3e4aSElliott Hughes (900, 185), 550*e1fe3e4aSElliott Hughes ], 551*e1fe3e4aSElliott Hughes axisOrdering=1, 552*e1fe3e4aSElliott Hughes axisLabels=[ 553*e1fe3e4aSElliott Hughes AxisLabelDescriptor(name="Hair", userValue=100), 554*e1fe3e4aSElliott Hughes AxisLabelDescriptor(userValue=200, name="Thin"), 555*e1fe3e4aSElliott Hughes AxisLabelDescriptor(userValue=300, name="Light"), 556*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 557*e1fe3e4aSElliott Hughes userValue=400, 558*e1fe3e4aSElliott Hughes name="Regular", 559*e1fe3e4aSElliott Hughes elidable=True, 560*e1fe3e4aSElliott Hughes linkedUserValue=700, 561*e1fe3e4aSElliott Hughes ), 562*e1fe3e4aSElliott Hughes AxisLabelDescriptor(userValue=500, name="Medium"), 563*e1fe3e4aSElliott Hughes AxisLabelDescriptor(userValue=600, name="SemiBold"), 564*e1fe3e4aSElliott Hughes AxisLabelDescriptor(userValue=700, name="Bold"), 565*e1fe3e4aSElliott Hughes AxisLabelDescriptor(userValue=800, name="XBold"), 566*e1fe3e4aSElliott Hughes AxisLabelDescriptor(userValue=900, name="Black"), 567*e1fe3e4aSElliott Hughes ], 568*e1fe3e4aSElliott Hughes ), 569*e1fe3e4aSElliott Hughes AxisDescriptor( 570*e1fe3e4aSElliott Hughes tag="wdth", 571*e1fe3e4aSElliott Hughes name="Width", 572*e1fe3e4aSElliott Hughes minimum=75, 573*e1fe3e4aSElliott Hughes default=100, 574*e1fe3e4aSElliott Hughes maximum=125, 575*e1fe3e4aSElliott Hughes axisOrdering=0, 576*e1fe3e4aSElliott Hughes axisLabels=[ 577*e1fe3e4aSElliott Hughes AxisLabelDescriptor(name="Cd", userValue=75), 578*e1fe3e4aSElliott Hughes AxisLabelDescriptor(name="Normal", elidable=True, userValue=100), 579*e1fe3e4aSElliott Hughes AxisLabelDescriptor(name="Ex", userValue=125), 580*e1fe3e4aSElliott Hughes ], 581*e1fe3e4aSElliott Hughes ), 582*e1fe3e4aSElliott Hughes AxisDescriptor( 583*e1fe3e4aSElliott Hughes tag="ital", 584*e1fe3e4aSElliott Hughes name="Italic", 585*e1fe3e4aSElliott Hughes minimum=0, 586*e1fe3e4aSElliott Hughes default=0, 587*e1fe3e4aSElliott Hughes maximum=1, 588*e1fe3e4aSElliott Hughes axisOrdering=2, 589*e1fe3e4aSElliott Hughes axisLabels=[ 590*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 591*e1fe3e4aSElliott Hughes name="Upright", userValue=0, elidable=True, linkedUserValue=1 592*e1fe3e4aSElliott Hughes ), 593*e1fe3e4aSElliott Hughes AxisLabelDescriptor(name="Italic", userValue=1), 594*e1fe3e4aSElliott Hughes ], 595*e1fe3e4aSElliott Hughes ), 596*e1fe3e4aSElliott Hughes ], 597*e1fe3e4aSElliott Hughes ) 598*e1fe3e4aSElliott Hughes 599*e1fe3e4aSElliott Hughes assert_descriptors_equal( 600*e1fe3e4aSElliott Hughes doc.variableFonts, 601*e1fe3e4aSElliott Hughes [ 602*e1fe3e4aSElliott Hughes VariableFontDescriptor( 603*e1fe3e4aSElliott Hughes name="AktivGroteskVF_WghtWdthItal", 604*e1fe3e4aSElliott Hughes axisSubsets=[ 605*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor(name="Weight"), 606*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor(name="Width"), 607*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor(name="Italic"), 608*e1fe3e4aSElliott Hughes ], 609*e1fe3e4aSElliott Hughes ), 610*e1fe3e4aSElliott Hughes VariableFontDescriptor( 611*e1fe3e4aSElliott Hughes name="AktivGroteskVF_WghtWdth", 612*e1fe3e4aSElliott Hughes axisSubsets=[ 613*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor(name="Weight"), 614*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor(name="Width"), 615*e1fe3e4aSElliott Hughes ], 616*e1fe3e4aSElliott Hughes ), 617*e1fe3e4aSElliott Hughes VariableFontDescriptor( 618*e1fe3e4aSElliott Hughes name="AktivGroteskVF_Wght", 619*e1fe3e4aSElliott Hughes axisSubsets=[ 620*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor(name="Weight"), 621*e1fe3e4aSElliott Hughes ], 622*e1fe3e4aSElliott Hughes ), 623*e1fe3e4aSElliott Hughes VariableFontDescriptor( 624*e1fe3e4aSElliott Hughes name="AktivGroteskVF_Italics_WghtWdth", 625*e1fe3e4aSElliott Hughes axisSubsets=[ 626*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor(name="Weight"), 627*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor(name="Width"), 628*e1fe3e4aSElliott Hughes ValueAxisSubsetDescriptor(name="Italic", userValue=1), 629*e1fe3e4aSElliott Hughes ], 630*e1fe3e4aSElliott Hughes ), 631*e1fe3e4aSElliott Hughes VariableFontDescriptor( 632*e1fe3e4aSElliott Hughes name="AktivGroteskVF_Italics_Wght", 633*e1fe3e4aSElliott Hughes axisSubsets=[ 634*e1fe3e4aSElliott Hughes RangeAxisSubsetDescriptor(name="Weight"), 635*e1fe3e4aSElliott Hughes ValueAxisSubsetDescriptor(name="Italic", userValue=1), 636*e1fe3e4aSElliott Hughes ], 637*e1fe3e4aSElliott Hughes ), 638*e1fe3e4aSElliott Hughes ], 639*e1fe3e4aSElliott Hughes ) 640*e1fe3e4aSElliott Hughes 641*e1fe3e4aSElliott Hughes 642*e1fe3e4aSElliott Hughes@pytest.fixture 643*e1fe3e4aSElliott Hughesdef map_doc(): 644*e1fe3e4aSElliott Hughes """Generate a document with a few axes to test the mapping functions""" 645*e1fe3e4aSElliott Hughes doc = DesignSpaceDocument() 646*e1fe3e4aSElliott Hughes doc.addAxis( 647*e1fe3e4aSElliott Hughes AxisDescriptor( 648*e1fe3e4aSElliott Hughes tag="wght", 649*e1fe3e4aSElliott Hughes name="Weight", 650*e1fe3e4aSElliott Hughes minimum=100, 651*e1fe3e4aSElliott Hughes maximum=900, 652*e1fe3e4aSElliott Hughes default=100, 653*e1fe3e4aSElliott Hughes map=[(100, 10), (900, 90)], 654*e1fe3e4aSElliott Hughes ) 655*e1fe3e4aSElliott Hughes ) 656*e1fe3e4aSElliott Hughes doc.addAxis( 657*e1fe3e4aSElliott Hughes AxisDescriptor( 658*e1fe3e4aSElliott Hughes tag="wdth", 659*e1fe3e4aSElliott Hughes name="Width", 660*e1fe3e4aSElliott Hughes minimum=75, 661*e1fe3e4aSElliott Hughes maximum=200, 662*e1fe3e4aSElliott Hughes default=100, 663*e1fe3e4aSElliott Hughes map=[(75, 7500), (100, 10000), (200, 20000)], 664*e1fe3e4aSElliott Hughes ) 665*e1fe3e4aSElliott Hughes ) 666*e1fe3e4aSElliott Hughes doc.addAxis( 667*e1fe3e4aSElliott Hughes AxisDescriptor(tag="CUST", name="Custom", minimum=1, maximum=2, default=1.5) 668*e1fe3e4aSElliott Hughes ) 669*e1fe3e4aSElliott Hughes doc.addLocationLabel( 670*e1fe3e4aSElliott Hughes LocationLabelDescriptor( 671*e1fe3e4aSElliott Hughes name="Wonky", userLocation={"Weight": 800, "Custom": 1.2} 672*e1fe3e4aSElliott Hughes ) 673*e1fe3e4aSElliott Hughes ) 674*e1fe3e4aSElliott Hughes return doc 675*e1fe3e4aSElliott Hughes 676*e1fe3e4aSElliott Hughes 677*e1fe3e4aSElliott Hughesdef test_doc_location_map_forward(map_doc: DesignSpaceDocument): 678*e1fe3e4aSElliott Hughes assert map_doc.map_forward({"Weight": 400, "Width": 150, "Custom": 2}) == { 679*e1fe3e4aSElliott Hughes "Weight": 40, 680*e1fe3e4aSElliott Hughes "Width": 15000, 681*e1fe3e4aSElliott Hughes "Custom": 2, 682*e1fe3e4aSElliott Hughes }, "The mappings should be used to compute the design locations" 683*e1fe3e4aSElliott Hughes assert map_doc.map_forward({"Weight": 400}) == { 684*e1fe3e4aSElliott Hughes "Weight": 40, 685*e1fe3e4aSElliott Hughes "Width": 10000, 686*e1fe3e4aSElliott Hughes "Custom": 1.5, 687*e1fe3e4aSElliott Hughes }, "Missing user locations should be assumed equal to the axis's default" 688*e1fe3e4aSElliott Hughes 689*e1fe3e4aSElliott Hughes 690*e1fe3e4aSElliott Hughesdef test_doc_location_map_backward(map_doc: DesignSpaceDocument): 691*e1fe3e4aSElliott Hughes assert map_doc.map_backward({"Weight": 40, "Width": 15000, "Custom": 2}) == { 692*e1fe3e4aSElliott Hughes "Weight": 400, 693*e1fe3e4aSElliott Hughes "Width": 150, 694*e1fe3e4aSElliott Hughes "Custom": 2, 695*e1fe3e4aSElliott Hughes }, "The mappings should be used to compute the user locations" 696*e1fe3e4aSElliott Hughes assert map_doc.map_backward({"Weight": 40}) == { 697*e1fe3e4aSElliott Hughes "Weight": 400, 698*e1fe3e4aSElliott Hughes "Width": 100, 699*e1fe3e4aSElliott Hughes "Custom": 1.5, 700*e1fe3e4aSElliott Hughes }, "Missing design locations should be assumed equal to the axis's default" 701*e1fe3e4aSElliott Hughes assert map_doc.map_backward( 702*e1fe3e4aSElliott Hughes {"Weight": (40, 50), "Width": (15000, 100000), "Custom": (2, 1.5)} 703*e1fe3e4aSElliott Hughes ) == { 704*e1fe3e4aSElliott Hughes "Weight": 400, 705*e1fe3e4aSElliott Hughes "Width": 150, 706*e1fe3e4aSElliott Hughes "Custom": 2, 707*e1fe3e4aSElliott Hughes }, "Only the xvalue of anisotropic locations is used" 708*e1fe3e4aSElliott Hughes 709*e1fe3e4aSElliott Hughes 710*e1fe3e4aSElliott Hughesdef test_instance_location_from_label(map_doc): 711*e1fe3e4aSElliott Hughes inst = InstanceDescriptor(locationLabel="Wonky") 712*e1fe3e4aSElliott Hughes assert inst.getFullUserLocation(map_doc) == { 713*e1fe3e4aSElliott Hughes "Weight": 800, 714*e1fe3e4aSElliott Hughes "Width": 100, 715*e1fe3e4aSElliott Hughes "Custom": 1.2, 716*e1fe3e4aSElliott Hughes }, "an instance with a locationLabel uses the user location from that label, empty values on the label use axis defaults" 717*e1fe3e4aSElliott Hughes assert inst.getFullDesignLocation(map_doc) == { 718*e1fe3e4aSElliott Hughes "Weight": 80, 719*e1fe3e4aSElliott Hughes "Width": 10000, 720*e1fe3e4aSElliott Hughes "Custom": 1.2, 721*e1fe3e4aSElliott Hughes }, "an instance with a locationLabel computes the design location from that label, empty values on the label use axis defaults" 722*e1fe3e4aSElliott Hughes 723*e1fe3e4aSElliott Hughes inst = InstanceDescriptor(locationLabel="Wonky", userLocation={"Width": 200}) 724*e1fe3e4aSElliott Hughes assert inst.getFullUserLocation(map_doc) == { 725*e1fe3e4aSElliott Hughes "Weight": 800, 726*e1fe3e4aSElliott Hughes "Width": 100, 727*e1fe3e4aSElliott Hughes "Custom": 1.2, 728*e1fe3e4aSElliott Hughes }, "an instance with a locationLabel uses the user location from that label, other location values are ignored" 729*e1fe3e4aSElliott Hughes assert inst.getFullDesignLocation(map_doc) == { 730*e1fe3e4aSElliott Hughes "Weight": 80, 731*e1fe3e4aSElliott Hughes "Width": 10000, 732*e1fe3e4aSElliott Hughes "Custom": 1.2, 733*e1fe3e4aSElliott Hughes }, "an instance with a locationLabel computes the design location from that label, other location values are ignored" 734*e1fe3e4aSElliott Hughes 735*e1fe3e4aSElliott Hughes 736*e1fe3e4aSElliott Hughesdef test_instance_location_no_data(map_doc): 737*e1fe3e4aSElliott Hughes inst = InstanceDescriptor() 738*e1fe3e4aSElliott Hughes assert inst.getFullUserLocation(map_doc) == { 739*e1fe3e4aSElliott Hughes "Weight": 100, 740*e1fe3e4aSElliott Hughes "Width": 100, 741*e1fe3e4aSElliott Hughes "Custom": 1.5, 742*e1fe3e4aSElliott Hughes }, "an instance without any location data has the default user location" 743*e1fe3e4aSElliott Hughes assert inst.getFullDesignLocation(map_doc) == { 744*e1fe3e4aSElliott Hughes "Weight": 10, 745*e1fe3e4aSElliott Hughes "Width": 10000, 746*e1fe3e4aSElliott Hughes "Custom": 1.5, 747*e1fe3e4aSElliott Hughes }, "an instance without any location data has the default design location" 748*e1fe3e4aSElliott Hughes 749*e1fe3e4aSElliott Hughes 750*e1fe3e4aSElliott Hughesdef test_instance_location_design_first(map_doc): 751*e1fe3e4aSElliott Hughes inst = InstanceDescriptor( 752*e1fe3e4aSElliott Hughes designLocation={"Weight": (60, 61), "Width": 11000, "Custom": 1.2}, 753*e1fe3e4aSElliott Hughes userLocation={"Weight": 700, "Width": 180, "Custom": 1.4}, 754*e1fe3e4aSElliott Hughes ) 755*e1fe3e4aSElliott Hughes assert inst.getFullUserLocation(map_doc) == { 756*e1fe3e4aSElliott Hughes "Weight": 600, 757*e1fe3e4aSElliott Hughes "Width": 110, 758*e1fe3e4aSElliott Hughes "Custom": 1.2, 759*e1fe3e4aSElliott Hughes }, "when both design and user location data are provided, design wins" 760*e1fe3e4aSElliott Hughes assert inst.getFullDesignLocation(map_doc) == { 761*e1fe3e4aSElliott Hughes "Weight": (60, 61), 762*e1fe3e4aSElliott Hughes "Width": 11000, 763*e1fe3e4aSElliott Hughes "Custom": 1.2, 764*e1fe3e4aSElliott Hughes }, "when both design and user location data are provided, design wins (incl. anisotropy)" 765*e1fe3e4aSElliott Hughes 766*e1fe3e4aSElliott Hughes 767*e1fe3e4aSElliott Hughesdef test_instance_location_mix(map_doc): 768*e1fe3e4aSElliott Hughes inst = InstanceDescriptor( 769*e1fe3e4aSElliott Hughes designLocation={"Weight": (60, 61)}, 770*e1fe3e4aSElliott Hughes userLocation={"Width": 180}, 771*e1fe3e4aSElliott Hughes ) 772*e1fe3e4aSElliott Hughes assert inst.getFullUserLocation(map_doc) == { 773*e1fe3e4aSElliott Hughes "Weight": 600, 774*e1fe3e4aSElliott Hughes "Width": 180, 775*e1fe3e4aSElliott Hughes "Custom": 1.5, 776*e1fe3e4aSElliott Hughes }, "instance location is a mix of design and user locations" 777*e1fe3e4aSElliott Hughes assert inst.getFullDesignLocation(map_doc) == { 778*e1fe3e4aSElliott Hughes "Weight": (60, 61), 779*e1fe3e4aSElliott Hughes "Width": 18000, 780*e1fe3e4aSElliott Hughes "Custom": 1.5, 781*e1fe3e4aSElliott Hughes }, "instance location is a mix of design and user location" 782*e1fe3e4aSElliott Hughes 783*e1fe3e4aSElliott Hughes 784*e1fe3e4aSElliott Hughes@pytest.mark.parametrize( 785*e1fe3e4aSElliott Hughes "filename", 786*e1fe3e4aSElliott Hughes [ 787*e1fe3e4aSElliott Hughes "test_v4_original.designspace", 788*e1fe3e4aSElliott Hughes "test_v5_original.designspace", 789*e1fe3e4aSElliott Hughes "test_v5_aktiv.designspace", 790*e1fe3e4aSElliott Hughes "test_v5_decovar.designspace", 791*e1fe3e4aSElliott Hughes "test_v5_discrete.designspace", 792*e1fe3e4aSElliott Hughes "test_v5_sourceserif.designspace", 793*e1fe3e4aSElliott Hughes "test_v5.designspace", 794*e1fe3e4aSElliott Hughes ], 795*e1fe3e4aSElliott Hughes) 796*e1fe3e4aSElliott Hughesdef test_roundtrip(tmpdir, datadir, filename): 797*e1fe3e4aSElliott Hughes test_file = datadir / filename 798*e1fe3e4aSElliott Hughes output_path = tmpdir / filename 799*e1fe3e4aSElliott Hughes # Move the file to the tmpdir so that the filenames stay the same 800*e1fe3e4aSElliott Hughes # (they're relative to the file's path) 801*e1fe3e4aSElliott Hughes shutil.copy(test_file, output_path) 802*e1fe3e4aSElliott Hughes doc = DesignSpaceDocument.fromfile(output_path) 803*e1fe3e4aSElliott Hughes doc.write(output_path) 804*e1fe3e4aSElliott Hughes # The input XML has comments and empty lines for documentation purposes 805*e1fe3e4aSElliott Hughes xml = test_file.read_text(encoding="utf-8") 806*e1fe3e4aSElliott Hughes xml = re.sub( 807*e1fe3e4aSElliott Hughes r"<!-- ROUNDTRIP_TEST_REMOVE_ME_BEGIN -->(.|\n)*?<!-- ROUNDTRIP_TEST_REMOVE_ME_END -->", 808*e1fe3e4aSElliott Hughes "", 809*e1fe3e4aSElliott Hughes xml, 810*e1fe3e4aSElliott Hughes ) 811*e1fe3e4aSElliott Hughes xml = re.sub(r"<!--(.|\n)*?-->", "", xml) 812*e1fe3e4aSElliott Hughes xml = re.sub(r"\s*\n+", "\n", xml) 813*e1fe3e4aSElliott Hughes assert output_path.read_text(encoding="utf-8") == xml 814*e1fe3e4aSElliott Hughes 815*e1fe3e4aSElliott Hughes 816*e1fe3e4aSElliott Hughesdef test_using_v5_features_upgrades_format(tmpdir, datadir): 817*e1fe3e4aSElliott Hughes test_file = datadir / "test_v4_original.designspace" 818*e1fe3e4aSElliott Hughes output_4_path = tmpdir / "test_v4.designspace" 819*e1fe3e4aSElliott Hughes output_5_path = tmpdir / "test_v5.designspace" 820*e1fe3e4aSElliott Hughes shutil.copy(test_file, output_4_path) 821*e1fe3e4aSElliott Hughes doc = DesignSpaceDocument.fromfile(output_4_path) 822*e1fe3e4aSElliott Hughes doc.write(output_4_path) 823*e1fe3e4aSElliott Hughes assert 'format="4.1"' in output_4_path.read_text(encoding="utf-8") 824*e1fe3e4aSElliott Hughes doc.addVariableFont(VariableFontDescriptor(name="TestVF")) 825*e1fe3e4aSElliott Hughes doc.write(output_5_path) 826*e1fe3e4aSElliott Hughes assert 'format="5.0"' in output_5_path.read_text(encoding="utf-8") 827*e1fe3e4aSElliott Hughes 828*e1fe3e4aSElliott Hughes 829*e1fe3e4aSElliott Hughesdef test_addAxisDescriptor_discrete(): 830*e1fe3e4aSElliott Hughes ds = DesignSpaceDocument() 831*e1fe3e4aSElliott Hughes 832*e1fe3e4aSElliott Hughes axis = ds.addAxisDescriptor( 833*e1fe3e4aSElliott Hughes name="Italic", 834*e1fe3e4aSElliott Hughes tag="ital", 835*e1fe3e4aSElliott Hughes values=[0, 1], 836*e1fe3e4aSElliott Hughes default=0, 837*e1fe3e4aSElliott Hughes hidden=True, 838*e1fe3e4aSElliott Hughes map=[(0, -12), (1, 0)], 839*e1fe3e4aSElliott Hughes axisOrdering=3, 840*e1fe3e4aSElliott Hughes axisLabels=[ 841*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 842*e1fe3e4aSElliott Hughes name="Roman", 843*e1fe3e4aSElliott Hughes userValue=0, 844*e1fe3e4aSElliott Hughes elidable=True, 845*e1fe3e4aSElliott Hughes olderSibling=True, 846*e1fe3e4aSElliott Hughes linkedUserValue=1, 847*e1fe3e4aSElliott Hughes labelNames={"fr": "Romain"}, 848*e1fe3e4aSElliott Hughes ) 849*e1fe3e4aSElliott Hughes ], 850*e1fe3e4aSElliott Hughes ) 851*e1fe3e4aSElliott Hughes 852*e1fe3e4aSElliott Hughes assert ds.axes[0] is axis 853*e1fe3e4aSElliott Hughes assert_descriptors_equal( 854*e1fe3e4aSElliott Hughes [axis], 855*e1fe3e4aSElliott Hughes [ 856*e1fe3e4aSElliott Hughes DiscreteAxisDescriptor( 857*e1fe3e4aSElliott Hughes tag="ital", 858*e1fe3e4aSElliott Hughes name="Italic", 859*e1fe3e4aSElliott Hughes values=[0, 1], 860*e1fe3e4aSElliott Hughes default=0, 861*e1fe3e4aSElliott Hughes hidden=True, 862*e1fe3e4aSElliott Hughes map=[(0, -12), (1, 0)], 863*e1fe3e4aSElliott Hughes axisOrdering=3, 864*e1fe3e4aSElliott Hughes axisLabels=[ 865*e1fe3e4aSElliott Hughes AxisLabelDescriptor( 866*e1fe3e4aSElliott Hughes name="Roman", 867*e1fe3e4aSElliott Hughes userValue=0, 868*e1fe3e4aSElliott Hughes elidable=True, 869*e1fe3e4aSElliott Hughes olderSibling=True, 870*e1fe3e4aSElliott Hughes linkedUserValue=1, 871*e1fe3e4aSElliott Hughes labelNames={"fr": "Romain"}, 872*e1fe3e4aSElliott Hughes ) 873*e1fe3e4aSElliott Hughes ], 874*e1fe3e4aSElliott Hughes ) 875*e1fe3e4aSElliott Hughes ], 876*e1fe3e4aSElliott Hughes ) 877*e1fe3e4aSElliott Hughes 878*e1fe3e4aSElliott Hughes 879*e1fe3e4aSElliott Hughesdef test_addLocationLabelDescriptor(): 880*e1fe3e4aSElliott Hughes ds = DesignSpaceDocument() 881*e1fe3e4aSElliott Hughes 882*e1fe3e4aSElliott Hughes label = ds.addLocationLabelDescriptor( 883*e1fe3e4aSElliott Hughes name="Somewhere", 884*e1fe3e4aSElliott Hughes userLocation={}, 885*e1fe3e4aSElliott Hughes elidable=True, 886*e1fe3e4aSElliott Hughes olderSibling=True, 887*e1fe3e4aSElliott Hughes labelNames={"fr": "Quelque part"}, 888*e1fe3e4aSElliott Hughes ) 889*e1fe3e4aSElliott Hughes 890*e1fe3e4aSElliott Hughes assert ds.locationLabels[0] is label 891*e1fe3e4aSElliott Hughes assert_descriptors_equal( 892*e1fe3e4aSElliott Hughes [label], 893*e1fe3e4aSElliott Hughes [ 894*e1fe3e4aSElliott Hughes LocationLabelDescriptor( 895*e1fe3e4aSElliott Hughes name="Somewhere", 896*e1fe3e4aSElliott Hughes userLocation={}, 897*e1fe3e4aSElliott Hughes elidable=True, 898*e1fe3e4aSElliott Hughes olderSibling=True, 899*e1fe3e4aSElliott Hughes labelNames={"fr": "Quelque part"}, 900*e1fe3e4aSElliott Hughes ) 901*e1fe3e4aSElliott Hughes ], 902*e1fe3e4aSElliott Hughes ) 903*e1fe3e4aSElliott Hughes 904*e1fe3e4aSElliott Hughes 905*e1fe3e4aSElliott Hughesdef test_addVariableFontDescriptor(): 906*e1fe3e4aSElliott Hughes ds = DesignSpaceDocument() 907*e1fe3e4aSElliott Hughes 908*e1fe3e4aSElliott Hughes vf = ds.addVariableFontDescriptor(name="TestVF", filename="TestVF.ttf") 909*e1fe3e4aSElliott Hughes 910*e1fe3e4aSElliott Hughes assert ds.variableFonts[0] is vf 911*e1fe3e4aSElliott Hughes assert_descriptors_equal( 912*e1fe3e4aSElliott Hughes [vf], [VariableFontDescriptor(name="TestVF", filename="TestVF.ttf")] 913*e1fe3e4aSElliott Hughes ) 914