prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  ascender and ascent
  The [opentype spec ](https://docs.microsoft.com/en-gb/typography/opentype/spec/hhea) calls the first two substantive entries in the `hhea` table "`ascender`" and "`descender`". fonttools calls them "`ascent`" and "`descent`".
  
  This was surprising! Maybe it's too late to change then but can we at least have an alias?
  
  </issue>
  <code>
  [start of Lib/fontTools/ttLib/tables/_h_h_e_a.py]
  1 from fontTools.misc.py23 import *
  2 from fontTools.misc import sstruct
  3 from fontTools.misc.textTools import safeEval
  4 from fontTools.misc.fixedTools import (
  5 	ensureVersionIsLong as fi2ve, versionToFixed as ve2fi)
  6 from . import DefaultTable
  7 import math
  8 
  9 
  10 hheaFormat = """
  11 		>  # big endian
  12 		tableVersion:           L
  13 		ascent:                 h
  14 		descent:                h
  15 		lineGap:                h
  16 		advanceWidthMax:        H
  17 		minLeftSideBearing:     h
  18 		minRightSideBearing:    h
  19 		xMaxExtent:             h
  20 		caretSlopeRise:         h
  21 		caretSlopeRun:          h
  22 		caretOffset:            h
  23 		reserved0:              h
  24 		reserved1:              h
  25 		reserved2:              h
  26 		reserved3:              h
  27 		metricDataFormat:       h
  28 		numberOfHMetrics:       H
  29 """
  30 
  31 
  32 class table__h_h_e_a(DefaultTable.DefaultTable):
  33 
  34 	# Note: Keep in sync with table__v_h_e_a
  35 
  36 	dependencies = ['hmtx', 'glyf', 'CFF ']
  37 
  38 	def decompile(self, data, ttFont):
  39 		sstruct.unpack(hheaFormat, data, self)
  40 
  41 	def compile(self, ttFont):
  42 		if ttFont.recalcBBoxes and (ttFont.isLoaded('glyf') or ttFont.isLoaded('CFF ')):
  43 			self.recalc(ttFont)
  44 		self.tableVersion = fi2ve(self.tableVersion)
  45 		return sstruct.pack(hheaFormat, self)
  46 
  47 	def recalc(self, ttFont):
  48 		if 'hmtx' in ttFont:
  49 			hmtxTable = ttFont['hmtx']
  50 			self.advanceWidthMax = max(adv for adv, _ in hmtxTable.metrics.values())
  51 
  52 		boundsWidthDict = {}
  53 		if 'glyf' in ttFont:
  54 			glyfTable = ttFont['glyf']
  55 			for name in ttFont.getGlyphOrder():
  56 				g = glyfTable[name]
  57 				if g.numberOfContours == 0:
  58 					continue
  59 				if g.numberOfContours < 0 and not hasattr(g, "xMax"):
  60 					# Composite glyph without extents set.
  61 					# Calculate those.
  62 					g.recalcBounds(glyfTable)
  63 				boundsWidthDict[name] = g.xMax - g.xMin
  64 		elif 'CFF ' in ttFont:
  65 			topDict = ttFont['CFF '].cff.topDictIndex[0]
  66 			charStrings = topDict.CharStrings
  67 			for name in ttFont.getGlyphOrder():
  68 				cs = charStrings[name]
  69 				bounds = cs.calcBounds(charStrings)
  70 				if bounds is not None:
  71 					boundsWidthDict[name] = int(
  72 						math.ceil(bounds[2]) - math.floor(bounds[0]))
  73 
  74 		if boundsWidthDict:
  75 			minLeftSideBearing = float('inf')
  76 			minRightSideBearing = float('inf')
  77 			xMaxExtent = -float('inf')
  78 			for name, boundsWidth in boundsWidthDict.items():
  79 				advanceWidth, lsb = hmtxTable[name]
  80 				rsb = advanceWidth - lsb - boundsWidth
  81 				extent = lsb + boundsWidth
  82 				minLeftSideBearing = min(minLeftSideBearing, lsb)
  83 				minRightSideBearing = min(minRightSideBearing, rsb)
  84 				xMaxExtent = max(xMaxExtent, extent)
  85 			self.minLeftSideBearing = minLeftSideBearing
  86 			self.minRightSideBearing = minRightSideBearing
  87 			self.xMaxExtent = xMaxExtent
  88 
  89 		else:  # No glyph has outlines.
  90 			self.minLeftSideBearing = 0
  91 			self.minRightSideBearing = 0
  92 			self.xMaxExtent = 0
  93 
  94 	def toXML(self, writer, ttFont):
  95 		formatstring, names, fixes = sstruct.getformat(hheaFormat)
  96 		for name in names:
  97 			value = getattr(self, name)
  98 			if name == "tableVersion":
  99 				value = fi2ve(value)
  100 				value = "0x%08x" % value
  101 			writer.simpletag(name, value=value)
  102 			writer.newline()
  103 
  104 	def fromXML(self, name, attrs, content, ttFont):
  105 		if name == "tableVersion":
  106 			setattr(self, name, ve2fi(attrs["value"]))
  107 			return
  108 		setattr(self, name, safeEval(attrs["value"]))
  109
  [end of Lib/fontTools/ttLib/tables/_h_h_e_a.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/Lib/fontTools/ttLib/tables/_h_h_e_a.py b/Lib/fontTools/ttLib/tables/_h_h_e_a.py
  --- a/Lib/fontTools/ttLib/tables/_h_h_e_a.py
  +++ b/Lib/fontTools/ttLib/tables/_h_h_e_a.py
  @@ -35,6 +35,19 @@
   
   	dependencies = ['hmtx', 'glyf', 'CFF ']
   
  +	# OpenType spec renamed these, add aliases for compatibility
  +	@property
  +	def ascender(self): return self.ascent
  +
  +	@ascender.setter
  +	def ascender(self,value): self.ascent = value
  +
  +	@property
  +	def descender(self): return self.descent
  +
  +	@descender.setter
  +	def descender(self,value): self.descent = value
  +
   	def decompile(self, data, ttFont):
   		sstruct.unpack(hheaFormat, data, self)
  
verification_info: {"golden_diff": "diff --git a/Lib/fontTools/ttLib/tables/_h_h_e_a.py b/Lib/fontTools/ttLib/tables/_h_h_e_a.py\n--- a/Lib/fontTools/ttLib/tables/_h_h_e_a.py\n+++ b/Lib/fontTools/ttLib/tables/_h_h_e_a.py\n@@ -35,6 +35,19 @@\n \n \tdependencies = ['hmtx', 'glyf', 'CFF ']\n \n+\t# OpenType spec renamed these, add aliases for compatibility\n+\t@property\n+\tdef ascender(self): return self.ascent\n+\n+\t@ascender.setter\n+\tdef ascender(self,value): self.ascent = value\n+\n+\t@property\n+\tdef descender(self): return self.descent\n+\n+\t@descender.setter\n+\tdef descender(self,value): self.descent = value\n+\n \tdef decompile(self, data, ttFont):\n \t\tsstruct.unpack(hheaFormat, data, self)\n", "issue": "ascender and ascent\nThe [opentype spec ](https://docs.microsoft.com/en-gb/typography/opentype/spec/hhea) calls the first two substantive entries in the `hhea` table \"`ascender`\" and \"`descender`\". fonttools calls them \"`ascent`\" and \"`descent`\".\r\n\r\nThis was surprising! Maybe it's too late to change then but can we at least have an alias?\n", "before_files": [{"content": "from fontTools.misc.py23 import *\nfrom fontTools.misc import sstruct\nfrom fontTools.misc.textTools import safeEval\nfrom fontTools.misc.fixedTools import (\n\tensureVersionIsLong as fi2ve, versionToFixed as ve2fi)\nfrom . import DefaultTable\nimport math\n\n\nhheaFormat = \"\"\"\n\t\t>  # big endian\n\t\ttableVersion:           L\n\t\tascent:                 h\n\t\tdescent:                h\n\t\tlineGap:                h\n\t\tadvanceWidthMax:        H\n\t\tminLeftSideBearing:     h\n\t\tminRightSideBearing:    h\n\t\txMaxExtent:             h\n\t\tcaretSlopeRise:         h\n\t\tcaretSlopeRun:          h\n\t\tcaretOffset:            h\n\t\treserved0:              h\n\t\treserved1:              h\n\t\treserved2:              h\n\t\treserved3:              h\n\t\tmetricDataFormat:       h\n\t\tnumberOfHMetrics:       H\n\"\"\"\n\n\nclass table__h_h_e_a(DefaultTable.DefaultTable):\n\n\t# Note: Keep in sync with table__v_h_e_a\n\n\tdependencies = ['hmtx', 'glyf', 'CFF ']\n\n\tdef decompile(self, data, ttFont):\n\t\tsstruct.unpack(hheaFormat, data, self)\n\n\tdef compile(self, ttFont):\n\t\tif ttFont.recalcBBoxes and (ttFont.isLoaded('glyf') or ttFont.isLoaded('CFF ')):\n\t\t\tself.recalc(ttFont)\n\t\tself.tableVersion = fi2ve(self.tableVersion)\n\t\treturn sstruct.pack(hheaFormat, self)\n\n\tdef recalc(self, ttFont):\n\t\tif 'hmtx' in ttFont:\n\t\t\thmtxTable = ttFont['hmtx']\n\t\t\tself.advanceWidthMax = max(adv for adv, _ in hmtxTable.metrics.values())\n\n\t\tboundsWidthDict = {}\n\t\tif 'glyf' in ttFont:\n\t\t\tglyfTable = ttFont['glyf']\n\t\t\tfor name in ttFont.getGlyphOrder():\n\t\t\t\tg = glyfTable[name]\n\t\t\t\tif g.numberOfContours == 0:\n\t\t\t\t\tcontinue\n\t\t\t\tif g.numberOfContours < 0 and not hasattr(g, \"xMax\"):\n\t\t\t\t\t# Composite glyph without extents set.\n\t\t\t\t\t# Calculate those.\n\t\t\t\t\tg.recalcBounds(glyfTable)\n\t\t\t\tboundsWidthDict[name] = g.xMax - g.xMin\n\t\telif 'CFF ' in ttFont:\n\t\t\ttopDict = ttFont['CFF '].cff.topDictIndex[0]\n\t\t\tcharStrings = topDict.CharStrings\n\t\t\tfor name in ttFont.getGlyphOrder():\n\t\t\t\tcs = charStrings[name]\n\t\t\t\tbounds = cs.calcBounds(charStrings)\n\t\t\t\tif bounds is not None:\n\t\t\t\t\tboundsWidthDict[name] = int(\n\t\t\t\t\t\tmath.ceil(bounds[2]) - math.floor(bounds[0]))\n\n\t\tif boundsWidthDict:\n\t\t\tminLeftSideBearing = float('inf')\n\t\t\tminRightSideBearing = float('inf')\n\t\t\txMaxExtent = -float('inf')\n\t\t\tfor name, boundsWidth in boundsWidthDict.items():\n\t\t\t\tadvanceWidth, lsb = hmtxTable[name]\n\t\t\t\trsb = advanceWidth - lsb - boundsWidth\n\t\t\t\textent = lsb + boundsWidth\n\t\t\t\tminLeftSideBearing = min(minLeftSideBearing, lsb)\n\t\t\t\tminRightSideBearing = min(minRightSideBearing, rsb)\n\t\t\t\txMaxExtent = max(xMaxExtent, extent)\n\t\t\tself.minLeftSideBearing = minLeftSideBearing\n\t\t\tself.minRightSideBearing = minRightSideBearing\n\t\t\tself.xMaxExtent = xMaxExtent\n\n\t\telse:  # No glyph has outlines.\n\t\t\tself.minLeftSideBearing = 0\n\t\t\tself.minRightSideBearing = 0\n\t\t\tself.xMaxExtent = 0\n\n\tdef toXML(self, writer, ttFont):\n\t\tformatstring, names, fixes = sstruct.getformat(hheaFormat)\n\t\tfor name in names:\n\t\t\tvalue = getattr(self, name)\n\t\t\tif name == \"tableVersion\":\n\t\t\t\tvalue = fi2ve(value)\n\t\t\t\tvalue = \"0x%08x\" % value\n\t\t\twriter.simpletag(name, value=value)\n\t\t\twriter.newline()\n\n\tdef fromXML(self, name, attrs, content, ttFont):\n\t\tif name == \"tableVersion\":\n\t\t\tsetattr(self, name, ve2fi(attrs[\"value\"]))\n\t\t\treturn\n\t\tsetattr(self, name, safeEval(attrs[\"value\"]))\n", "path": "Lib/fontTools/ttLib/tables/_h_h_e_a.py"}]}