+
    i=                    L   R t ^ RIHt ^ RIt^ RIHt ^ RIHt . ROtRt	^]	,
          t
R]	,           tR R	 lt ! R
 R]4      t]! 4       tRR R lltRR R llt] ! R R4      4       t]R8X  d6   ^ RIt^ RIt]P*                  ! ]P,                  ! 4       P.                  4       R# R# )a	  Affine 2D transformation matrix class.

The Transform class implements various transformation matrix operations,
both on the matrix itself, as well as on 2D coordinates.

Transform instances are effectively immutable: all methods that operate on the
transformation itself always return a new instance. This has as the
interesting side effect that Transform instances are hashable, ie. they can be
used as dictionary keys.

This module exports the following symbols:

Transform
        this is the main class
Identity
        Transform instance set to the identity transformation
Offset
        Convenience function that returns a translating transformation
Scale
        Convenience function that returns a scaling transformation

The DecomposedTransform class implements a transformation with separate
translate, rotation, scale, skew, and transformation-center components.

:Example:

        >>> t = Transform(2, 0, 0, 3, 0, 0)
        >>> t.transformPoint((100, 100))
        (200, 300)
        >>> t = Scale(2, 3)
        >>> t.transformPoint((100, 100))
        (200, 300)
        >>> t.transformPoint((0, 0))
        (0, 0)
        >>> t = Offset(2, 3)
        >>> t.transformPoint((100, 100))
        (102, 103)
        >>> t.transformPoint((0, 0))
        (2, 3)
        >>> t2 = t.scale(0.5)
        >>> t2.transformPoint((100, 100))
        (52.0, 53.0)
        >>> import math
        >>> t3 = t2.rotate(math.pi / 2)
        >>> t3.transformPoint((0, 0))
        (2.0, 3.0)
        >>> t3.transformPoint((100, 100))
        (-48.0, 53.0)
        >>> t = Identity.scale(0.5).translate(100, 200).skew(0.1, 0.2)
        >>> t.transformPoints([(0, 0), (1, 1), (100, 100)])
        [(50.0, 100.0), (50.550167336042726, 100.60135501775433), (105.01673360427253, 160.13550177543362)]
        >>>
)annotationsN)
NamedTuple)	dataclass	TransformDecomposedTransformgV瞯<c                    V ^8  d   QhRRRR/# )   vfloatreturn )formats   "x/Users/tonyclaw/.openclaw/workspace/skills/math-calculator/venv/lib/python3.14/site-packages/fontTools/misc/transform.py__annotate__r   F   s      5 U     c                n    \        V 4      \        8  d   ^ p V # V \        8  d   ^p V # V \        8  d   Rp V # )    )abs_EPSILON_ONE_EPSILON_MINUS_ONE_EPSILON)r	   s   &r   _normSinCosr   F   sE    
1v
 H	 
\	 H 
	Hr   c                     ] tR t^Pt$ Rt^tR]R&   ^ tR]R&   ^ tR]R&   ^t	R]R&   ^ t
R]R&   ^ tR]R&   R	 tR
 tR tR tR"R R lltR#R R lltR R ltR"R R lltR tR tR tR R ltR R ltR R ltR R  ltR!tR# )$r   a  2x2 transformation matrix plus offset, a.k.a. Affine transform.
Transform instances are immutable: all transforming methods, eg.
rotate(), return a new Transform instance.

:Example:

        >>> t = Transform()
        >>> t
        <Transform [1 0 0 1 0 0]>
        >>> t.scale(2)
        <Transform [2 0 0 2 0 0]>
        >>> t.scale(2.5, 5.5)
        <Transform [2.5 0 0 5.5 0 0]>
        >>>
        >>> t.scale(2, 3).transformPoint((100, 100))
        (200, 300)

Transform's constructor takes six arguments, all of which are
optional, and can be used as keyword arguments::

        >>> Transform(12)
        <Transform [12 0 0 1 0 0]>
        >>> Transform(dx=12)
        <Transform [1 0 0 1 12 0]>
        >>> Transform(yx=12)
        <Transform [1 0 12 1 0 0]>

