)EjJddlmZddlZddlZddlmZmZmZddlm Z ddl m Z GddeZ Gd d eeZ Gd d eeZdS) ) annotationsN)AnyStrGeneric NamedTuple) ImageFont)_Inkc8eZdZUded<ded<ded<ded<dS) _Linefloatxystranchor str | bytestextN)__name__ __module__ __qualname____annotations__?C:\PYTHON\MyICR_Suite\python\Lib\site-packages\PIL/ImageText.pyr r s9 HHH HHHKKKrr c<eZdZUgZded<dZdZ dddZddZdS)_Wrapz list[AnyStr]linesrNr Text[AnyStr]widthintheight int | NonefontImageFont.BaseImageFont | NonereturnNonec,||_||_||_||_|jj}t |t rdnd}|}t jt |t rdnd|D]w}t jt |t rdnd|} | r||snGt| D]V\} }| dkr||sn5|xj t|z c_ |t|d}W|}||z} |j | |jd|kr| }|r||snt|} | }| t|z |_|j ||jd|kr|d } t| n|}y|r||||j d|_dS) Nrz\s*\S+s\s*\S+z [^\S\n]*\ns [^\S\n]*\nrzWord does not fit within line)rrr r" isinstancerrefindalladd_line enumeratepositionlen _get_bboxlstripoffset ValueErrorremaining_text)selfrrr r" input_text emptystringlinewordnewlinesinew_lineoriginal_lengthmsgs r__init__z_Wrap.__init__s,#'    Y^ &z377@bbS J#J44 DII*j  & $& $Dz!+J!><9C$S//)DD $ d###&0&Arr8rboolcH|j|gz}|j\|j|dj}|j||jd}||z|jkrdS||_|xjt||j zz c_d|_ dS)N)rFrT) rr r_splitrr0r"r.r/r2)r5r8r last_line_ylast_line_heights rr,z_Wrap.add_linePs dV# ; ")***77;=K#y224CCAF -- ;;u  TT[00  trNN) rrrrr r!r"r#r$r%)r8rr$r@) rrrrrr.r2r?r,rrrrrslEH F "/3 7B7B7B7B7Br      rrceZdZ d1d2dZd3dZd4d5dZd6dZ d7d8d!Zd9d"Z d:d;d,Z d7dd0Z dS)?TextNRGBrrr"r#moderspacingr direction str | Nonefeatureslist[str] | Nonelanguager$r%c||_|ptj|_||_||_||_||_||_d|_ d|_ d|_ dS)a :param text: String to be drawn. :param font: Either an :py:class:`~PIL.ImageFont.ImageFont` instance, :py:class:`~PIL.ImageFont.FreeTypeFont` instance, :py:class:`~PIL.ImageFont.TransposedFont` instance or ``None``. If ``None``, the default font from :py:meth:`.ImageFont.load_default` will be used. :param mode: The image mode this will be used with. :param spacing: The number of pixels between lines. :param direction: Direction of the text. It can be ``"rtl"`` (right to left), ``"ltr"`` (left to right) or ``"ttb"`` (top to bottom). Requires libraqm. :param features: A list of OpenType font features to be used during text layout. This is usually used to turn on optional font features that are not enabled by default, for example ``"dlig"`` or ``"ss01"``, but can be also used to turn off default font features, for example ``"-liga"`` to disable ligatures or ``"-kern"`` to disable kerning. To get all supported features, see `OpenType docs`_. Requires libraqm. :param language: Language of the text. Different languages may use different glyph shapes or ligatures. This parameter tells the font which language the text is in, and to apply the correct substitutions as appropriate, if available. It should be a `BCP 47 language code`_. Requires libraqm. FrN) rr load_defaultr"rLrMrNrPrRembedded_color stroke_width stroke_fill)r5rr"rLrMrNrPrRs rr?z Text.__init___sbJ! 4I244   "    ##$(,rcH|jdvrd}t|d|_dS)z? Use embedded color glyphs (COLR, CBDT, SBIX). )rJRGBAz3Embedded color supported only in RGB and RGBA modesTN)rLr3rU)r5r>s r embed_colorzText.embed_colors0 9O + +GCS// !"rrrfill _Ink | Nonec"||_||_dS)a  :param width: The width of the text stroke. :param fill: Color to use for the text stroke when drawing. If not given, will default to the ``fill`` parameter from :py:meth:`.ImageDraw.ImageDraw.text`. N)rVrW)r5rr[s rstrokez Text.strokes"rc.|jdvrdS|jrdSdS)N)1PIFr`rYL)rLrU)r5s r _get_fontmodezText._get_fontmodes* 9, , ,3   63rrr r!scalingstr | tuple[str, int] | NoneText[AnyStr] | Nonec t|jtjrd}t ||jdvrd}t ||t |||}nt|jtjsd}t ||d}t |t|trd}n|\}}|j}t ||||}|dkr|j sdStj |j }|j r^|t|dkrd }t ||dz}|j| }t ||||}|j ^||_n|j rd }t |tj|j }|j sR||krd }t ||dz }|j| }|} t ||||}|j R|dz}||jj kr |j| |_| }|j r^t!|j |j|j|j|j|j|j } |j| _|j| _|j| _nd} t|jtrd nd } | |j|_| S)a Wrap text to fit within a given width. :param width: The width to fit within. :param height: An optional height limit. Any text that does not fit within this will be returned as a new :py:class:`.Text` object. :param scaling: An optional directive to scale the text, either "grow" as much as possible within the given dimensions, or "shrink" until it fits. It can also be a tuple of (direction, limit), with an integer limit to stop scaling at. :returns: An :py:class:`.Text` object, or None. zTransposedFont not supported)NltrzOnly ltr direction supportedNz$'scaling' only supports FreeTypeFontz'scaling' requires 'height'rshrinkzText could not be scaled)size)rr"rLrMrNrPrR  )r)r"rTransposedFontr3rNr FreeTypeFontrr4mathceilrlmax font_variantfloorrIrLrMrPrRrUrVrWrjoinr) r5rr rfr>wraplimitr"rl last_wraprnewlines rrwz Text.wraps& di!9 : : "0CS// ! > . .0CS// ! ?uf--DDdi)?@@ &< oo%~3 oo%'3'' )!(9Dufd33D(""* 4y++)<s5!}},,8(oo-AID911t1<)) $ 6 6D 6 A ADI    (YY .D#'"5D  $ 1D #/D  D$TY44?$$%LL,,  rc t|jtr d|jv}n d|jv}|rd}t||j|j||j|j|j S)a Returns length (in pixels with 1/64 precision) of text. This is the amount by which following text should be offset. Text bounding box may extend past the length in some fonts, e.g. when using italics or accents. The result is returned as a float; it is a whole number if using basic layout. Note that the sum of two lengths may not equal the length of a concatenated string due to kerning. If you need to adjust for kerning, include the following character and subtract its length. For example, instead of:: hello = ImageText.Text("Hello", font).get_length() world = ImageText.Text("World", font).get_length() helloworld = ImageText.Text("HelloWorld", font).get_length() assert hello + world == helloworld use:: hello = ( ImageText.Text("HelloW", font).get_length() - ImageText.Text("W", font).get_length() ) # adjusted for kerning world = ImageText.Text("World", font).get_length() helloworld = ImageText.Text("HelloWorld", font).get_length() assert hello + world == helloworld or disable kerning with (requires libraqm):: hello = ImageText.Text("Hello", font, features=["-kern"]).get_length() world = ImageText.Text("World", font, features=["-kern"]).get_length() helloworld = ImageText.Text( "HelloWorld", font, features=["-kern"] ).get_length() assert hello + world == helloworld :return: Either width for horizontal text, or height for vertical text. rmrnz&can't measure length of multiline text) r)rrr3r" getlengthrerNrPrR)r5 multiliner>s r get_lengthzText.get_length sT di % % + )II*I  ":CS// !y"" I    N M M    rrrleftxytuple[float, float]ralignrlist[str] | list[bytes] | None list[_Line]c |jdkrdnd}n$t|dkrd}t||Ntjt rjdnjd}t|dkr%t|d |d||d gS|dd vrjdkrd }t|j d dj j j d j zjz}|d}g}jdkr9|d } |D],} |t| ||| | |z } -njg} d } |D]T} j | jj j } | | t#| | } U|ddkr|t|dz |zdz z}n$|ddkr|t|dz |zz}d}|D]} |d } |dz }| | |z }|dvrn,|dkr | |dz z } n|dkr| |z } nd}t||dkr|d kr|t|dz krt| t r| dn| d}t|dkr|d dkr | | dz z} n|d dkr| | z} fd|D}d|dz}| t%|z }d }|D]M}|t| |||| |||t|dz z zz } |dz }N||z }m|d dkr | |dz z} n|d dkr| |z} |t| ||| ||z }|S)Nttbltlar(z#anchor must be a 2 character stringrmrnrrtbz'anchor not supported for multiline textArCmg@drB)rjustifycenterrightz4align must be "left", "center", "right" or "justify"r  rc jg|]/}j|jjj0Sr)r"r|rNrPrR).0r9fontmoder5s r zText._split..sR ' ' '!%!I// $ ( $ $ $  ' ' 'rl)rNr/r3r)rrsplitr rer"getbboxrPrRrVrMappendr|rssum)r5rrrrr> line_spacingtoppartsrr8widths max_width line_widthidxwidth_differencewords word_widths word_anchorr;r9rs` @rrDz Text._splitEs >!^u44TT$FF [[A  7CS// ! =di--, %%%Y__U++  u::??"Q%Aa99: : !9  5!8!8;CS// !%%'' I    !     l  e >U " "a5D % % U4fd;;<<< $ %F I 7 7!Y00(DNDM4=  j))) :66 ayCE Q,6<<c!!E Q,66C9 $9 $!uq#,vc{#: ///h&&,s22DDg%%,,DDPC$S//)Y&&(A--s5zzA~--,6dC+@+@V 3djjQUFVFV5zzA~~!!9++ IO3DD#AY#-- I-D ' ' ' ' '). ' ' ' '*F1Io +4s;7G7G+G($)##D!LLtS+t)L)LMMM KN5EUVW5X$XXDFAA|+ !9##,s22DDAY#%%,,D U4fd;;<<<|# rr!tuple[float, float, float, float]c |p|j|||j|j|j|j|S)N)r"rrerNrPrRrV)r5rr"rs rr0zText._get_bboxsM ! **     N M M      rc d}||||D]\}}}}|||}|d|z|d|z|d|z|d|zf}||}Mt|d|dt|d|dt|d|dt|d|df}|J|S)a Returns bounding box (in pixels) of text. Use :py:meth:`get_length` to get the offset of following text with 1/64 pixel precision. The bounding box includes extra margins for some fonts, e.g. italics or accents. :param xy: The anchor coordinates of the text. :param anchor: The text anchor alignment. Determines the relative location of the anchor to the text. The default alignment is top left, specifically ``la`` for horizontal text and ``lt`` for vertical text. See :ref:`text-anchors` for details. :param align: For multiline text, ``"left"``, ``"center"``, ``"right"`` or ``"justify"`` determines the relative alignment of lines. Use the ``anchor`` parameter to specify the alignment to ``xy``. :return: ``(left, top, right, bottom)`` bounding box N)rrrr(rC)rDr0minrs) r5rrrbboxr rr bbox_lines rget_bboxz Text.get_bboxs0:>"&++b&%"@"@   Aq&$tF;;I! q ! q ! q ! q I | Q1..Q1..Q1..Q1..  r)NrJrKNNN)rrr"r#rLrrMr rNrOrPrQrRrOr$r%)r$r%)rN)rr r[r\r$r%)r$rrG)rrr r!rfrgr$rh)r$r )rNrN) rrrrOrrrrr$r)rrr"r#rrOr$r)rNr)rrrrOrrr$r) rrrr?rZr^rerwr~rDr0rrrrrIrI^s104 $%)#1-1-1-1-1-f####     "04 ]]]]]~7 7 7 7 v#)!04 zzzzz~04!      $#)! ,,,,,,,rrI) __future__rrqr*typingrrrr'r_typingr r rrIrrrrs"""""" ..........JIIIIIGFOIIIX_____76?_____r