Beispiel #1
0
def test_Vector():
    v = Vector([100, 200])
    assert v == Vector([100, 200])
    assert v == [100, 200]
    assert v + Vector([1, 2]) == [101, 202]
    assert v - Vector([1, 2]) == [99, 198]
    assert v * 2 == [200, 400]
    assert v * 0.5 == [50, 100]
    assert v / 2 == [50, 100]
Beispiel #2
0
def _merge_TTHinting(font, model, master_ttfs, tolerance=0.5):

	log.info("Merging TT hinting")
	assert "cvar" not in font

	# Check that the existing hinting is compatible

	# fpgm and prep table

	for tag in ("fpgm", "prep"):
		all_pgms = [m[tag].program for m in master_ttfs if tag in m]
		if len(all_pgms) == 0:
			continue
		if tag in font:
			font_pgm = font[tag].program
		else:
			font_pgm = Program()
		if any(pgm != font_pgm for pgm in all_pgms):
			log.warning("Masters have incompatible %s tables, hinting is discarded." % tag)
			_remove_TTHinting(font)
			return

	# glyf table

	for name, glyph in font["glyf"].glyphs.items():
		all_pgms = [
			m["glyf"][name].program
			for m in master_ttfs
			if hasattr(m["glyf"][name], "program")
		]
		if not any(all_pgms):
			continue
		glyph.expand(font["glyf"])
		if hasattr(glyph, "program"):
			font_pgm = glyph.program
		else:
			font_pgm = Program()
		if any(pgm != font_pgm for pgm in all_pgms if pgm):
			log.warning("Masters have incompatible glyph programs in glyph '%s', hinting is discarded." % name)
			_remove_TTHinting(font)
			return

	# cvt table

	all_cvs = [Vector(m["cvt "].values) for m in master_ttfs if "cvt " in m]
	
	if len(all_cvs) == 0:
		# There is no cvt table to make a cvar table from, we're done here.
		return

	if len(all_cvs) != len(master_ttfs):
		log.warning("Some masters have no cvt table, hinting is discarded.")
		_remove_TTHinting(font)
		return

	num_cvt0 = len(all_cvs[0])
	if (any(len(c) != num_cvt0 for c in all_cvs)):
		log.warning("Masters have incompatible cvt tables, hinting is discarded.")
		_remove_TTHinting(font)
		return

	# We can build the cvar table now.

	cvar = font["cvar"] = newTable('cvar')
	cvar.version = 1
	cvar.variations = []

	deltas = model.getDeltas(all_cvs)
	supports = model.supports
	for i,(delta,support) in enumerate(zip(deltas[1:], supports[1:])):
		delta = [int(round(d)) for d in delta]
		if all(abs(v) <= tolerance for v in delta):
			continue
		var = TupleVariation(support, delta)
		cvar.variations.append(var)
