示例#1
0
def _buildAxisRecords(axes, nameTable):
    axisRecords = []
    axisValues = []
    for axisRecordIndex, axisDict in enumerate(axes):
        axis = ot.AxisRecord()
        axis.AxisTag = axisDict["tag"]
        axis.AxisNameID = _addName(nameTable, axisDict["name"])
        axis.AxisOrdering = axisDict.get("ordering", axisRecordIndex)
        axisRecords.append(axis)

        for axisVal in axisDict.get("values", ()):
            axisValRec = ot.AxisValue()
            axisValRec.AxisIndex = axisRecordIndex
            axisValRec.Flags = axisVal.get("flags", 0)
            axisValRec.ValueNameID = _addName(nameTable, axisVal['name'])

            if "value" in axisVal:
                axisValRec.Value = axisVal["value"]
                if "linkedValue" in axisVal:
                    axisValRec.Format = 3
                    axisValRec.LinkedValue = axisVal["linkedValue"]
                else:
                    axisValRec.Format = 1
            elif "nominalValue" in axisVal:
                axisValRec.Format = 2
                axisValRec.NominalValue = axisVal["nominalValue"]
                axisValRec.RangeMinValue = axisVal.get("rangeMinValue", AXIS_VALUE_NEGATIVE_INFINITY)
                axisValRec.RangeMaxValue = axisVal.get("rangeMaxValue", AXIS_VALUE_POSITIVE_INFINITY)
            else:
                raise ValueError("Can't determine format for AxisValue")

            axisValues.append(axisValRec)
    return axisRecords, axisValues
示例#2
0
def test_updateNameTable_format4_axisValues(varfont):
    # format 4 axisValues should dominate the other axisValues
    stat = varfont["STAT"].table

    axisValue = otTables.AxisValue()
    axisValue.Format = 4
    axisValue.Flags = 0
    varfont["name"].setName("Dominant Value", 297, 3, 1, 0x409)
    axisValue.ValueNameID = 297
    axisValue.AxisValueRecord = []
    for tag, value in (("wght", 900), ("wdth", 79)):
        rec = otTables.AxisValueRecord()
        rec.AxisIndex = next(
            i for i, a in enumerate(stat.DesignAxisRecord.Axis) if a.AxisTag == tag
        )
        rec.Value = value
        axisValue.AxisValueRecord.append(rec)
    stat.AxisValueArray.AxisValue.append(axisValue)

    instancer.names.updateNameTable(varfont, {"wdth": 79, "wght": 900})
    expected = {
        (1, 3, 1, 0x409): "Test Variable Font Dominant Value",
        (2, 3, 1, 0x409): "Regular",
        (16, 3, 1, 0x409): "Test Variable Font",
        (17, 3, 1, 0x409): "Dominant Value",
    }
    _test_name_records(varfont, expected, isNonRIBBI=True)
示例#3
0
def _update_italic_stat(ttfont):
    stat = ttfont['STAT'].table

    record = ot.AxisValue()
    record.AxisIndex = 2
    record.Flags = 0
    record.ValueNameID = 258 # Italic
    record.Value = 1.0
    record.Format = 1

    stat.AxisValueArray.AxisValue[-1] = record
示例#4
0
def _update_roman_stat(ttfont):
    stat = ttfont['STAT'].table

    record = ot.AxisValue()
    record.AxisIndex = 2
    record.Flags = 2
    record.ValueNameID = 296 # Roman
    record.LinkedValue = 1
    record.Value = 0
    record.Format = 3

    stat.AxisValueArray.AxisValue[-1] = record
示例#5
0
def append_stat_record(stat,
                       axis_index,
                       value,
                       namerecord_id,
                       linked_value=None):
    records = stat.table.AxisValueArray.AxisValue
    axis_record = otTables.AxisValue()
    axis_record.Format = 1
    axis_record.ValueNameID = namerecord_id
    axis_record.Value = value
    axis_record.AxisIndex = axis_index

    axis_record.Flags = 0
    if linked_value:
        axis_record.Format = 3
        axis_record.LinkedValue = linked_value
    records.append(axis_record)
示例#6
0
def _buildAxisValuesFormat4(locations, axes, nameTable):
    axisTagToIndex = {}
    for axisRecordIndex, axisDict in enumerate(axes):
        axisTagToIndex[axisDict["tag"]] = axisRecordIndex

    axisValues = []
    for axisLocationDict in locations:
        axisValRec = ot.AxisValue()
        axisValRec.Format = 4
        axisValRec.ValueNameID = _addName(nameTable, axisLocationDict['name'])
        axisValRec.Flags = axisLocationDict.get("flags", 0)
        axisValueRecords = []
        for tag, value in axisLocationDict["location"].items():
            avr = ot.AxisValueRecord()
            avr.AxisIndex = axisTagToIndex[tag]
            avr.Value = value
            axisValueRecords.append(avr)
        axisValueRecords.sort(key=lambda avr: avr.AxisIndex)
        axisValRec.AxisCount = len(axisValueRecords)
        axisValRec.AxisValueRecord = axisValueRecords
        axisValues.append(axisValRec)
    return axisValues
