1from fontTools.varLib.instancer import solver 2from fontTools.varLib.instancer import NormalizedAxisTripleAndDistances 3import pytest 4 5 6class RebaseTentTest(object): 7 @pytest.mark.parametrize( 8 "tent, axisRange, expected", 9 [ 10 # Case 1: # Pin at default 11 pytest.param((0, 1, 1), (0.0, 0.0, 0.0), []), 12 # Case 1: 13 pytest.param((0.3, 0.5, 0.8), (0.1, 0.2, 0.3), []), 14 # Pin axis 15 pytest.param( 16 (0, 1, 1), 17 (0.5, 0.5, 0.5), 18 [ 19 (0.5, None), 20 ], 21 ), 22 # Case 2: 23 pytest.param( 24 (0, 1, 1), 25 (-1, 0, 0.5), 26 [ 27 (0.5, (0, 1, 1)), 28 ], 29 ), 30 # Case 2: 31 pytest.param( 32 (0, 1, 1), 33 (-1, 0, 0.75), 34 [ 35 (0.75, (0, 1, 1)), 36 ], 37 ), 38 # 39 # Without gain: 40 # 41 # Case 3 42 pytest.param( 43 (0, 0.2, 1), 44 (-1, 0, 0.8), 45 [ 46 (1, (0, 0.25, 1)), 47 (0.25, (0.25, 1, 1)), 48 ], 49 ), 50 # Case 3 boundary 51 pytest.param( 52 (0, 0.4, 1), 53 (-1, 0, 0.5), 54 [ 55 (1, (0, 0.8, 1)), 56 (2.5 / 3, (0.8, 1, 1)), 57 ], 58 ), 59 # Case 4 60 pytest.param( 61 (0, 0.25, 1), 62 (-1, 0, 0.4), 63 [ 64 (1, (0, 0.625, 1)), 65 (0.8, (0.625, 1, 1)), 66 ], 67 ), 68 pytest.param( 69 (0.25, 0.3, 1.05), 70 (0, 0.2, 0.4), 71 [ 72 (1, (0.25, 0.5, 1)), 73 (2.6 / 3, (0.5, 1, 1)), 74 ], 75 ), 76 # Case 4 boundary 77 pytest.param( 78 (0.25, 0.5, 1), 79 (0, 0.25, 0.5), 80 [ 81 (1, (0, 1, 1)), 82 ], 83 ), 84 # 85 # With gain: 86 # 87 # Case 3a/1neg 88 pytest.param( 89 (0.0, 0.5, 1), 90 (0, 0.5, 1), 91 [ 92 (1, None), 93 (-1, (0, 1, 1)), 94 (-1, (-1, -1, 0)), 95 ], 96 ), 97 pytest.param( 98 (0.0, 0.5, 1), 99 (0, 0.5, 0.75), 100 [ 101 (1, None), 102 (-0.5, (0, 1, 1)), 103 (-1, (-1, -1, 0)), 104 ], 105 ), 106 pytest.param( 107 (0.0, 0.5, 1), 108 (0, 0.25, 0.8), 109 [ 110 (0.5, None), 111 (0.5, (0, 0.45454545, 0.9090909090)), 112 (-0.1, (0.9090909090, 1.0, 1.0)), 113 (-0.5, (-1, -1, 0)), 114 ], 115 ), 116 # Case 3a/1neg 117 pytest.param( 118 (0.0, 0.5, 2), 119 (0.2, 0.5, 0.8), 120 [ 121 (1, None), 122 (-0.2, (0, 1, 1)), 123 (-0.6, (-1, -1, 0)), 124 ], 125 ), 126 # Case 3a/1neg 127 pytest.param( 128 (0.0, 0.5, 2), 129 (0.2, 0.5, 1), 130 [ 131 (1, None), 132 (-1 / 3, (0, 1, 1)), 133 (-0.6, (-1, -1, 0)), 134 ], 135 ), 136 # Case 3 137 pytest.param( 138 (0, 0.5, 1), 139 (0.25, 0.25, 0.75), 140 [ 141 (0.5, None), 142 (0.5, (0, 0.5, 1.0)), 143 ], 144 ), 145 # Case 1neg 146 pytest.param( 147 (0.0, 0.5, 1), 148 (0, 0.25, 0.5), 149 [ 150 (0.5, None), 151 (0.5, (0, 1, 1)), 152 (-0.5, (-1, -1, 0)), 153 ], 154 ), 155 # Case 2neg 156 pytest.param( 157 (0.05, 0.55, 1), 158 (0, 0.25, 0.5), 159 [ 160 (0.4, None), 161 (0.5, (0, 1, 1)), 162 (-0.4, (-1, -0.8, 0)), 163 (-0.4, (-1, -1, -0.8)), 164 ], 165 ), 166 # Case 2neg, other side 167 pytest.param( 168 (-1, -0.55, -0.05), 169 (-0.5, -0.25, 0), 170 [ 171 (0.4, None), 172 (0.5, (-1, -1, 0)), 173 (-0.4, (0, 0.8, 1)), 174 (-0.4, (0.8, 1, 1)), 175 ], 176 ), 177 # 178 # Misc corner cases 179 # 180 pytest.param( 181 (0.5, 0.5, 0.5), 182 (0.5, 0.5, 0.5), 183 [ 184 (1, None), 185 ], 186 ), 187 pytest.param( 188 (0.3, 0.5, 0.7), 189 (0.1, 0.5, 0.9), 190 [ 191 (1, None), 192 (-1, (0, 0.5, 1)), 193 (-1, (0.5, 1, 1)), 194 (-1, (-1, -0.5, 0)), 195 (-1, (-1, -1, -0.5)), 196 ], 197 ), 198 pytest.param( 199 (0.5, 0.5, 0.5), 200 (0.25, 0.25, 0.5), 201 [ 202 (1, (1, 1, 1)), 203 ], 204 ), 205 pytest.param( 206 (0.5, 0.5, 0.5), 207 (0.25, 0.35, 0.5), 208 [ 209 (1, (1, 1, 1)), 210 ], 211 ), 212 pytest.param( 213 (0.5, 0.5, 0.55), 214 (0.25, 0.35, 0.5), 215 [ 216 (1, (1, 1, 1)), 217 ], 218 ), 219 pytest.param( 220 (0.5, 0.5, 1), 221 (0.5, 0.5, 1), 222 [ 223 (1, None), 224 (-1, (0, 1, 1)), 225 ], 226 ), 227 pytest.param( 228 (0.25, 0.5, 1), 229 (0.5, 0.5, 1), 230 [ 231 (1, None), 232 (-1, (0, 1, 1)), 233 ], 234 ), 235 pytest.param( 236 (0, 0.2, 1), 237 (0, 0, 0.5), 238 [ 239 (1, (0, 0.4, 1)), 240 (0.625, (0.4, 1, 1)), 241 ], 242 ), 243 # https://github.com/fonttools/fonttools/issues/3139 244 pytest.param( 245 (0, 0.5, 1), 246 (-1, 0.25, 1), 247 [ 248 (0.5, None), 249 (0.5, (0.0, 1 / 3, 2 / 3)), 250 (-0.5, (2 / 3, 1, 1)), 251 (-0.5, (-1, -0.2, 0)), 252 (-0.5, (-1, -1, -0.2)), 253 ], 254 ), 255 # Dirac delta at new default. Fancy! 256 pytest.param( 257 (0.5, 0.5, 0.5), 258 (0, 0.5, 1), 259 [ 260 (1, None), 261 (-1, (0, 0.0001220703, 1)), 262 (-1, (0.0001220703, 1, 1)), 263 (-1, (-1, -0.0001220703, 0)), 264 (-1, (-1, -1, -0.0001220703)), 265 ], 266 ), 267 # https://github.com/fonttools/fonttools/issues/3177 268 pytest.param( 269 (0, 1, 1), 270 (-1, -0.5, +1, 1, 1), 271 [ 272 (1.0, (1 / 3, 1.0, 1.0)), 273 ], 274 ), 275 pytest.param( 276 (0, 1, 1), 277 (-1, -0.5, +1, 2, 1), 278 [ 279 (1.0, (0.5, 1.0, 1.0)), 280 ], 281 ), 282 # https://github.com/fonttools/fonttools/issues/3291 283 pytest.param( 284 (0.6, 0.7, 0.8), 285 (-1, 0.2, +1, 1, 1), 286 [ 287 (1.0, (0.5, 0.625, 0.75)), 288 ], 289 ), 290 ], 291 ) 292 def test_rebaseTent(self, tent, axisRange, expected): 293 axisRange = NormalizedAxisTripleAndDistances(*axisRange) 294 295 sol = solver.rebaseTent(tent, axisRange) 296 297 a = pytest.approx 298 expected = [ 299 (a(scalar), (a(v[0]), a(v[1]), a(v[2])) if v is not None else None) 300 for scalar, v in expected 301 ] 302 303 assert sol == expected, (tent, axisRange) 304