L i,8dZddlmZddlmZddlZddlZdZefdZ e e fdZ dZ d Zd Zd Zd Zd ZdZdZdZdZdZdZdZddZGddeZddZdZedk(r4ddlZddlZej@ejBjDyy)zTRoutines for calculating bounding boxes, point in rectangle calculations and so on. )otRound)VectorNc|sy|Dcgc]\}}| }}}|Dcgc]\}}| }}}t|t|t|t|fScc}}wcc}}w)zCalculate the bounding rectangle of a 2D points array. Args: array: A sequence of 2D tuples. Returns: A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``. rrrrminmax)arrayxyxsyss _/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/fontTools/misc/arrayTools.py calcBoundsr s_  1! B  1! B  r7CGSWc"g --  s A Ac>tfdt|DS)aCalculate the integer bounding rectangle of a 2D points array. Values are rounded to closest integer towards ``+Infinity`` using the :func:`fontTools.misc.fixedTools.otRound` function by default, unless an optional ``round`` function is passed. Args: array: A sequence of 2D tuples. round: A rounding function of type ``f(x: float) -> int``. Returns: A four-item tuple of integers representing the bounding rectangle: ``(xMin, yMin, xMax, yMax)``. c3.K|] }|yw)N).0vrounds r z calcIntBounds..*s5aq5s)tupler)r rs `r calcIntBoundsrs 5:e#45 55cn|\}}|||||fS|\}}}} ||||||||||| |fS)a_Add a point to a bounding rectangle. Args: bounds: A bounding rectangle expressed as a tuple ``(xMin, yMin, xMax, yMax), or None``. p: A 2D tuple representing a point. min,max: functions to compute the minimum and maximum. Returns: The updated bounding rectangle ``(xMin, yMin, xMax, yMax)``. r) boundsprr r r xMinyMinxMaxyMaxs r updateBoundsr"-sUFQ ~!Qz#D$d tQ<T1s4|Sq\ AArc^|\}}|\}}}}||cxkxr|kncxr||cxkxr|kScS)a'Test if a point is inside a bounding rectangle. Args: p: A 2D tuple representing a point. rect: A bounding rectangle expressed as a tuple ``(xMin, yMin, xMax, yMax)``. Returns: ``True`` if the point is inside the rectangle, ``False`` otherwise. r)rrectr r rrr r!s r pointInRectr%@s@FQ!D$d A   6DA$5$56$56rct|dkrgS|\}}}}|Dcgc]'\}}||cxkxr|kncxr||cxkxr|knc)c}}Scc}}w)aDetermine which points are inside a bounding rectangle. Args: array: A sequence of 2D tuples. rect: A bounding rectangle expressed as a tuple ``(xMin, yMin, xMax, yMax)``. Returns: A list containing the points inside the rectangle. )len)r r$rrr r!r r s r pointsInRectr)PsV 5zA~ !D$dDI JDAqTQ $  7TQ%6$%6 7 JJ Js,A cH|\}}tj|dz|dzzS)zCalculate the length of the given vector. Args: vector: A 2D tuple. Returns: The Euclidean length of the vector. )mathsqrt)vectorr r s r vectorLengthr/as( DAq 99QTAqD[ !!rc j|Dcgc]#}ttj|dz%c}Scc}w)zRound a list of floats to 16-bit signed integers. Args: array: List of float values. Returns: A list of rounded integers. g?)intr,floor)r is rasInt16r4ns*/4 4C 1s7# $ 44 4s(0cl|\}}}}t||t||t||t||fS)aPNormalize a bounding box rectangle. This function "turns the rectangle the right way up", so that the following holds:: xMin <= xMax and yMin <= yMax Args: rect: A bounding rectangle expressed as a tuple ``(xMin, yMin, xMax, yMax)``. Returns: A normalized bounding rectangle. rr$rrr r!s rnormRectr7zs9 $T4t tT?CdOSt_c$o MMrc4|\}}}}||z||z||z||zfS)a:Scale a bounding box rectangle. Args: rect: A bounding rectangle expressed as a tuple ``(xMin, yMin, xMax, yMax)``. x: Factor to scale the rectangle along the X axis. Y: Factor to scale the rectangle along the Y axis. Returns: A scaled bounding rectangle. r)r$r r rrr r!s r scaleRectr9s1 $T4t !8TAXtax 11rc4|\}}}}||z||z||z||zfS)a@Offset a bounding box rectangle. Args: rect: A bounding rectangle expressed as a tuple ``(xMin, yMin, xMax, yMax)``. dx: Amount to offset the rectangle along the X axis. dY: Amount to offset the rectangle along the Y axis. Returns: An offset bounding rectangle. rr$dxdyrrr r!s r offsetRectr>1 $T4t "9dRiD2I 55rc4|\}}}}||z||z||z ||z fS)aIInset a bounding box rectangle on all sides. Args: rect: A bounding rectangle expressed as a tuple ``(xMin, yMin, xMax, yMax)``. dx: Amount to inset the rectangle along the X axis. dY: Amount to inset the rectangle along the Y axis. Returns: An inset bounding rectangle. rr;s r insetRectrAr?rc|\}}}}|\}}}} t||t||t||t|| f\} } } } | | k\s| | k\ryd| | | | ffS)aTest for rectangle-rectangle intersection. Args: rect1: First bounding rectangle, expressed as tuples ``(xMin, yMin, xMax, yMax)``. rect2: Second bounding rectangle. Returns: A boolean and a rectangle. If the input rectangles intersect, returns ``True`` and the intersecting rectangle. Returns ``False`` and ``(0, 0, 0, 0)`` if the input rectangles don't intersect. )FrT)r rrect1rect2xMin1yMin1xMax1yMax1xMin2yMin2xMax2yMax2rrr r!s rsectRectrNs~$) UE5%#( UE5% E5 E5 E5 E5 D$d  t|tt|" $dD) ))rc|\}}}}|\}}}} t||t||t||t|| f\} } } } | | | | fS)a0Determine union of bounding rectangles. Args: rect1: First bounding rectangle, expressed as tuples ``(xMin, yMin, xMax, yMax)``. rect2: Second bounding rectangle. Returns: The smallest rectangle in which both input rectangles are fully enclosed. rrCs r unionRectrPsi$) UE5%#( UE5% E5 E5 E5 E5 D$d $d ##rc0|\}}}}||zdz ||zdz fS)zDetermine rectangle center. Args: rect: Bounding rectangle, expressed as tuples ``(xMin, yMin, xMax, yMax)``. Returns: A 2D tuple representing the point at the center of the rectangle. r+rr6s r rectCenterrRs/ $T4t 4K1 td{a/ //rc&|\}}}}||z ||z zS)zDetermine rectangle area. Args: rect: Bounding rectangle, expressed as tuples ``(xMin, yMin, xMax, yMax)``. Returns: The area of the rectangle. rr6s rrectArearTs% $T4t 4KD4K ((rc |\}}}}ttj|}ttj|}ttj|}ttj|}||||fS)aRound a rectangle to integer values. Guarantees that the resulting rectangle is NOT smaller than the original. Args: rect: Bounding rectangle, expressed as tuples ``(xMin, yMin, xMax, yMax)``. Returns: A rounded bounding rectangle. )r1r,r2ceilr6s rintRectrW sk $T4t tzz$ D tzz$ D tyy D tyy D $d ##rc d|dkrtd|t|\}}}}ttj||z |zttj||z |zttj ||z |zttj ||z |zfS)z >>> bounds = (72.3, -218.4, 1201.3, 919.1) >>> quantizeRect(bounds) (72, -219, 1202, 920) >>> quantizeRect(bounds, factor=10) (70, -220, 1210, 920) >>> quantizeRect(bounds, factor=100) (0, -300, 1300, 1000) r'z*Expected quantization factor >= 1, found: ) ValueErrorr7r1r,r2rV)r$factorrrr r!s r quantizeRectr[szEfZPQQ%d^D$d DJJtf} % ./ DJJtf} % ./ DIIdVm $v -. DIIdVm $v -.  rceZdZdZy)rc8tjdty)NzffontTools.misc.arrayTools.Vector has been deprecated, please use fontTools.misc.vector.Vector instead.)warningswarnDeprecationWarning)selfargskwargss r__init__zVector.__init__5s  4  rN)__name__ __module__ __qualname__rdrrrrr4s rrc#K|sy|r t|}n t|}t|d}|}|D] }||f|} ||fyw)aIterate over current and next items in iterable. Args: iterable: An iterable reverse: If true, iterate in reverse order. Returns: A iterable yielding two elements per iteration. Example: >>> tuple(pairwise([])) () >>> tuple(pairwise([], reverse=True)) () >>> tuple(pairwise([0])) ((0, 0),) >>> tuple(pairwise([0], reverse=True)) ((0, 0),) >>> tuple(pairwise([0, 1])) ((0, 1), (1, 0)) >>> tuple(pairwise([0, 1], reverse=True)) ((1, 0), (0, 1)) >>> tuple(pairwise([0, 1, 2])) ((0, 1), (1, 2), (2, 0)) >>> tuple(pairwise([0, 1, 2], reverse=True)) ((2, 1), (1, 0), (0, 2)) >>> tuple(pairwise(['a', 'b', 'c', 'd'])) (('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')) >>> tuple(pairwise(['a', 'b', 'c', 'd'], reverse=True)) (('d', 'c'), ('c', 'b'), ('b', 'a'), ('a', 'd')) N)reversediternext)iterablereverseitfirstabs rpairwiserr=s^B  h  (^ TNE A !f  e*sAAcy)a >>> import math >>> calcBounds([]) (0, 0, 0, 0) >>> calcBounds([(0, 40), (0, 100), (50, 50), (80, 10)]) (0, 10, 80, 100) >>> updateBounds((0, 0, 0, 0), (100, 100)) (0, 0, 100, 100) >>> pointInRect((50, 50), (0, 0, 100, 100)) True >>> pointInRect((0, 0), (0, 0, 100, 100)) True >>> pointInRect((100, 100), (0, 0, 100, 100)) True >>> not pointInRect((101, 100), (0, 0, 100, 100)) True >>> list(pointsInRect([(50, 50), (0, 0), (100, 100), (101, 100)], (0, 0, 100, 100))) [True, True, True, False] >>> vectorLength((3, 4)) 5.0 >>> vectorLength((1, 1)) == math.sqrt(2) True >>> list(asInt16([0, 0.1, 0.5, 0.9])) [0, 0, 1, 1] >>> normRect((0, 10, 100, 200)) (0, 10, 100, 200) >>> normRect((100, 200, 0, 10)) (0, 10, 100, 200) >>> scaleRect((10, 20, 50, 150), 1.5, 2) (15.0, 40, 75.0, 300) >>> offsetRect((10, 20, 30, 40), 5, 6) (15, 26, 35, 46) >>> insetRect((10, 20, 50, 60), 5, 10) (15, 30, 45, 50) >>> insetRect((10, 20, 50, 60), -5, -10) (5, 10, 55, 70) >>> intersects, rect = sectRect((0, 10, 20, 30), (0, 40, 20, 50)) >>> not intersects True >>> intersects, rect = sectRect((0, 10, 20, 30), (5, 20, 35, 50)) >>> intersects 1 >>> rect (5, 20, 20, 30) >>> unionRect((0, 10, 20, 30), (0, 40, 20, 50)) (0, 10, 20, 50) >>> rectCenter((0, 0, 100, 200)) (50.0, 100.0) >>> rectCenter((0, 0, 100, 199.0)) (50.0, 99.5) >>> intRect((0.9, 2.9, 3.1, 4.1)) (0, 2, 4, 5) Nrrrr_testrtlsr__main__)r')F)#__doc__fontTools.misc.roundToolsrfontTools.misc.vectorr_Vectorr,r^rrrr r"r%r)r/r4r7r9r>rArNrPrRrTrWr[rrrtresysdoctestexittestmodfailedrrrrs.3  . '6$!$B& 7 K" " 5N& 2 6 6 *6$. 0 )$(* W ,^5p z CHH_W__  % %& r