diff --git a/Lib/fontTools/varLib/interpolatable.py b/Lib/fontTools/varLib/interpolatable.py index d6bf817cb..20b99921e 100644 --- a/Lib/fontTools/varLib/interpolatable.py +++ b/Lib/fontTools/varLib/interpolatable.py @@ -442,6 +442,11 @@ def main(args=None): action="store", help="Output report in PDF format", ) + parser.add_argument( + "--html", + action="store", + help="Output report in HTML format", + ) parser.add_argument( "--quiet", action="store_true", @@ -693,6 +698,23 @@ def main(args=None): if not problems: pdf.draw_cupcake() + if args.html: + from .interpolatablePlot import InterpolatableSVG + + svgs = [] + with InterpolatableSVG(svgs, glyphsets=glyphsets, names=names) as svg: + svg.add_problems(problems) + if not problems: + svg.draw_cupcake() + + with open(args.html, "wb") as f: + f.write(b"\n") + f.write(b"\n") + for svg in svgs: + f.write(svg) + f.write(b"
\n") + f.write(b"\n") + if problems: return problems diff --git a/Lib/fontTools/varLib/interpolatablePlot.py b/Lib/fontTools/varLib/interpolatablePlot.py index e127763c8..795c44e8f 100644 --- a/Lib/fontTools/varLib/interpolatablePlot.py +++ b/Lib/fontTools/varLib/interpolatablePlot.py @@ -5,6 +5,7 @@ from fontTools.pens.pointPen import SegmentToPointPen from fontTools.varLib.interpolatable import PerContourOrComponentPen, RecordingPointPen from itertools import cycle from functools import wraps +from io import BytesIO import cairo import math @@ -76,10 +77,10 @@ class InterpolatablePlot: setattr(self, k, v) def __enter__(self): - raise NotImplementedError + return self def __exit__(self, type, value, traceback): - raise NotImplementedError + pass def set_size(self, width, height): raise NotImplementedError @@ -427,3 +428,18 @@ class InterpolatablePDF(InterpolatablePostscriptLike): def __enter__(self): self.surface = cairo.PDFSurface(self.out, self.width, self.height) return self + + +class InterpolatableSVG(InterpolatablePlot): + @wraps(InterpolatablePlot.__init__) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def set_size(self, width, height): + self.sink = BytesIO() + self.surface = cairo.SVGSurface(self.sink, width, height) + + def show_page(self): + self.surface.finish() + self.out.append(self.sink.getvalue()) + self.surface = None