o
    nĎi~                  
   @  sv  U d Z ddlmZ ddlZddlmZmZ ddlmZ ddl	m
  mZ ddlmZmZmZmZ ddlmZ ddlmZ eeeeeeee d	f f ef f ZdddZdddZdddZdddZdddZ ddd Z!dd!d"Z"dd#d$Z#dd%d&Z$dd'd(Z%dd)d*Z&dd+d,Z'dd-d.Z(dd/d0Z)dd1d2Z*dd3d4Z+dd5d6Z,dd7d8Z-dd9d:Z.dd;d<Z/dd=d>Z0dd?d@Z1ddAdBZ2ddCdDZ3ddEdFZ4ddGdHZ5ddIdJZ6ddKdLZ7ddMdNZ8ddOdPZ9ddQdRZ:ddSdTZ;ddUdVZ<dddYdZZ=ee>e?fd[fe>e?fd[fe>e?fd[fed[fed[fed[fd\Z@deAd]< dd^d_ZBddd`daZCee>e?fd[fe>e?fd[fed[fed[fed[fdbZDdeAdc< ddddeZEddfdgZFddhdiZGdjZHdkeAdl< eedmfe>e?fd[fe>e?fd[fe>e?fd[fe>e?fd[fe>e?fd[fe>e?fd[fed[fdnZIdeAdo< dpdq ZJ			dddydzZKdd~dZLdddZMdddZNdZOdddZPdddZQeRdkrddlSZSeST  dS dS )z"Various low level data validators.    )annotationsN)MappingSequence)open)AnyTypeOptionalUnion)IntFloat)numberTypes.valuer   returnboolc                 C  s,   t | trdS dD ]
}t| |s dS q	dS )zY
    Some objects will likely come in that aren't
    dicts but are dict-ish enough.
    T)keysvaluesitemsF)
isinstancer   hasattr)r   attr r   W/home/jeff/fluffinator/venv/lib/python3.10/site-packages/fontTools/ufoLib/validators.pyisDictEnough   s   

r   typ	Type[Any]c                 C  s
   t | |S )(
    Generic. (Added at version 2.)
    )r   )r   r   r   r   r   genericTypeValidator#   s   
r   r   validValuesSequence[int]c                 C  sL   t | ttfs	dS t| }t|}|| rdS | D ]
}t |ts# dS qdS )r   FT)r   listtuplesetint)r   r   	valuesSetvalidValuesSetr   r   r   r   genericIntListValidator*   s   
r$   c                 C     t | tsdS | dk rdS dS (
    Generic. (Added at version 3.)
    Fr   Tr   r!   r   r   r   r   genericNonNegativeIntValidator:   
   
r*   c                 C  r%   r&   )r   r   r)   r   r   r   !genericNonNegativeNumberValidatorE   r+   r,   	prototypeGenericDictc                 C  s   t | tsdS | D ]\}\}}|sq|| vr dS q|  D ]	}||vr) dS q |  D ]\}}|| \}}|du r?|s?q.t ||sG dS q.dS )r'   FNT)r   r   r   r   )r   r-   keyr   requiredvprototypeTyper   r   r   genericDictValidatorP   s(   

r3   c                 C  s   g d}| |v S )
    Version 2+.
    )regularitalicboldzbold italicr   )r   optionsr   r   r   "fontInfoStyleMapStyleNameValidatorr   s   r9   c           	      C  s   t | tsdS t| dkrdS g d}ttdftdfd}g }| D ]*}t||s+ dS |d }|d }t|}|s< dS t||}|sF dS || q!|t	|krTdS dS )
    Version 3+.
    Fr   T)r            )rangeMaxPPEMrangeGaspBehaviorr>   r?   )
r   r   lendictr!   r3   r*   r$   appendsorted)	r   validBehaviorsdictPrototype	ppemOrderrangeRecordppembehaviorppemValiditybehaviorValidityr   r   r   )fontInfoOpenTypeGaspRangeRecordsValidatorz   s0   


rL   c                 C  s  t | tsdS t| dksdS | ddkrdS | d\}}|ddkr(dS |ddkr1dS |d\}}}t|dkrAdS t|dkrIdS t|dkrQdS zt|}t|}t|}W n
 tyi   Y dS w |dk sr|d	krtdS t||d }	|dk s||	krdS |d\}
}}t|
dkrdS t|dkrdS t|dkrdS zt|
}t|}t|}W n
 ty   Y dS w |d
