Source code for foundrytools.core.tables.hhea

import math
from copy import deepcopy

from fontTools.misc.roundTools import otRound
from fontTools.ttLib import TTFont
from fontTools.ttLib.tables._h_h_e_a import table__h_h_e_a

from foundrytools.constants import T_HEAD, T_HHEA, T_POST
from foundrytools.core.tables.default import DefaultTbl


[docs] class HheaTable(DefaultTbl): """This class extends the fontTools ``hhea`` tables.""" def __init__(self, ttfont: TTFont) -> None: """ Initializes the ``hhea`` table handler. :param ttfont: The ``TTFont`` object. :type ttfont: TTFont """ super().__init__(ttfont=ttfont, table_tag=T_HHEA) self._copy = deepcopy(self.table) @property def table(self) -> table__h_h_e_a: """ The wrapped ``table__h_h_e_a`` table object. """ return self._table @table.setter def table(self, value: table__h_h_e_a) -> None: """ Wraps a new ``table__h_h_e_a`` object. """ self._table = value @property def is_modified(self) -> bool: """ A read-only property that returns whether the ``hhea`` table has been modified. :return: Whether the ``hhea`` table has been modified. :rtype: bool """ return self._copy.compile(self.ttfont) != self.table.compile(self.ttfont) @property def ascent(self) -> int: """ A property with getter and setter for the ``ascent`` field of the ``hhea`` table. :return: The ``ascent`` value. :rtype: int """ return self.table.ascent @ascent.setter def ascent(self, value: int) -> None: """Sets the ``ascent`` field of the ``hhea`` table.""" self.table.ascent = value @property def descent(self) -> int: """ A property with getter and setter for the ``descent`` field of the ``hhea`` table. :return: The ``descent`` value. :rtype: int """ return self.table.descent @descent.setter def descent(self, value: int) -> None: """Sets the ``descent`` field of the ``hhea`` table.""" self.table.descent = value @property def line_gap(self) -> int: """ A property with getter and setter for the ``lineGap`` field of the ``hhea`` table. :return: The ``lineGap`` value. :rtype: int """ return self.table.lineGap @line_gap.setter def line_gap(self, value: int) -> None: """Sets the ``lineGap`` field of the ``hhea`` table.""" self.table.lineGap = value @property def advance_width_max(self) -> int: """ A property with getter and setter for the ``advanceWidthMax`` field of the ``hhea`` table. :return: The ``advanceWidthMax`` value. :rtype: int """ return self.table.advanceWidthMax @advance_width_max.setter def advance_width_max(self, value: int) -> None: """Sets the ``advanceWidthMax`` field of the ``hhea`` table.""" self.table.advanceWidthMax = value @property def min_left_side_bearing(self) -> int: """ A read-only property for the ``minLeftSideBearing`` field of the ``hhea`` table. :return: The ``minLeftSideBearing`` value. :rtype: int """ return self.table.minLeftSideBearing @property def min_right_side_bearing(self) -> int: """ A read-only property for the ``minRightSideBearing`` field of the ``hhea`` table. :return: The ``minRightSideBearing`` value. :rtype: int """ return self.table.minRightSideBearing @property def x_max_extent(self) -> int: """ A read-only property for the ``xMaxExtent`` field of the ``hhea`` table. :return: The ``xMaxExtent`` value. :rtype: int """ return self.table.xMaxExtent @property def caret_slope_rise(self) -> int: """ A property with getter and setter for the ``caretSlopeRise`` field of the ``hhea`` table. :return: The ``caretSlopeRise`` value. :rtype: int """ return self.table.caretSlopeRise @caret_slope_rise.setter def caret_slope_rise(self, value: int) -> None: """Sets the ``caretSlopeRise`` field of the ``hhea`` table.""" self.table.caretSlopeRise = value @property def caret_slope_run(self) -> int: """ A property with getter and setter for the ``caretSlopeRun`` field of the ``hhea`` table. :return: The ``caretSlopeRun`` value. :rtype: int """ return self.table.caretSlopeRun @caret_slope_run.setter def caret_slope_run(self, value: int) -> None: """Sets the ``caretSlopeRun`` field of the ``hhea`` table.""" self.table.caretSlopeRun = value @property def caret_offset(self) -> int: """ A property with getter and setter for the ``caretOffset`` field of the ``hhea`` table. :return: The ``caretOffset`` value. :rtype: int """ return self.table.caretOffset @caret_offset.setter def caret_offset(self, value: int) -> None: """Sets the ``caretOffset`` field of the ``hhea`` table.""" self.table.caretOffset = value @property def metric_data_format(self) -> int: """ A read-only property for the ``metricDataFormat`` field of the ``hhea`` table. :return: The ``metricDataFormat`` value. :rtype: int """ return self.table.metricDataFormat @property def number_of_hmetrics(self) -> int: """ A read-only property for the ``numberOfHMetrics`` field of the ``hhea`` table. :return: The ``numberOfHMetrics`` value. :rtype: int """ return self.table.numberOfHMetrics @property def run_rise_angle(self) -> float: """ Calculate the slope angle by dividing the caret slope run by the caret slope rise. :return: The slope angle in degrees. :rtype: float """ rise = self.table.caretSlopeRise run = self.table.caretSlopeRun run_rise_angle = math.degrees(math.atan(-run / rise)) return run_rise_angle
[docs] def calc_caret_slope_rise(self, italic_angle: int | float | None = None) -> int: """ Calculate the ``caretSlopeRise`` field of the ``hhea`` table. :param italic_angle: The italic to use for the calculation. If ``None``, the italic angle from the ``post`` table will be used. :type italic_angle: Optional[Union[int, float]] :return: The caret slope rise value. :rtype: int """ if italic_angle is None: italic_angle = self.ttfont[T_POST].italicAngle if italic_angle == 0: return 1 return self.ttfont[T_HEAD].unitsPerEm
[docs] def calc_caret_slope_run(self, italic_angle: int | float | None = None) -> int: """ Calculate the ``caretSlopeRun`` field of the ``hhea`` table. :param italic_angle: The italic to use for the calculation. If ``None``, the italic angle from the ``post`` table will be used. :type italic_angle: Optional[Union[int, float]] :return: The caret slope run value. :rtype: int """ if italic_angle is None: italic_angle = self.ttfont[T_POST].italicAngle if italic_angle == 0: return 0 return otRound( math.tan(math.radians(-self.ttfont[T_POST].italicAngle)) * self.ttfont[T_HEAD].unitsPerEm )