def compile_instructions(font, ship=True, keep_cvar=False):
    if "glyf" not in font:
        raise VTTLibError("Missing 'glyf' table; not a TrueType font")
    if "TSI1" not in font:
        raise VTTLibError("The font contains no 'TSI1' table")
    if keep_cvar and "cvar" not in font:
        raise VTTLibError(
            "The keep_cvar parameter is set, but the cvar table is missing from the font"
        )

    control_program = get_extra_assembly(font, "cvt")
    set_cvt_table(font, control_program)
    if "TSIC" in font and not keep_cvar:
        # Compile TSIC
        tsic = font["TSIC"].table
        cvts = font["cvt "].values
        # Gather the full set of cvts (not just those in TSIC) for all locations
        cvt_sets = [Vector(cvts)]
        for record in tsic.Record:
            cvt_local = {
                i: v
                for i, v in zip(record.CVTArray, record.CVTValueArray)
            }
            cvt_set = [
                cvt_local[i] if i in cvt_local else cvt
                for i, cvt in enumerate(cvts)
            ]
            cvt_sets.append(Vector(cvt_set))

        # Compute variations
        locs = [{axis_tag: 0.0
                 for axis_tag in tsic.AxisArray}]  # default instance
        locs += [{
            axis_tag: val
            for axis_tag, val in zip(tsic.AxisArray, loc.Axis)
        } for loc in tsic.RecordLocations]
        model = models.VariationModel(locs)
        variations = []
        deltas, supports = model.getDeltasAndSupports(cvt_sets)
        for i, (delta, support) in enumerate(zip(deltas[1:], supports[1:])):
            delta = [otRound(d) for d in delta]
            if all(abs(v) <= 0.5 for v in delta):
                continue
            # Remove any deltas that weren't specified in TSIC at this location
            # TODO: Just replace optimizaton with getting rid of 0 deltas?
            tsic_rec_index = model.reverseMapping[
                i + 1] - 1  # Map back to TSIC records
            delta = [
                d if j in tsic.Record[tsic_rec_index].CVTArray and d != 0 else
                None for j, d in enumerate(delta)
            ]
            var = TupleVariation(support, delta)
            variations.append(var)

        if variations:
            cvar = font["cvar"] = newTable("cvar")
            cvar.version = 1
            cvar.variations = variations

    for tag in ("prep", "fpgm"):
        if tag not in font:
            font[tag] = newTable(tag)
        data = get_extra_assembly(font, tag)
        font[tag].program = make_program(data, tag)

    glyph_order = font.getGlyphOrder()
    glyf_table = font["glyf"]
    for glyph_name in glyph_order:
        try:
            data = get_glyph_assembly(font, glyph_name)
        except KeyError:
            continue
        program, components = make_glyph_program(data, glyph_name)
        if program or components:
            glyph = glyf_table[glyph_name]
            if components:
                if not glyph.isComposite():
                    log.warning(
                        "Glyph '%s' contains components in VTT assembly but "
                        "not in glyf table; drop assembly and skip "
                        "compilation" % glyph_name)
                    set_glyph_assembly(font, glyph_name, "")
                else:
                    check_composite_info(glyph_name, glyph, components,
                                         glyph_order)
                    set_components_flags(glyph, components)
            if program:
                glyph.program = program

    if ship:
        for tag in ("TSI%s" % i for i in (0, 1, 2, 3, 5, "C")):
            if tag in font:
                del font[tag]
Beispiel #4
0
def _merge_TTHinting(font, masterModel, master_ttfs, tolerance=0.5):

    log.info("Merging TT hinting")
    assert "cvar" not in font

    # Check that the existing hinting is compatible

    # fpgm and prep table

    for tag in ("fpgm", "prep"):
        all_pgms = [m[tag].program for m in master_ttfs if tag in m]
        if len(all_pgms) == 0:
            continue
        if tag in font:
            font_pgm = font[tag].program
        else:
            font_pgm = Program()
        if any(pgm != font_pgm for pgm in all_pgms):
            log.warning(
                "Masters have incompatible %s tables, hinting is discarded." %
                tag)
            _remove_TTHinting(font)
            return

    # glyf table

    for name, glyph in font["glyf"].glyphs.items():
        all_pgms = [
            m["glyf"][name].program for m in master_ttfs
            if name in m['glyf'] and hasattr(m["glyf"][name], "program")
        ]
        if not any(all_pgms):
            continue
        glyph.expand(font["glyf"])
        if hasattr(glyph, "program"):
            font_pgm = glyph.program
        else:
            font_pgm = Program()
        if any(pgm != font_pgm for pgm in all_pgms if pgm):
            log.warning(
                "Masters have incompatible glyph programs in glyph '%s', hinting is discarded."
                % name)
            # TODO Only drop hinting from this glyph.
            _remove_TTHinting(font)
            return

    # cvt table

    all_cvs = [
        Vector(m["cvt "].values) if 'cvt ' in m else None for m in master_ttfs
    ]

    nonNone_cvs = models.nonNone(all_cvs)
    if not nonNone_cvs:
        # There is no cvt table to make a cvar table from, we're done here.
        return

    if not models.allEqual(len(c) for c in nonNone_cvs):
        log.warning(
            "Masters have incompatible cvt tables, hinting is discarded.")
        _remove_TTHinting(font)
        return

    variations = []
    deltas, supports = masterModel.getDeltasAndSupports(all_cvs)
    for i, (delta, support) in enumerate(zip(deltas[1:], supports[1:])):
        delta = [otRound(d) for d in delta]
        if all(abs(v) <= tolerance for v in delta):
            continue
        var = TupleVariation(support, delta)
        variations.append(var)

    # We can build the cvar table now.
    if variations:
        cvar = font["cvar"] = newTable('cvar')
        cvar.version = 1
        cvar.variations = variations