k s|dkrdS |d
k s|dkrdS |d
k s|dkrdS dS )r4   F    r;   /r<   :      r      ;   T)	r   strr@   countsplitr!   
ValueErrorcalendar
monthrange)r   strDatestrTimestrYearstrMonthstrDayintYearintMonthintDaymonthMaxDaystrHour	strMinute	strSecondintHour	intMinute	intSecondr   r   r   $fontInfoOpenTypeHeadCreatedValidator   sf   
rj   c                 C  sR   t | tsdS ttdftdftdftdftdfd}| D ]
}t||s& dS qdS )r:   FT)nameID
platformID
encodingID
languageIDstring)r   r   rA   r!   rU   r3   )r   rE   
nameRecordr   r   r   $fontInfoOpenTypeNameRecordsValidator   s   

rq   c                 C  r%   )r4   Fr   Tr(   r)   r   r   r   'fontInfoOpenTypeOS2WeightClassValidator   r+   rr   c                 C  s*   t | tsdS | dk rdS | dkrdS dS )r4   Fr;   	   Tr(   r)   r   r   r   &fontInfoOpenTypeOS2WidthClassValidator   s   
rt   c                 C  s@   t | ttfs	dS t| dkrdS | D ]
}t |ts dS qdS )z
    Version 2.
    F
   Tr   r   r   r@   r!   r   r   r   r   r   *fontInfoVersion2OpenTypeOS2PanoseValidator   s   