Transform instances also behave like sequences of length 6::

        >>> len(Identity)
        6
        >>> list(Identity)
        [1, 0, 0, 1, 0, 0]
        >>> tuple(Identity)
        (1, 0, 0, 1, 0, 0)

Transform instances are comparable::

        >>> t1 = Identity.scale(2, 3).translate(4, 6)
        >>> t2 = Identity.translate(8, 18).scale(2, 3)
        >>> t1 == t2
        1

But beware of floating point rounding errors::

        >>> t1 = Identity.scale(0.2, 0.3).translate(0.4, 0.6)
        >>> t2 = Identity.translate(0.08, 0.18).scale(0.2, 0.3)
        >>> t1
        <Transform [0.2 0 0 0.3 0.08 0.18]>
        >>> t2
        <Transform [0.2 0 0 0.3 0.08 0.18]>
        >>> t1 == t2
        0

Transform instances are hashable, meaning you can use them as
keys in dictionaries::

        >>> d = {Scale(12, 13): None}
        >>> d
        {<Transform [12 0 0 13 0 0]>: None}

But again, beware of floating point rounding errors::

        >>> t1 = Identity.scale(0.2, 0.3).translate(0.4, 0.6)
        >>> t2 = Identity.translate(0.08, 0.18).scale(0.2, 0.3)
        >>> t1
        <Transform [0.2 0 0 0.3 0.08 0.18]>
        >>> t2
        <Transform [0.2 0 0 0.3 0.08 0.18]>
        >>> d = {t1: None}
        >>> d
        {<Transform [0.2 0 0 0.3 0.08 0.18]>: None}
        >>> d[t2]
        Traceback (most recent call last):
          File "<stdin>", line 1, in ?
        KeyError: <Transform [0.2 0 0 0.3 0.08 0.18]>
r
   xxxyyxyydxdyc                    Vw  r#V w  rErgrWB,          Wc,          ,           V,           WR,          Ws,          ,           V	,           3# )zTransform a point.

:Example:

        >>> t = Transform()
        >>> t = t.scale(2.5, 5.5)
        >>> t.transformPoint((100, 100))
        (250.0, 550.0)
r   )
selfpxyr   r   r   r   r   r   s
   &&        r   transformPointTransform.transformPoint   s<     !%"$bfrvo&:;;r   c                    V w  r#rErgV UU	u. uF=  w  rW(,          WI,          ,           V,           W8,          WY,          ,           V,           3NK?  	  up	p# u up	pi )zTransform a list of points.

:Example:

        >>> t = Scale(2, 3)
        >>> t.transformPoints([(0, 0), (0, 100), (100, 100), (100, 0)])
        [(0, 0), (0, 300), (200, 300), (200, 0)]
        >>>
r   )
r!   pointsr   r   r   r   r   r   r#   r$   s
   &&        r   transformPointsTransform.transformPoints   sI     "&IOP"&2%rv';<PPPs   AAc                v    Vw  r#V R,          w  rErgWB,          Wc,          ,           WR,          Ws,          ,           3# )zTransform an (dx, dy) vector, treating translation as zero.

:Example:

        >>> t = Transform(2, 0, 0, 2, 10, 20)
        >>> t.transformVector((3, -4))
        (6, -8)
        >>>
N   Nr   )r!   r	   r   r   r   r   r   r   s   &&      r   transformVectorTransform.transformVector   s5     b"'!27RW#455r   c                    V R,          w  r#rEV UUu. uF/  w  rgW&,          WG,          ,           W6,          WW,          ,           3NK1  	  upp# u uppi )zTransform a list of (dx, dy) vector, treating translation as zero.

:Example:
        >>> t = Transform(2, 0, 0, 2, 10, 20)
        >>> t.transformVectors([(3, -4), (5, -6)])
        [(6, -8), (10, -12)]
        >>>
r,   r   )r!   vectorsr   r   r   r   r   r   s   &&      r   transformVectorsTransform.transformVectors   sB     bELMW6227"BGbg$56WMMMs   5Ac                    V ^8  d   QhRRRR/# r   r#   r
   r$   r   )r   s   "r   r   Transform.__annotate__   s     	2 	25 	2 	2r   c                .    V P                  ^^ ^ ^W34      # )zReturn a new transformation, translated (offset) by x, y.

