# models

Variation fonts interpolation models.

fontTools.varLib.models.normalizeValue(v, triple, extrapolate=False)

  Normalizes value based on a min/default/max triple.

      >>> normalizeValue(400, (100, 400, 900))
      0.0
      >>> normalizeValue(100, (100, 400, 900))
      -1.0
      >>> normalizeValue(650, (100, 400, 900))
      0.5

fontTools.varLib.models.normalizeLocation(location, axes, extrapolate=False, *, validate=False)

  Normalizes location based on axis min/default/max values from axes.

      >>> axes = {"wght": (100, 400, 900)}
      >>> normalizeLocation({"wght": 400}, axes)
      {'wght': 0.0}
      >>> normalizeLocation({"wght": 100}, axes)
      {'wght': -1.0}
      >>> normalizeLocation({"wght": 900}, axes)
      {'wght': 1.0}
      >>> normalizeLocation({"wght": 650}, axes)
      {'wght': 0.5}
      >>> normalizeLocation({"wght": 1000}, axes)
      {'wght': 1.0}
      >>> normalizeLocation({"wght": 0}, axes)
      {'wght': -1.0}
      >>> axes = {"wght": (0, 0, 1000)}
      >>> normalizeLocation({"wght": 0}, axes)
      {'wght': 0.0}
      >>> normalizeLocation({"wght": -1}, axes)
      {'wght': 0.0}
      >>> normalizeLocation({"wght": 1000}, axes)
      {'wght': 1.0}
      >>> normalizeLocation({"wght": 500}, axes)
      {'wght': 0.5}
      >>> normalizeLocation({"wght": 1001}, axes)
      {'wght': 1.0}
      >>> axes = {"wght": (0, 1000, 1000)}
      >>> normalizeLocation({"wght": 0}, axes)
      {'wght': -1.0}
      >>> normalizeLocation({"wght": -1}, axes)
      {'wght': -1.0}
      >>> normalizeLocation({"wght": 500}, axes)
      {'wght': -0.5}
      >>> normalizeLocation({"wght": 1000}, axes)
      {'wght': 0.0}
      >>> normalizeLocation({"wght": 1001}, axes)
      {'wght': 0.0}

fontTools.varLib.models.supportScalar(location, support, ot=True, extrapolate=False, axisRanges=None)

  Returns the scalar multiplier at location, for a master with support. If ot is True, then a peak value of zero for support of an axis means “axis does not participate”. That is how OpenType Variation Font technology works.

  If extrapolate is True, axisRanges must be a dict that maps axis names to (axisMin, axisMax) tuples.

      >>> supportScalar({}, {})
      1.0
      >>> supportScalar({'wght':.2}, {})
      1.0
      >>> supportScalar({'wght':.2}, {'wght':(0,2,3)})
      0.1
      >>> supportScalar({'wght':2.5}, {'wght':(0,2,4)})
      0.75
      >>> supportScalar({'wght':2.5, 'wdth':0}, {'wght':(0,2,4), 'wdth':(-1,0,+1)})
      0.75
      >>> supportScalar({'wght':2.5, 'wdth':.5}, {'wght':(0,2,4), 'wdth':(-1,0,+1)}, ot=False)
      0.375
      >>> supportScalar({'wght':2.5, 'wdth':0}, {'wght':(0,2,4), 'wdth':(-1,0,+1)})
      0.75
      >>> supportScalar({'wght':2.5, 'wdth':.5}, {'wght':(0,2,4), 'wdth':(-1,0,+1)})
      0.75
      >>> supportScalar({'wght':3}, {'wght':(0,1,2)}, extrapolate=True, axisRanges={'wght':(0, 2)})
      -1.0
      >>> supportScalar({'wght':-1}, {'wght':(0,1,2)}, extrapolate=True, axisRanges={'wght':(0, 2)})
      -1.0
      >>> supportScalar({'wght':3}, {'wght':(0,2,2)}, extrapolate=True, axisRanges={'wght':(0, 2)})
      1.5
      >>> supportScalar({'wght':-1}, {'wght':(0,2,2)}, extrapolate=True, axisRanges={'wght':(0, 2)})
      -0.5