示例#7
0
def generate_name_and_STAT_variable(
    stylespace: statmake.classes.Stylespace,
    varfont: fontTools.ttLib.TTFont,
    additional_locations: Mapping[str, float],
):
    """Generate a new name and STAT table ready for insertion."""

    if "fvar" not in varfont:
        raise ValueError(
            "Need a variable font with the fvar table to determine which instances "
            "are present.")

    stylespace_name_to_axis = {a.name.default: a for a in stylespace.axes}
    fvar_name_to_axis = {}
    name_to_tag: Dict[str, str] = {}
    name_to_index: Dict[str, int] = {}
    index = 0
    for index, fvar_axis in enumerate(varfont["fvar"].axes):
        fvar_axis_name = _default_name_string(varfont, fvar_axis.axisNameID)
        try:
            stylespace_axis = stylespace_name_to_axis[fvar_axis_name]
        except KeyError:
            raise ValueError(
                f"No stylespace entry found for axis name '{fvar_axis_name}'.")
        if fvar_axis.axisTag != stylespace_axis.tag:
            raise ValueError(
                f"fvar axis '{fvar_axis_name}' tag is '{fvar_axis.axisTag}', but "
                f"Stylespace tag is '{stylespace_axis.tag}'.")
        fvar_name_to_axis[fvar_axis_name] = fvar_axis
        name_to_tag[fvar_axis_name] = fvar_axis.axisTag
        name_to_index[fvar_axis_name] = index

    for axis_name in additional_locations:
        try:
            stylespace_axis = stylespace_name_to_axis[axis_name]
        except KeyError:
            raise ValueError(
                f"No stylespace entry found for axis name '{axis_name}'.")
        name_to_tag[stylespace_axis.name.default] = stylespace_axis.tag
        index += 1
        name_to_index[stylespace_axis.name.default] = index

    # First, determine which stops are used on which axes. The STAT table must contain
    # a name for each stop that is used on each axis, so each stop must have an entry
    # in the Stylespace. Also include locations in additional_locations that can refer
    # to axes not present in the current varfont.
    stylespace_stops: Dict[str, Set[float]] = {}
    for axis in stylespace.axes:
        stylespace_stops[axis.tag] = {l.value for l in axis.locations}
    for named_location in stylespace.locations:
        for name, value in named_location.axis_values.items():
            stylespace_stops[name_to_tag[name]].add(value)

    axis_stops: Mapping[str, Set[float]] = collections.defaultdict(
        set)  # tag to stops
    for instance in varfont["fvar"].instances:
        for k, v in instance.coordinates.items():
            if v not in stylespace_stops[k]:
                raise ValueError(
                    f"There is no Stylespace entry for stop {v} on axis {k}.")
            axis_stops[k].add(v)

    for k, v in additional_locations.items():
        axis_tag = name_to_tag[k]
        if v not in stylespace_stops[axis_tag]:
            raise ValueError(
                f"There is no Stylespace entry for stop {v} on axis {k} (from "
                "additional locations).")
        axis_stops[axis_tag].add(v)

    # Construct temporary name and STAT tables for returning at the end.
    name_table = copy.deepcopy(varfont["name"])
    stat_table = _new_empty_STAT_table()

    # Generate axis records. Reuse an axis' name ID if it exists, else make a new one.
    for axis_name, axis_tag in name_to_tag.items():
        stylespace_axis = stylespace_name_to_axis[axis_name]
        if axis_name in fvar_name_to_axis:
            axis_name_id = fvar_name_to_axis[axis_name].axisNameID
        else:
            axis_name_id = name_table.addMultilingualName(
                stylespace_axis.name.mapping, mac=False)
        axis_record = _new_axis_record(tag=axis_tag,
                                       name_id=axis_name_id,
                                       ordering=stylespace_axis.ordering)
        stat_table.table.DesignAxisRecord.Axis.append(axis_record)

    # Generate formats 1, 2 and 3.
    for axis in stylespace.axes:
        for location in axis.locations:
            if location.value not in axis_stops[axis.tag]:
                continue
            axis_value = otTables.AxisValue()
            name_id = name_table.addMultilingualName(location.name.mapping,
                                                     mac=False)
            location.fill_in_AxisValue(
                axis_value,
                axis_index=name_to_index[axis.name.default],
                name_id=name_id)
            stat_table.table.AxisValueArray.AxisValue.append(axis_value)

    # Generate format 4.
    for named_location in stylespace.locations:
        if all(name_to_tag[k] in axis_stops and v in axis_stops[name_to_tag[k]]
               for k, v in named_location.axis_values.items()):
            stat_table.table.Version = 0x00010002
            axis_value = otTables.AxisValue()
            name_id = name_table.addMultilingualName(
                named_location.name.mapping, mac=False)
            named_location.fill_in_AxisValue(
                axis_value,
                axis_name_to_index=name_to_index,
                name_id=name_id,
                axis_value_record_type=otTables.AxisValueRecord,
            )
            stat_table.table.AxisValueArray.AxisValue.append(axis_value)

    stat_table.table.ElidedFallbackNameID = stylespace.elided_fallback_name_id

    return name_table, stat_table