rx   c                 C  sN   t | ttfs	dS t| dkrdS | D ]}t |ts dS |dk r$ dS qdS )r:   Fru   r   Trv   rw   r   r   r   *fontInfoVersion3OpenTypeOS2PanoseValidator  s   
ry   c                 C  sp   t | ttfs	dS t| dkrdS | D ]
}t |ts dS q| \}}|dk s*|dkr,dS |dk s4|dkr6dS dS )r4   Fr<   r         Trv   )r   r   classID
subclassIDr   r   r   'fontInfoOpenTypeOS2FamilyClassValidator  s   
r~   c                 C  P   t | ttfs	dS t| dkrdS t| d rdS | D ]
}t |ts% dS qdS )r4   Frz   r<   Tr   r   r   r@   r   rw   r   r   r    fontInfoPostscriptBluesValidator2     
r   c                 C  r   )r4   Fru   r<   Tr   rw   r   r   r   %fontInfoPostscriptOtherBluesValidatorB  r   r   c                 C  s@   t | ttfs	dS t| dkrdS | D ]
}t |ts dS qdS )r4   FrR   Tr   rw   r   r   r    fontInfoPostscriptStemsValidatorR  s   
r   c                 C  s   t tdd}| |vrdS dS )r4   r;      FT)r   range)r   r   r   r   r   .fontInfoPostscriptWindowsCharacterSetValidator`  s   r   c                 C  s    t tdfd}t| |sdS dS )r:   T)idF)rA   rU   r3   r   rE   r   r   r   %fontInfoWOFFMetadataUniqueIDValidatorj  s   
r   c                 C  J   t dft dft dft dfd}t| |sdS d| v r#| ddvr#dS dS )r:   TF)nameurldirclassr   ltrrtlrU   r3   getr   r   r   r   #fontInfoWOFFMetadataVendorValidatort     
r   c                 C  s   t tdfd}t| |sdS t| d sdS tdftdftdftdftdfd}| d D ]}t||s6 dS d|v rD|ddvrD dS q,dS )r:   T)creditsFr   )r   r   roler   r   r   r   )rA   r   r3   r@   rU   r   )r   rE   creditr   r   r   $fontInfoWOFFMetadataCreditsValidator  s$   

r   c                 C  sB   t tdftdfd}t| |sdS | d D ]	}t|s dS qdS )r:   FT)r   textr   rA   rU   r   r3   fontInfoWOFFMetadataTextValuer   rE   r   r   r   r   (fontInfoWOFFMetadataDescriptionValidator  s   
r   c                 C  sP   t tdftdftdfd}t| |sdS d| v r&| d D ]	}t|s% dS qdS )r:   F)r   r   r   r   Tr   r   r   r   r   $fontInfoWOFFMetadataLicenseValidator  s   
r   c                 C  <   t tdfd}t| |sdS | d D ]	}t|s dS qdS r:   T)r   Fr   rA   r   r3   r   r   r   r   r   &fontInfoWOFFMetadataTrademarkValidator     
r   c                 C  r   r   r   r   r   r   r   &fontInfoWOFFMetadataCopyrightValidator  r   r   c                 C  sD   t dft dft dfd}t| |sdS d| v r | ddvr dS dS )r:   TF)r   r   r   r   r   r   r   r   r   r   %fontInfoWOFFMetadataLicenseeValidator  s   
r   c                 C  r   r:   TF)r   languager   r   r   r   r   r   r   r   r   r     r   r   c                 C  s2   t | tsdS | sdS | D ]	}t|s dS qdS )r:   FT)r   r   &fontInfoWOFFMetadataExtensionValidator)r   	extensionr   r   r   'fontInfoWOFFMetadataExtensionsValidator  s   
r   c                 C  sl   t tdftdftdfd}t| |sdS d| v r&| d D ]	}t|s% dS q| d D ]	}t|s3 dS q*dS )r:   FT)namesr   r   r   r   )rA   r   rU   r3   *fontInfoWOFFMetadataExtensionNameValidator*fontInfoWOFFMetadataExtensionItemValidator)r   rE   r   itemr   r   r   r     s   
r   c                 C  sd   t tdftdftdfd}t| |sdS | d D ]	}t|s! dS q| d D ]	}t|s/ dS q&dS )r:   FT)r   r   r   r   r   )rA   rU   r   r3   r   +fontInfoWOFFMetadataExtensionValueValidator)r   rE   r   valr   r   r   r     s   
r   c                 C  r   r   r   r   r   r   r   r   (  r   r   c                 C  r   r   r   r   r   r   r   r   9  r   r   identifiersOptional[set[str]]c                 C  b   t | tsdS |du rt }| D ]}t|s dS |d}|dur.||v r) dS || qdS r:   FN
identifierT)r   r   r    guidelineValidatorr   add)r   r   guider   r   r   r   guidelinesValidatorO     


r   F)xyangler   colorr   _guidelineDictPrototypec                 C  s   t | tsdS | d}| d}| d}|du r |du r dS |du s(|du r.|dur.dS |dur<|dur<|du r<dS |durL|dk rFdS |dkrLdS | d}|dur[t|s[dS | d	}|durjt|sjdS d
S )r:   Fr   r   r   Nr   ih  r   r   T)r3   r   r   identifierValidatorcolorValidator)r   r   r   r   r   r   r   r   r   r   l  s0   





r   c                 C  r   r   )r   r   r    anchorValidatorr   r   )r   r   anchorr   r   r   r   anchorsValidator  r   r   )r   r   r   r   r   _anchorDictPrototypec                 C  sv   t | tsdS | d}| d}|du s|du rdS | d}|dur*t|s*dS | d}|dur9t|s9dS dS )r:   Fr   r   Nr   r   T)r3   r   r   r   r   )r   r   r   r   r   r   r   r   r     s   




r   c                 C  sZ   d}d}t | tsdS | sdS t| dkrdS | D ]}t|}||k s'||kr* dS qdS )z
    Version 3+.

    >>> identifierValidator("a")
    True
    >>> identifierValidator("")
    False
    >>> identifierValidator("a" * 101)
    False
        ~   Fd   T)r   rU   r@   ord)r   validCharactersMinvalidCharactersMaxcir   r   r   r     s   
r   c              	   C  s   t | tsdS | d}t|dkrdS |D ]C}| }d}zt|}d}W n	 ty/   Y nw |sDzt|}d}W n	 tyC   Y nw |sI dS d|  krUdksY dS   dS qdS )a  
    Version 3+.

    >>> colorValidator("0,0,0,0")
    True
    >>> colorValidator(".5,.5,.5,.5")
    True
    >>> colorValidator("0.5,0.5,0.5,0.5")
    True
    >>> colorValidator("1,1,1,1")
    True

    >>> colorValidator("2,0,0,0")
    False
    >>> colorValidator("0,2,0,0")
    False
    >>> colorValidator("0,0,2,0")
    False
    >>> colorValidator("0,0,0,2")
    False

    >>> colorValidator("1r,1,1,1")
    False
    >>> colorValidator("1,1g,1,1")
    False
    >>> colorValidator("1,1,1b,1")
    False
    >>> colorValidator("1,1,1,1a")
    False

    >>> colorValidator("1 1 1 1")
    False
    >>> colorValidator("1 1,1,1")
    False
    >>> colorValidator("1,1 1,1")
    False
    >>> colorValidator("1,1,1 1")
    False

    >>> colorValidator("1, 1, 1, 1")
    True
    F,rQ   Tr   r;   )r   rU   rW   r@   stripr!   rX   float)r   partspart	convertednumberr   r   r   r     s:   
+
r   s   PNG

bytespngSignatureT)fileNamexScalexyScaleyxScaleyScalexOffsetyOffsetr   _imageDictPrototypec                 C  s<   t | tsdS | d sdS | d}|durt|sdS dS )r:   Fr   r   NT)r3   r   r   r   )r   r   r   r   r   imageValidatorC  s   

r   pathOptional[str]dataOptional[bytes]fileObjOptional[Any]tuple[bool, Any]c                 C  s   | dus|dus|dusJ | dur-t | d}|d}W d   n1 s'w   Y  n|dur8|dd }n|durJ| }|d}|| |tkrPdS dS )zG
    Version 3+.

    This checks the signature of the image data.
    Nrb   )Fz,Image does not begin with the PNG signature.TN)r   readtellseekr   )r   r   r   f	signatureposr   r   r   pngValidatorS  s   


r   ufoPathOrFileSystemUnion[str, fs.base.FS]tuple[bool, Optional[str]]c                 C  sr  t |tjjr
|}ntj|}d}t | tsd|fS t }t }i }| D ]}t |ts2d|f  S t|dks>d|f  S |D ]}t |t	sOd|f    S q@|\}	}
|
dkre|

dsedd|
 f  S t|	dkrn dS ||
s{dd	|
 f  S |	d
kr|
dkr dS |	|v rdd|	 f  S ||	 |
|v rdd|
 f  S ||
 |
||	< q%d| v }|sdS dS )zD
    Check the validity of layercontents.plist.
    Version 3+.
    z1layercontents.plist in not in the correct format.Fr<   glyphszglyphs.z3Invalid directory name (%s) in layercontents.plist.r   )Fz(Empty layer name in layercontents.plist.z A glyphset does not exist at %s.zpublic.default)FzIThe name public.default is being used by a layer that is not the default.z1The layer name %s is used by more than one layer.z0The directory %s is used by more than one layer.)Fz1The required default glyph set is not in the UFO.r   )r   fsbaseFSosfsOSFSr   r    r@   rU   
startswithexistsr   r   )r   r   
fileSystembogusFileMessageusedLayerNamesusedDirectoriescontentsentryr   	layerNamedirectoryNamefoundDefaultr   r   r   layerContentsValidatorq  s^   







r  c                 C  s  d}t | s
d|fS i }i }|  D ]l\}}t|ts!d|f  S t|ttfs.d|f  S |s3 dS |dr~|dsC|dsCqtdt|krN dS |drV|}n|}|D ]#}t|tskdd	| f    S ||v rydd
| f    S |||< qZqdS )a  
    Check the validity of the groups.
    Version 3+ (though it's backwards compatible with UFO 1 and UFO 2).

    >>> groups = {"A" : ["A", "A"], "A2" : ["A"]}
    >>> groupsValidator(groups)
    (True, None)

    >>> groups = {"" : ["A"]}
    >>> valid, msg = groupsValidator(groups)
    >>> valid
    False
    >>> print(msg)
    A group has an empty name.

    >>> groups = {"public.awesome" : ["A"]}
    >>> groupsValidator(groups)
    (True, None)

    >>> groups = {"public.kern1." : ["A"]}
    >>> valid, msg = groupsValidator(groups)
    >>> valid
    False
    >>> print(msg)
    The group data contains a kerning group with an incomplete name.
    >>> groups = {"public.kern2." : ["A"]}
    >>> valid, msg = groupsValidator(groups)
    >>> valid
    False
    >>> print(msg)
    The group data contains a kerning group with an incomplete name.

    >>> groups = {"public.kern1.A" : ["A"], "public.kern2.A" : ["A"]}
    >>> groupsValidator(groups)
    (True, None)

    >>> groups = {"public.kern1.A1" : ["A"], "public.kern1.A2" : ["A"]}
    >>> valid, msg = groupsValidator(groups)
    >>> valid
    False
    >>> print(msg)
    The glyph "A" occurs in too many kerning groups.
    z,The group data is not in the correct format.F)FzA group has an empty name.zpublic.zpublic.kern1.zpublic.kern2.zpublic.kernN.)Fz@The group data contains a kerning group with an incomplete name.z-The group data %s contains an invalid member.z1The glyph "%s" occurs in too many kerning groups.r   )r   r   r   rU   r   r   r   r@   )r   bogusFormatMessagefirstSideMappingsecondSideMapping	groupName	glyphListd	glyphNamer   r   r   groupsValidator  sD   ,




r  c                 C  s   d}t | tsd|fS |  D ]=\}}t |tsd|f  S t |ts)d|f  S | D ]\}}t |ts>d|f    S t |tsKd|f    S q-qdS )aA  
    Check the validity of the kerning data structure.
    Version 3+ (though it's backwards compatible with UFO 1 and UFO 2).

    >>> kerning = {"A" : {"B" : 100}}
    >>> kerningValidator(kerning)
    (True, None)

    >>> kerning = {"A" : ["B"]}
    >>> valid, msg = kerningValidator(kerning)
    >>> valid
    False
    >>> print(msg)
    The kerning data is not in the correct format.

    >>> kerning = {"A" : {"B" : "100"}}
    >>> valid, msg = kerningValidator(kerning)
    >>> valid
    False
    >>> print(msg)
    The kerning data is not in the correct format.
    z.The kerning data is not in the correct format.Fr   )r   r   r   rU   r   )r   r  first
secondDictsecondr   r   r   r   kerningValidator  s    




r  z-The lib data is not in the correct format: %sc                 C  s   t | sdt| j }dt| fS |  D ]M\}} t|ts+ddt|j|f f  S |dkrbd}t| ttfsGdt| j }d|| f  S | D ]}t|tsadt|j }d|| f    S qIqdS )	a  
    Check the validity of the lib.
    Version 3+ (though it's backwards compatible with UFO 1 and UFO 2).

    >>> lib = {"foo" : "bar"}
    >>> fontLibValidator(lib)
    (True, None)

    >>> lib = {"public.awesome" : "hello"}
    >>> fontLibValidator(lib)
    (True, None)

    >>> lib = {"public.glyphOrder" : ["A", "C", "B"]}
    >>> fontLibValidator(lib)
    (True, None)

    >>> lib = "hello"
    >>> valid, msg = fontLibValidator(lib)
    >>> valid
    False
    >>> print(msg)  # doctest: +ELLIPSIS
    The lib data is not in the correct format: expected a dictionary, ...

    >>> lib = {1: "hello"}
    >>> valid, msg = fontLibValidator(lib)
    >>> valid
    False
    >>> print(msg)
    The lib key is not properly formatted: expected str, found int: 1

    >>> lib = {"public.glyphOrder" : "hello"}
    >>> valid, msg = fontLibValidator(lib)
    >>> valid
    False
    >>> print(msg)  # doctest: +ELLIPSIS
    public.glyphOrder is not properly formatted: expected list or tuple,...

    >>> lib = {"public.glyphOrder" : ["A", 1, "B"]}
    >>> valid, msg = fontLibValidator(lib)
    >>> valid
    False
    >>> print(msg)  # doctest: +ELLIPSIS
    public.glyphOrder is not properly formatted: expected str,...
    expected a dictionary, found %sFzAThe lib key is not properly formatted: expected str, found %s: %rzpublic.glyphOrderz/public.glyphOrder is not properly formatted: %sz expected list or tuple, found %szexpected str, found %sr   )	r   type__name___bogusLibFormatMessager   r   rU   r   r   )r   reasonr/   bogusGlyphOrderMessager  r   r   r   fontLibValidatorG  s,   -

r  c                 C  sp   t | sdt| j }dt| fS |  D ] \}} t|ts*d| }dt| f  S |dkr5t| s5 dS qdS )a,  
    Check the validity of the lib.
    Version 3+ (though it's backwards compatible with UFO 1 and UFO 2).

    >>> lib = {"foo" : "bar"}
    >>> glyphLibValidator(lib)
    (True, None)

    >>> lib = {"public.awesome" : "hello"}
    >>> glyphLibValidator(lib)
    (True, None)

    >>> lib = {"public.markColor" : "1,0,0,0.5"}
    >>> glyphLibValidator(lib)
    (True, None)

    >>> lib = {"public.markColor" : 1}
    >>> valid, msg = glyphLibValidator(lib)
    >>> valid
    False
    >>> print(msg)
    public.markColor is not properly formatted.
    r  Fzkey (%s) should be a stringzpublic.markColor)Fz+public.markColor is not properly formatted.r   )r   r  r  r  r   r   rU   r   )r   r  r/   r   r   r   glyphLibValidator  s   
r  __main__)r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r-   r.   r   r   )r   r   r   r   )N)r   r   r   r   r   r   )NNN)r   r   r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   )r   r   r   r   )U__doc__
__future__r   rY   collections.abcr   r   ior   fontTools.misc.filesystemmisc
filesystemr   typingr   r   r   r	   fontTools.annotationsr
   fontTools.ufoLib.utilsr   rA   rU   r   r  r   r.   r   r   r$   r*   r,   r3   r9   rL   rj   rq   rr   rt   rx   ry   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r!   r   r   __annotations__r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  doctesttestmodr   r   r   r   <module>   s    (






"


<





























)


	

J







L
\+

H
&