fontTools.varLib.models.piecewiseLinearMap(v, mapping)

class fontTools.varLib.models.VariationModel(locations, axisOrder=None, extrapolate=False, *, axisRanges=None)

  Bases: `object`

  Locations must have the base master at the origin (ie. 0).

  If axis-ranges are not provided, values are assumed to be normalized to the range [-1, 1].

  If the extrapolate argument is set to True, then values are extrapolated outside the axis range.

      >>> from pprint import pprint
      >>> axisRanges = {'wght': (-180, +180), 'wdth': (-1, +1)}
      >>> locations = [       {'wght':100},       {'wght':-100},       {'wght':-180},       {'wdth':+.3},       {'wght':+120,'wdth':.3},       {'wght':+120,'wdth':.2},       {},       {'wght':+180,'wdth':.3},       {'wght':+180},       ]
      >>> model = VariationModel(locations, axisOrder=['wght'], axisRanges=axisRanges)
      >>> pprint(model.locations)
      [{},
       {'wght': -100},
       {'wght': -180},
       {'wght': 100},
       {'wght': 180},
       {'wdth': 0.3},
       {'wdth': 0.3, 'wght': 180},
       {'wdth': 0.3, 'wght': 120},
       {'wdth': 0.2, 'wght': 120}]
      >>> pprint(model.deltaWeights)
      [{},
       {0: 1.0},
       {0: 1.0},
       {0: 1.0},
       {0: 1.0},
       {0: 1.0},
       {0: 1.0, 4: 1.0, 5: 1.0},
       {0: 1.0, 3: 0.75, 4: 0.25, 5: 1.0, 6: 0.6666666666666666},
       {0: 1.0,
        3: 0.75,
        4: 0.25,
        5: 0.6666666666666667,
        6: 0.4444444444444445,
        7: 0.6666666666666667}]

  getSubModel(items)

    Return a sub-model and the items that are not None.

    The sub-model is necessary for working with the subset of items when some are None.

    The sub-model is cached.

  static computeAxisRanges(locations)
  static getMasterLocationsSortKeyFunc(locations, axisOrder=[])
  reorderMasters(master_list, mapping)
  getDeltas(masterValues, *, round=<function noRound>)
  getDeltasAndSupports(items, *, round=<function noRound>)
  getScalars(loc)

    Return scalars for each delta, for the given location. If interpolating many master-values at the same location, this function allows speed up by fetching the scalars once and using them with interpolateFromMastersAndScalars().

  getMasterScalars(targetLocation)

    Return multipliers for each master, for the given location. If interpolating many master-values at the same location, this function allows speed up by fetching the scalars once and using them with interpolateFromValuesAndScalars().

    Note that the scalars used in interpolateFromMastersAndScalars(), are not the same as the ones returned here. They are the result of getScalars().

  static interpolateFromValuesAndScalars(values, scalars)

    Interpolate from values and scalars coefficients.

    If the values are master-values, then the scalars should be fetched from getMasterScalars().

    If the values are deltas, then the scalars should be fetched from getScalars(); in which case this is the same as interpolateFromDeltasAndScalars().

  static interpolateFromDeltasAndScalars(deltas, scalars)

    Interpolate from deltas and scalars fetched from getScalars().

  interpolateFromDeltas(loc, deltas)

    Interpolate from deltas, at location loc.

  interpolateFromMasters(loc, masterValues, *, round=<function noRound>)

    Interpolate from master-values, at location loc.

  interpolateFromMastersAndScalars(masterValues, scalars, *, round=<function noRound>)

    Interpolate from master-values, and scalars fetched from getScalars(), which is useful when you want to interpolate multiple master-values with the same location.