HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //proc/1233/cwd/home/arjun/projects/env/lib/python3.10/site-packages/fontTools/pens/boundsPen.py
from fontTools.misc.arrayTools import updateBounds, pointInRect, unionRect
from fontTools.misc.bezierTools import calcCubicBounds, calcQuadraticBounds
from fontTools.pens.basePen import BasePen


__all__ = ["BoundsPen", "ControlBoundsPen"]


class ControlBoundsPen(BasePen):

    """Pen to calculate the "control bounds" of a shape. This is the
    bounding box of all control points, so may be larger than the
    actual bounding box if there are curves that don't have points
    on their extremes.

    When the shape has been drawn, the bounds are available as the
    ``bounds`` attribute of the pen object. It's a 4-tuple::

            (xMin, yMin, xMax, yMax).

    If ``ignoreSinglePoints`` is True, single points are ignored.
    """

    def __init__(self, glyphSet, ignoreSinglePoints=False):
        BasePen.__init__(self, glyphSet)
        self.ignoreSinglePoints = ignoreSinglePoints
        self.init()

    def init(self):
        self.bounds = None
        self._start = None

    def _moveTo(self, pt):
        self._start = pt
        if not self.ignoreSinglePoints:
            self._addMoveTo()

    def _addMoveTo(self):
        if self._start is None:
            return
        bounds = self.bounds
        if bounds:
            self.bounds = updateBounds(bounds, self._start)
        else:
            x, y = self._start
            self.bounds = (x, y, x, y)
        self._start = None

    def _lineTo(self, pt):
        self._addMoveTo()
        self.bounds = updateBounds(self.bounds, pt)

    def _curveToOne(self, bcp1, bcp2, pt):
        self._addMoveTo()
        bounds = self.bounds
        bounds = updateBounds(bounds, bcp1)
        bounds = updateBounds(bounds, bcp2)
        bounds = updateBounds(bounds, pt)
        self.bounds = bounds

    def _qCurveToOne(self, bcp, pt):
        self._addMoveTo()
        bounds = self.bounds
        bounds = updateBounds(bounds, bcp)
        bounds = updateBounds(bounds, pt)
        self.bounds = bounds


class BoundsPen(ControlBoundsPen):

    """Pen to calculate the bounds of a shape. It calculates the
    correct bounds even when the shape contains curves that don't
    have points on their extremes. This is somewhat slower to compute
    than the "control bounds".

    When the shape has been drawn, the bounds are available as the
    ``bounds`` attribute of the pen object. It's a 4-tuple::

            (xMin, yMin, xMax, yMax)
    """

    def _curveToOne(self, bcp1, bcp2, pt):
        self._addMoveTo()
        bounds = self.bounds
        bounds = updateBounds(bounds, pt)
        if not pointInRect(bcp1, bounds) or not pointInRect(bcp2, bounds):
            bounds = unionRect(
                bounds, calcCubicBounds(self._getCurrentPoint(), bcp1, bcp2, pt)
            )
        self.bounds = bounds

    def _qCurveToOne(self, bcp, pt):
        self._addMoveTo()
        bounds = self.bounds
        bounds = updateBounds(bounds, pt)
        if not pointInRect(bcp, bounds):
            bounds = unionRect(
                bounds, calcQuadraticBounds(self._getCurrentPoint(), bcp, pt)
            )
        self.bounds = bounds