
    ]Mh2                     \    d Z d	dZd Zd
dZd Zedk    rddlZ ej                     dS dS )z
Functions for converting UFO1 or UFO2 files into UFO3 format.

Currently provides functionality for converting kerning rules
and kerning groups. Conversion is only supported _from_ UFO1
or UFO2, and _to_ UFO3.
 c                 r   t          |          \  }}t          |                                           D ]\  }}||v r.||vr*|                    d          s|                    |           t          |                                          D ]4}||v r.||vr*|                    d          s|                    |           5i }|D ]u}t          |                                          t          |                                          z   }	|                    dd          }
d|
z   }
t          |
|	          }
|
||<   vi }|D ]u}t          |                                          t          |                                          z   }	|                    dd          }
d|
z   }
t          |
|	          }
|
||<   vi }t          |                                           D ]d\  }}|                    ||          }i }t          |                                          D ] \  }}|                    ||          }|||<   !|||<   et          |                                          }|t          |                                          z  }|D ]\  }}
t          ||                   }|||
<    ||t          ||          fS )a  Convert kerning data in UFO1 or UFO2 syntax into UFO3 syntax.

    Args:
      kerning:
          A dictionary containing the kerning rules defined in
          the UFO font, as used in :class:`.UFOReader` objects.
      groups:
          A dictionary containing the groups defined in the UFO
          font, as used in :class:`.UFOReader` objects.
      glyphSet:
        Optional; a set of glyph objects to skip (default: None).

    Returns:
      1. A dictionary representing the converted kerning data.
      2. A copy of the groups dictionary, with all groups renamed to UFO3 syntax.
      3. A dictionary containing the mapping of old group names to new group names.

    zpublic.kern1.zpublic.kern2.@MMK_L_ @MMK_R_)side1side2)
findKnownKerningGroupslistitems
startswithaddkeysreplacemakeUniqueGroupNamegetdict)kerninggroupsglyphSetfirstReferencedGroupssecondReferencedGroupsfirstsecondssecondfirstRenamedGroupsexistingGroupNamesnewNamesecondRenamedGroups
newKerning
newSecondsvalueallRenamedGroupsoldNamegroups                     [/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/fontTools/ufoLib/converters.py%convertUFO1OrUFO2KerningToUFO3Kerningr&      s   ( 5K64R4R11w}}// 7 7wF??uH44##O44 1%))%0007<<>>** 	7 	7FF($:$:((99 7*..v666	7
 & 