:Example:
        >>> t = Transform()
        >>> t.translate(20, 30)
        <Transform [1 0 0 1 20 30]>
        >>>
	transformr!   r#   r$   s   &&&r   	translateTransform.translate   s     ~~q!Q1011r   Nc                    V ^8  d   QhRRRR/# )r   r#   r
   r$   float | Noner   )r   s   "r   r   r6      s     2 2u 2\ 2r   c                <    Vf   TpV P                  V^ ^ V^ ^ 34      # )a#  Return a new transformation, scaled by x, y. The 'y' argument
may be None, which implies to use the x value for y as well.

:Example:
        >>> t = Transform()
        >>> t.scale(5)
        <Transform [5 0 0 5 0 0]>
        >>> t.scale(5, 6)
        <Transform [5 0 0 6 0 0]>
        >>>
r8   r:   s   &&&r   scaleTransform.scale   s*     9A~~q!Q1a011r   c                   V ^8  d   QhRR/# )r   angler
   r   )r   s   "r   r   r6      s     3 3E 3r   c                    \        \        P                  ! V4      4      p\        \        P                  ! V4      4      pV P	                  W#V) V^ ^ 34      # )zReturn a new transformation, rotated by 'angle' (radians).

:Example:
        >>> import math
        >>> t = Transform()
        >>> t.rotate(math.pi / 2)
        <Transform [0 1 -1 0 0 0]>
        >>>
)r   mathcossinr9   )r!   rC   css   &&  r   rotateTransform.rotate   sD     ((~~qaRAq122r   c                    V ^8  d   QhRRRR/# r5   r   )r   s   "r   r   r6     s     
F 
Fe 
FE 
Fr   c                    V P                  ^\        P                  ! V4      \        P                  ! V4      ^^ ^ 34      # )zReturn a new transformation, skewed by x and y.

:Example:
        >>> import math
        >>> t = Transform()
        >>> t.skew(math.pi / 4)
        <Transform [1 0 1 1 0 0]>
        >>>
)r9   rE   tanr:   s   &&&r   skewTransform.skew  s0     ~~q$((1+txx{Aq!DEEr   c           
     F   Vw  r#rErgV w  rrrV P                  W(,          W:,          ,           W),          W;,          ,           WH,          WZ,          ,           WI,          W[,          ,           W,          W,          ,           V,           W,          W,          ,           V,           4      # )zReturn a new transformation, transformed by another
transformation.

:Example:
        >>> t = Transform(2, 0, 0, 3, 1, 6)
        >>> t.transform((4, 3, 2, 1, 5, 6))
        <Transform [8 9 4 3 11 24]>
        >>>
	__class__r!   otherxx1xy1yx1yy1dx1dy1xx2xy2yx2yy2dx2dy2s   &&            r   r9   Transform.transform  s     (-$#C'+$#C~~I	!I	!I	!I	!I	!C'I	!C'
 	
r   c           
     F   V w  r#rErgVw  rrrV P                  W(,          W:,          ,           W),          W;,          ,           WH,          WZ,          ,           WI,          W[,          ,           W,          W,          ,           V,           W,          W,          ,           V,           4      # )a  Return a new transformation, which is the other transformation
transformed by self. self.reverseTransform(other) is equivalent to
other.transform(self).

:Example:
        >>> t = Transform(2, 0, 0, 3, 1, 6)
        >>> t.reverseTransform((4, 3, 2, 1, 5, 6))
        <Transform [8 6 6 3 21 15]>
        >>> Transform(4, 3, 2, 1, 5, 6).transform((2, 0, 0, 3, 1, 6))
        <Transform [8 6 6 3 21 15]>
        >>>
rR   rT   s   &&            r   reverseTransformTransform.reverseTransform%  s     (,$#C',$#C~~I	!I	!I	!I	!I	!C'I	!C'
 	
r   c                   V \         8X  d   V # V w  rr4rVW,          W2,          ,
          pWG,          V) V,          V) V,          W,          3w  rr4V) V,          W6,          ,
          V) V,          WF,          ,
          reV P                  WW4WV4      # )a  Return the inverse transformation.

:Example:
        >>> t = Identity.translate(2, 3).scale(4, 5)
        >>> t.transformPoint((10, 20))
        (42, 103)
        >>> it = t.inverse()
        >>> it.transformPoint((42, 103))
        (10.0, 20.0)
        >>>
)IdentityrS   )r!   r   r   r   r   r   r   dets   &       r   inverseTransform.inverse=  s     8K!%gB39rcCiArBG#bS2X%7B~~bbb55r   c                   V ^8  d   QhRR/# r   r   strr   )r   s   "r   r   r6   Q  s     
, 
,c 
,r   c                    RV ,          # )zReturn a PostScript representation

