# Source code for fontTools.ttLib.tables._g_a_s_p

    from fontTools.misc.textTools import safeEval
    from . import DefaultTable
    import struct

    GASP_SYMMETRIC_GRIDFIT = 0x0004
    GASP_SYMMETRIC_SMOOTHING = 0x0008
    GASP_DOGRAY = 0x0002
    GASP_GRIDFIT = 0x0001

    class table__g_a_s_p(DefaultTable.DefaultTable):
        """Grid-fitting and Scan-conversion Procedure table

        The ``gasp`` table defines the preferred rasterization settings for
        the font when rendered on monochrome and greyscale output devices.

        See also https://learn.microsoft.com/en-us/typography/opentype/spec/gasp
        """

        def decompile(self, data, ttFont):
            self.version, numRanges = struct.unpack(">HH", data[:4])
            assert 0 <= self.version <= 1, "unknown 'gasp' format: %s" % self.version
            data = data[4:]
            self.gaspRange = {}
            for i in range(numRanges):
                rangeMaxPPEM, rangeGaspBehavior = struct.unpack(">HH", data[:4])
                self.gaspRange[int(rangeMaxPPEM)] = int(rangeGaspBehavior)
                data = data[4:]
            assert not data, "too much data"

        def compile(self, ttFont):
            version = 0  # ignore self.version
            numRanges = len(self.gaspRange)
            data = b""
            items = sorted(self.gaspRange.items())
            for rangeMaxPPEM, rangeGaspBehavior in items:
                data = data + struct.pack(">HH", rangeMaxPPEM, rangeGaspBehavior)
                if rangeGaspBehavior & ~(GASP_GRIDFIT | GASP_DOGRAY):
                    version = 1
            data = struct.pack(">HH", version, numRanges) + data
            return data

        def toXML(self, writer, ttFont):
            items = sorted(self.gaspRange.items())
            for rangeMaxPPEM, rangeGaspBehavior in items:
                writer.simpletag(
                    "gaspRange",
                    [
                        ("rangeMaxPPEM", rangeMaxPPEM),
                        ("rangeGaspBehavior", rangeGaspBehavior),
                    ],
                )
                writer.newline()

        def fromXML(self, name, attrs, content, ttFont):
            if name != "gaspRange":
                return
            if not hasattr(self, "gaspRange"):
                self.gaspRange = {}
            self.gaspRange[safeEval(attrs["rangeMaxPPEM"])] = safeEval(
                attrs["rangeGaspBehavior"]
            )