text: from __future__ import print_function, division, absolute_import
  from fontTools.misc.py23 import *
  from fontTools import ttLib
  from fontTools.misc import sstruct
  from fontTools.misc.fixedTools import fixedToFloat, floatToFixed
  from fontTools.misc.textTools import safeEval
  from fontTools.ttLib import TTLibError
  from . import DefaultTable
  import array
  import struct
  import logging
  
  
  log = logging.getLogger(__name__)
  
  # Apple's documentation of 'avar':
  # https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6avar.html
  
  AVAR_HEADER_FORMAT = """
      > # big endian
      majorVersion:  H
      minorVersion:  H
      reserved:      H
      axisCount:     H
  """
  assert sstruct.calcsize(AVAR_HEADER_FORMAT) == 8, sstruct.calcsize(AVAR_HEADER_FORMAT)
  
  
  class table__a_v_a_r(DefaultTable.DefaultTable):
  
      dependencies = ["fvar"]
  
      def __init__(self, tag=None):
          DefaultTable.DefaultTable.__init__(self, tag)
          self.segments = {}
  
      def compile(self, ttFont):
          axisTags = [axis.axisTag for axis in ttFont["fvar"].axes]
          header = {
              "majorVersion": 1,
              "minorVersion": 0,
              "reserved": 0,
              "axisCount": len(axisTags)
          }
          result = [sstruct.pack(AVAR_HEADER_FORMAT, header)]
          for axis in axisTags:
              mappings = sorted(self.segments[axis].items())
              result.append(struct.pack(">H", len(mappings)))
              for key, value in mappings:
                  fixedKey = floatToFixed(key, 14)
                  fixedValue = floatToFixed(value, 14)
                  result.append(struct.pack(">hh", fixedKey, fixedValue))
          return bytesjoin(result)
  
      def decompile(self, data, ttFont):
          axisTags = [axis.axisTag for axis in ttFont["fvar"].axes]
          header = {}
          headerSize = sstruct.calcsize(AVAR_HEADER_FORMAT)
          header = sstruct.unpack(AVAR_HEADER_FORMAT, data[0:headerSize])
          majorVersion = header["majorVersion"]
          if majorVersion != 1:
              raise TTLibError("unsupported 'avar' version %d" % majorVersion)
          pos = headerSize
          for axis in axisTags:
              segments = self.segments[axis] = {}
              numPairs = struct.unpack(">H", data[pos:pos+2])[0]
              pos = pos + 2
              for _ in range(numPairs):
                  fromValue, toValue = struct.unpack(">hh", data[pos:pos+4])
                  segments[fixedToFloat(fromValue, 14)] = fixedToFloat(toValue, 14)
                  pos = pos + 4
  
      def toXML(self, writer, ttFont):
          axisTags = [axis.axisTag for axis in ttFont["fvar"].axes]
          for axis in axisTags:
              writer.begintag("segment", axis=axis)
              writer.newline()
              for key, value in sorted(self.segments[axis].items()):
                  # roundtrip float -> fixed -> float to normalize TTX output
                  # as dumped after decompiling or straight from varLib
                  key = fixedToFloat(floatToFixed(key, 14), 14)
                  value = fixedToFloat(floatToFixed(value, 14), 14)
                  writer.simpletag("mapping", **{"from": key, "to": value})
                  writer.newline()
              writer.endtag("segment")
              writer.newline()
  
      def fromXML(self, name, attrs, content, ttFont):
          if name == "segment":
              axis = attrs["axis"]
              segment = self.segments[axis] = {}
              for element in content:
                  if isinstance(element, tuple):
                      elementName, elementAttrs, _ = element
                      if elementName == "mapping":
                          fromValue = safeEval(elementAttrs["from"])
                          toValue = safeEval(elementAttrs["to"])
                          if fromValue in segment:
                              log.warning("duplicate entry for %s in axis '%s'",
                                          fromValue, axis)
                          segment[fromValue] = toValue
  