:Example:

        >>> t = Identity.scale(2, 3).translate(4, 5)
        >>> t.toPS()
        '[2 0 0 3 8 15]'
        >>>
z[%s %s %s %s %s %s]r   r!   s   &r   toPSTransform.toPSQ  s     %t++r   c                   V ^8  d   QhRR/# )r   r   z'DecomposedTransform'r   )r   s   "r   r   r6   ]  s     7 73 7r   c                ,    \         P                  V 4      # )z%Decompose into a DecomposedTransform.)r   fromTransformro   s   &r   toDecomposedTransform.toDecomposed]  s    "0066r   c                   V ^8  d   QhRR/# )r   r   boolr   )r   s   "r   r   r6   a  s        $  r   c                    V \         8g  # )ak  Returns True if transform is not identity, False otherwise.

:Example:

        >>> bool(Identity)
        False
        >>> bool(Transform())
        False
        >>> bool(Scale(1.))
        False
        >>> bool(Scale(2))
        True
        >>> bool(Offset())
        False
        >>> bool(Offset(0))
        False
        >>> bool(Offset(2))
        True
)rg   ro   s   &r   __bool__Transform.__bool__a  s    ( xr   c                   V ^8  d   QhRR/# rl   r   )r   s   "r   r   r6   w  s     P P# Pr   c                	L    R V P                   P                  3V ,           ,          # )z<%s [%g %g %g %g %g %g]>)rS   __name__ro   s   &r   __repr__Transform.__repr__w  s    )dnn.E.E-G$-NOOr   r   r   r   )   N)r~   
__module____qualname____firstlineno____doc__r   __annotations__r   r   r   r   r   r%   r)   r.   r2   r;   r@   rJ   rO   r9   rd   ri   rp   ru   rz   r   __static_attributes__r   r   r   r   r   P   s    L\ BMBMBMBMBMBM<Q6
N	22 3
F
*
06(
,7 ,P Pr   c               $    V ^8  d   QhRRRRRR/# )r   r#   r
   r$   r   r   r   )r   s   "r   r   r   ~  s!     ' 'e 'E ') 'r   c                     \        ^^ ^ ^W4      # )zReturn the identity transformation offset by x, y.

:Example:
        >>> Offset(2, 3)
        <Transform [1 0 0 1 2 3]>
        >>>
r   r#   r$   s   &&r   Offsetr   ~  s     Q1a&&r   c               $    V ^8  d   QhRRRRRR/# )r   r#   r
   r$   r>   r   r   r   )r   s   "r   r   r     s!     ' 'U '| 'y 'r   c                .    Vf   T p\        V ^ ^ V^ ^ 4      # )zReturn the identity transformation scaled by x, y. The 'y' argument
may be None, which implies to use the x value for y as well.

:Example:
        >>> Scale(2, 3)
        <Transform [2 0 0 3 0 0]>
        >>>
r   r   s   &&r   Scaler     s#     	yQ1aA&&r   c                      ] tR tRt$ Rt^ tR]R&   ^ tR]R&   ^ tR]R&   ^t	R]R&   ^t
R]R&   ^ tR]R	&   ^ tR]R
&   ^ tR]R&   ^ tR]R&   R t]R 4       tR R ltRtR# )r   i  zThe DecomposedTransform class implements a transformation with separate
translate, rotation, scale, skew, and transformation-center components.
r
   
translateX
translateYrotationscaleXscaleYskewXskewYtCenterXtCenterYc                	   V P                   ^ 8g  ;'       g    V P                  ^ 8g  ;'       g    V P                  ^ 8g  ;'       g    V P                  ^8g  ;'       gl    V P                  ^8g  ;'       gU    V P
                  ^ 8g  ;'       g>    V P                  ^ 8g  ;'       g'    V P                  ^ 8g  ;'       g    V P                  ^ 8g  # )r   )	r   r   r   r   r   r   r   r   r   ro   s   &r   rz   DecomposedTransform.__bool__  s    OOq  " "!#" "}}!" " {{a" " {{a	" "
 zzQ" " zzQ" " }}!" " }}!
	