, 
,!&++--0048J8O8O8Q8Q3R3RR--	2..!G+%g/ABB$+5!!( 
. 
.!&++--0048K8P8P8R8R3S3SS..B//!G+%g/ABB&-F##Jw}}// ' 'w"&&ue44
!'--//22 	' 	'MFE(,,VV<<F!&Jv&
5 .44667706688999,    VG_%%wvt*<DWXXXXX    c                 Z   dg}dg}t                      }t                      }t          |                                           D ]d}|D ].}|                    |          r|                    |            n/|D ].}|                    |          r|                    |            n/e||fS )a  Find all kerning groups in a UFO1 or UFO2 font that use known prefixes.

    In some cases, not all kerning groups will be referenced
    by the kerning pairs in a UFO. The algorithm for locating
    groups in :func:`convertUFO1OrUFO2KerningToUFO3Kerning` will
    miss these unreferenced groups. By scanning for known prefixes,
    this function will catch all of the prefixed groups.

    The prefixes and sides by this function are:

    @MMK_L_ - side 1
    @MMK_R_ - side 2

    as defined in the UFO1 specification.

    Args:
        groups:
          A dictionary containing the groups defined in the UFO
          font, as read by :class:`.UFOReader`.

    Returns:
        Two sets; the first containing the names of all
        first-side kerning groups identified in the ``groups``
        dictionary, and the second containing the names of all
        second-side kerning groups identified.

        "First-side" and "second-side" are with respect to the
        writing direction of the script.

        Example::

          >>> testGroups = {
          ...     "@MMK_L_1" : None,
          ...     "@MMK_L_2" : None,
          ...     "@MMK_L_3" : None,
          ...     "@MMK_R_1" : None,
          ...     "@MMK_R_2" : None,
          ...     "@MMK_R_3" : None,
          ...     "@MMK_l_1" : None,
          ...     "@MMK_r_1" : None,
          ...     "@MMK_X_1" : None,
          ...     "foo" : None,
          ... }
          >>> first, second = findKnownKerningGroups(testGroups)
          >>> sorted(first) == ['@MMK_L_1', '@MMK_L_2', '@MMK_L_3']
          True
          >>> sorted(second) == ['@MMK_R_1', '@MMK_R_2', '@MMK_R_3']
          True
    r   r   )setr
   r   r   r   )r   knownFirstGroupPrefixesknownSecondGroupPrefixesfirstGroupssecondGroups	groupNamefirstPrefixsecondPrefixs           r%   r	   r	   W   s    d  )k ){%%K55L&++--((  	2 	 	K##K00 	*** 5 	 	L##L11   +++ $$r'       c                 T    | }|dk    rd||fz  }||v rt          | ||dz             S |S )aT  Make a kerning group name that will be unique within the set of group names.

    If the requested kerning group name already exists within the set, this
    will return a new name by adding an incremented counter to the end
    of the requested name.

    Args:
        name:
          The requested kerning group name.
        groupNames:
          A list of the existing kerning group names.
        counter:
          Optional; a counter of group names already seen (default: 0). If
          :attr:`.counter` is not provided, the function will recurse,
          incrementing the value of :attr:`.counter` until it finds the
          first unused ``name+counter`` combination, and return that result.

    Returns:
        A unique kerning group name composed of the requested name suffixed
        by the smallest available integer counter.
    r1   z%s%d   )r   )name
groupNamescounterr   s       r%   r   r      sG    . G{{GW--*"4Wq[AAANr'   c                      dS )aJ  
    Tests for :func:`.convertUFO1OrUFO2KerningToUFO3Kerning`.

    No known prefixes.

    >>> testKerning = {
    ...     "A" : {
    ...         "A" : 1,
    ...         "B" : 2,
    ...         "CGroup" : 3,
    ...         "DGroup" : 4
    ...     },
    ...     "BGroup" : {
    ...         "A" : 5,
    ...         "B" : 6,
    ...         "CGroup" : 7,
    ...         "DGroup" : 8
    ...     },
    ...     "CGroup" : {
    ...         "A" : 9,
    ...         "B" : 10,
    ...         "CGroup" : 11,
    ...         "DGroup" : 12
    ...     },
    ... }
    >>> testGroups = {
    ...     "BGroup" : ["B"],
    ...     "CGroup" : ["C"],
    ...     "DGroup" : ["D"],
    ... }
    >>> kerning, groups, maps = convertUFO1OrUFO2KerningToUFO3Kerning(
    ...     testKerning, testGroups, [])
    >>> expected = {
    ...     "A" : {
    ...         "A": 1,
    ...         "B": 2,
    ...         "public.kern2.CGroup": 3,
    ...         "public.kern2.DGroup": 4
    ...     },
    ...     "public.kern1.BGroup": {
    ...         "A": 5,
    ...         "B": 6,
    ...         "public.kern2.CGroup": 7,
    ...         "public.kern2.DGroup": 8
    ...     },
    ...     "public.kern1.CGroup": {
    ...         "A": 9,
    ...         "B": 10,
    ...         "public.kern2.CGroup": 11,
    ...         "public.kern2.DGroup": 12
    ...     }
    ... }
    >>> kerning == expected
    True
    >>> expected = {
    ...     "BGroup": ["B"],
    ...     "CGroup": ["C"],
    ...     "DGroup": ["D"],
    ...     "public.kern1.BGroup": ["B"],
    ...     "public.kern1.CGroup": ["C"],
    ...     "public.kern2.CGroup": ["C"],
    ...     "public.kern2.DGroup": ["D"],
    ... }
    >>> groups == expected
    True

    Known prefixes.

    >>> testKerning = {
    ...     "A" : {
    ...         "A" : 1,
    ...         "B" : 2,
    ...         "@MMK_R_CGroup" : 3,
    ...         "@MMK_R_DGroup" : 4
    ...     },
    ...     "@MMK_L_BGroup" : {
    ...         "A" : 5,
    ...         "B" : 6,
    ...         "@MMK_R_CGroup" : 7,
    ...         "@MMK_R_DGroup" : 8
    ...     },
    ...     "@MMK_L_CGroup" : {
    ...         "A" : 9,
    ...         "B" : 10,
    ...         "@MMK_R_CGroup" : 11,
    ...         "@MMK_R_DGroup" : 12
    ...     },
    ... }
    >>> testGroups = {
    ...     "@MMK_L_BGroup" : ["B"],
    ...     "@MMK_L_CGroup" : ["C"],
    ...     "@MMK_L_XGroup" : ["X"],
    ...     "@MMK_R_CGroup" : ["C"],
    ...     "@MMK_R_DGroup" : ["D"],
    ...     "@MMK_R_XGroup" : ["X"],
    ... }
    >>> kerning, groups, maps = convertUFO1OrUFO2KerningToUFO3Kerning(
    ...     testKerning, testGroups, [])
    >>> expected = {
    ...     "A" : {
    ...         "A": 1,
    ...         "B": 2,
    ...         "public.kern2.CGroup": 3,
    ...         "public.kern2.DGroup": 4
    ...     },
    ...     "public.kern1.BGroup": {
    ...         "A": 5,
    ...         "B": 6,
    ...         "public.kern2.CGroup": 7,
    ...         "public.kern2.DGroup": 8
    ...     },
    ...     "public.kern1.CGroup": {
    ...         "A": 9,
    ...         "B": 10,
    ...         "public.kern2.CGroup": 11,
    ...         "public.kern2.DGroup": 12
    ...     }
    ... }
    >>> kerning == expected
    True
    >>> expected = {
    ...     "@MMK_L_BGroup": ["B"],
    ...     "@MMK_L_CGroup": ["C"],
    ...     "@MMK_L_XGroup": ["X"],
    ...     "@MMK_R_CGroup": ["C"],
    ...     "@MMK_R_DGroup": ["D"],
    ...     "@MMK_R_XGroup": ["X"],
    ...     "public.kern1.BGroup": ["B"],
    ...     "public.kern1.CGroup": ["C"],
    ...     "public.kern1.XGroup": ["X"],
    ...     "public.kern2.CGroup": ["C"],
    ...     "public.kern2.DGroup": ["D"],
    ...     "public.kern2.XGroup": ["X"],
    ... }
    >>> groups == expected
    True

    >>> from .validators import kerningValidator
    >>> kerningValidator(kerning)
    (True, None)

    Mixture of known prefixes and groups without prefixes.

    >>> testKerning = {
    ...     "A" : {
    ...         "A" : 1,
    ...         "B" : 2,
    ...         "@MMK_R_CGroup" : 3,
    ...         "DGroup" : 4
    ...     },
    ...     "BGroup" : {
    ...         "A" : 5,
    ...         "B" : 6,
    ...         "@MMK_R_CGroup" : 7,
    ...         "DGroup" : 8
    ...     },
    ...     "@MMK_L_CGroup" : {
    ...         "A" : 9,
    ...         "B" : 10,
    ...         "@MMK_R_CGroup" : 11,
    ...         "DGroup" : 12
    ...     },
    ... }
    >>> testGroups = {
    ...     "BGroup" : ["B"],
    ...     "@MMK_L_CGroup" : ["C"],
    ...     "@MMK_R_CGroup" : ["C"],
    ...     "DGroup" : ["D"],
    ... }
    >>> kerning, groups, maps = convertUFO1OrUFO2KerningToUFO3Kerning(
    ...     testKerning, testGroups, [])
    >>> expected = {
    ...     "A" : {
    ...         "A": 1,
    ...         "B": 2,
    ...         "public.kern2.CGroup": 3,
    ...         "public.kern2.DGroup": 4
    ...     },
    ...     "public.kern1.BGroup": {
    ...         "A": 5,
    ...         "B": 6,
    ...         "public.kern2.CGroup": 7,
    ...         "public.kern2.DGroup": 8
    ...     },
    ...     "public.kern1.CGroup": {
    ...         "A": 9,
    ...         "B": 10,
    ...         "public.kern2.CGroup": 11,
    ...         "public.kern2.DGroup": 12
    ...     }
    ... }
    >>> kerning == expected
    True
    >>> expected = {
    ...     "BGroup": ["B"],
    ...     "@MMK_L_CGroup": ["C"],
    ...     "@MMK_R_CGroup": ["C"],
    ...     "DGroup": ["D"],
    ...     "public.kern1.BGroup": ["B"],
    ...     "public.kern1.CGroup": ["C"],
    ...     "public.kern2.CGroup": ["C"],
    ...     "public.kern2.DGroup": ["D"],
    ... }
    >>> groups == expected
    True
    Nr   r   r'   r%   testr8      s      r'   __main__N)r   )r1   )__doc__r&   r	   r   r8   __name__doctesttestmodr   r'   r%   <module>r>      s    HY HY HY HYV?% ?% ?%D   BN N Nb zNNNGO r'   