diff options
Diffstat (limited to 'Lib/fontTools/ttLib/scaleUpem.py')
-rw-r--r-- | Lib/fontTools/ttLib/scaleUpem.py | 86 |
1 files changed, 72 insertions, 14 deletions
diff --git a/Lib/fontTools/ttLib/scaleUpem.py b/Lib/fontTools/ttLib/scaleUpem.py index 9e0e0ade..3f9b22af 100644 --- a/Lib/fontTools/ttLib/scaleUpem.py +++ b/Lib/fontTools/ttLib/scaleUpem.py @@ -10,7 +10,9 @@ import fontTools.ttLib.tables.otBase as otBase import fontTools.ttLib.tables.otTables as otTables from fontTools.cffLib import VarStoreData import fontTools.cffLib.specializer as cffSpecializer +from fontTools.varLib import builder # for VarData.calculateNumShorts from fontTools.misc.fixedTools import otRound +from fontTools.ttLib.tables._g_l_y_f import VarComponentFlags __all__ = ["scale_upem", "ScalerVisitor"] @@ -111,30 +113,82 @@ def visit(visitor, obj, attr, VOriginRecords): @ScalerVisitor.register_attr(ttLib.getTableClass("glyf"), "glyphs") def visit(visitor, obj, attr, glyphs): for g in glyphs.values(): + for attr in ("xMin", "xMax", "yMin", "yMax"): + v = getattr(g, attr, None) + if v is not None: + setattr(g, attr, visitor.scale(v)) + if g.isComposite(): for component in g.components: component.x = visitor.scale(component.x) component.y = visitor.scale(component.y) - else: - for attr in ("xMin", "xMax", "yMin", "yMax"): - v = getattr(g, attr, None) - if v is not None: - setattr(g, attr, visitor.scale(v)) + continue - glyf = visitor.font["glyf"] - coordinates = g.getCoordinates(glyf)[0] - for i, (x, y) in enumerate(coordinates): - coordinates[i] = visitor.scale(x), visitor.scale(y) + if g.isVarComposite(): + for component in g.components: + for attr in ("translateX", "translateY", "tCenterX", "tCenterY"): + v = getattr(component.transform, attr) + setattr(component.transform, attr, visitor.scale(v)) + continue + + if hasattr(g, "coordinates"): + coordinates = g.coordinates + for i, (x, y) in enumerate(coordinates): + coordinates[i] = visitor.scale(x), visitor.scale(y) @ScalerVisitor.register_attr(ttLib.getTableClass("gvar"), "variations") def visit(visitor, obj, attr, variations): - for varlist in variations.values(): + # VarComposites are a pain to handle :-( + glyfTable = visitor.font["glyf"] + + for glyphName, varlist in variations.items(): + glyph = glyfTable[glyphName] + isVarComposite = glyph.isVarComposite() for var in varlist: coordinates = var.coordinates - for i, xy in enumerate(coordinates): - if xy is None: - continue + + if not isVarComposite: + for i, xy in enumerate(coordinates): + if xy is None: + continue + coordinates[i] = visitor.scale(xy[0]), visitor.scale(xy[1]) + continue + + # VarComposite glyph + + i = 0 + for component in glyph.components: + if component.flags & VarComponentFlags.AXES_HAVE_VARIATION: + i += len(component.location) + if component.flags & ( + VarComponentFlags.HAVE_TRANSLATE_X + | VarComponentFlags.HAVE_TRANSLATE_Y + ): + xy = coordinates[i] + coordinates[i] = visitor.scale(xy[0]), visitor.scale(xy[1]) + i += 1 + if component.flags & VarComponentFlags.HAVE_ROTATION: + i += 1 + if component.flags & ( + VarComponentFlags.HAVE_SCALE_X | VarComponentFlags.HAVE_SCALE_Y + ): + i += 1 + if component.flags & ( + VarComponentFlags.HAVE_SKEW_X | VarComponentFlags.HAVE_SKEW_Y + ): + i += 1 + if component.flags & ( + VarComponentFlags.HAVE_TCENTER_X | VarComponentFlags.HAVE_TCENTER_Y + ): + xy = coordinates[i] + coordinates[i] = visitor.scale(xy[0]), visitor.scale(xy[1]) + i += 1 + + # Phantom points + assert i + 4 == len(coordinates) + for i in range(i, len(coordinates)): + xy = coordinates[i] coordinates[i] = visitor.scale(xy[0]), visitor.scale(xy[1]) @@ -149,7 +203,8 @@ def visit(visitor, obj, attr, kernTables): def _cff_scale(visitor, args): for i, arg in enumerate(args): if not isinstance(arg, list): - args[i] = visitor.scale(arg) + if not isinstance(arg, bytes): + args[i] = visitor.scale(arg) else: num_blends = arg[-1] _cff_scale(visitor, arg) @@ -176,6 +231,8 @@ def visit(visitor, obj, attr, cff): c.program, getNumRegions=getNumRegions ) for op, args in commands: + if op == "vsindex": + continue _cff_scale(visitor, args) c.program[:] = cffSpecializer.commandsToProgram(commands) @@ -231,6 +288,7 @@ def visit(visitor, varData): for item in varData.Item: for i, v in enumerate(item): item[i] = visitor.scale(v) + varData.calculateNumShorts() # COLRv1 |