r   c                   Vw  r#rErg\         P                  ! ^V4      pV^ 8  d   W(,          pW8,          pW%,          W4,          ,
          p	^ p
^ ;r^ pV^ 8w  g   V^ 8w  d   \         P                  ! W",          W3,          ,           4      pV^ 8  d   \         P                  ! W.,          4      M\         P                  ! W.,          4      ) p
YV,          r\         P                  ! W$,          W5,          ,           W,          ,          4      pMV^ 8w  g   V^ 8w  d   \         P                  ! WD,          WU,          ,           4      p\         P
                  ^,          V^ 8  d   \         P                  ! V) V,          4      M\         P                  ! WO,          4      ) ,
          p
W,          TrM \        VV\         P                  ! V
4      W,          V\         P                  ! V4      V,          R^ ^ 4	      # )a-  Return a DecomposedTransform() equivalent of this transformation.
The returned solution always has skewY = 0, and angle in the (-180, 180].

:Example:
        >>> DecomposedTransform.fromTransform(Transform(3, 0, 0, 2, 0, 0))
        DecomposedTransform(translateX=0, translateY=0, rotation=0.0, scaleX=3.0, scaleY=2.0, skewX=0.0, skewY=0.0, tCenterX=0, tCenterY=0)
        >>> DecomposedTransform.fromTransform(Transform(0, 0, 0, 1, 0, 0))
        DecomposedTransform(translateX=0, translateY=0, rotation=0.0, scaleX=0.0, scaleY=1.0, skewX=0.0, skewY=0.0, tCenterX=0, tCenterY=0)
        >>> DecomposedTransform.fromTransform(Transform(0, 0, 1, 1, 0, 0))
        DecomposedTransform(translateX=0, translateY=0, rotation=-45.0, scaleX=0.0, scaleY=1.4142135623730951, skewX=0.0, skewY=0.0, tCenterX=0, tCenterY=0)
g        )rE   copysignsqrtacosatanpir   degrees)r!   r9   abrH   dr#   r$   sxdeltar   r   r   r   rrI   s   &&              r   rt   !DecomposedTransform.fromTransform  ss     %aA]]1a 6GAGA 6Q!V		!%!%-(A+,6tyy'		!%8H7HHFIIququ}78E!VqAv		!%!%-(Aww{%&!V		1"q&!$))AE2B1BH $iF "LL"KLL"$

 
	
r   c                   V ^8  d   QhRR/# )r   r   r   r   )r   s   "r   r    DecomposedTransform.__annotate__  s      Y r   c                @   \        4       pVP                  V P                  V P                  ,           V P                  V P
                  ,           4      pVP                  \        P                  ! V P                  4      4      pVP                  V P                  V P                  4      pVP                  \        P                  ! V P                  4      \        P                  ! V P                  4      4      pVP                  V P                  ) V P
                  ) 4      pV# )zReturn the Transform() equivalent of this transformation.

:Example:
        >>> DecomposedTransform(scaleX=2, scaleY=2).toTransform()
        <Transform [2 0 0 2 0 0]>
        >>>
)r   r;   r   r   r   r   rJ   rE   radiansr   r@   r   r   rO   r   r   )r!   ts   & r   toTransformDecomposedTransform.toTransform  s     KKKOOdmm+T__t}}-L
 HHT\\$--01GGDKK-FF4<<

+T\\$**-EFKK7r   r   N)r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rz   classmethodrt   r   r   r   r   r   r   r     s     JJHeFEFEE5E5HeHe
 6
 6
p r   __main__)r   rg   r   r   r   r   r   )N)r   
__future__r   rE   typingr   dataclassesr   __all__r   r   r   r   r   rg   r   r   r   r~   sysdoctestexittestmodfailedr   r   r   <module>r      s   4l #   ! N 8|(] hP
 hPV	 ;'' e e eP zHHW__%%&	 r   