o
    hUx                  
   @   s  d Z ddlZddlmZ ddlZddlZddlmZ ddl	m
Z
 dd Zdd	 Zd
d Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Z d2d3 Z!d4d5 Z"d6d7 Z#d8d9 Z$d:d; Z%d<d= Z&d>d? Z'd@dA Z(dBdC Z)dDdE Z*dFdG Z+djdHdIZ,e-e.e/fdJfe.e/fdJfe.e/fdJfe0dJfe0dJfe0dJfdKZ1dLdM Z2djdNdOZ3e-e.e/fdJfe.e/fdJfe0dJfe0dJfe0dJfdPZ4dQdR Z5dSdT Z6dUdV Z7dWZ8e-e0dXfe.e/fdJfe.e/fdJfe.e/fdJfe.e/fdJfe.e/fdJfe.e/fdJfe0dJfdYZ9dZd[ Z:dkd\d]Z;d^d_ Z<d`da Z=dbdc Z>ddZ?dedf Z@dgdh ZAeBdikrIddlCZCeCD  dS dS )lz"Various low level data validators.    N)open)Mapping)numberTypesc                 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)valueattr r   o/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/fontTools/ufoLib/validators.pyisDictEnough   s   

r   c                 C   s
   t | |S )(
    Generic. (Added at version 2.)
    )r   )r
   typr   r   r   genericTypeValidator   s   
r   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   validValues	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   genericNonNegativeIntValidator5   
   
r   c                 C   r   r   )r   r   r   r   r   r   !genericNonNegativeNumberValidator@   r    r!   c                 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
   	prototypekeyr   requiredvprototypeTyper   r   r   genericDictValidatorK   s(   

r'   c                 C   s   g d}| |v S )
    Version 2+.
    )regularitalicboldzbold italicr   )r
   optionsr   r   r   "fontInfoStyleMapStyleNameValidatorm   s   r-   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rangeGaspBehaviorr2   r3   )
r   r   lendictr   r'   r   r   appendsorted)	r
   validBehaviorsdictPrototype	ppemOrderrangeRecordppembehaviorppemValiditybehaviorValidityr   r   r   )fontInfoOpenTypeGaspRangeRecordsValidatoru   s,   


r@   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 )r(   F    r/   /r0   :      r      ;   T)	r   strr4   countsplitr   
ValueErrorcalendar
monthrange)
r
   datetimeyearmonthdaymonthMaxDayhourminutesecondr   r   r   $fontInfoOpenTypeHeadCreatedValidator   sf   
rX   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   r5   r   rI   r'   )r
   r9   
nameRecordr   r   r   $fontInfoOpenTypeNameRecordsValidator   s   

r_   c                 C   r   )r(   Fr   Tr   r   r   r   r   'fontInfoOpenTypeOS2WeightClassValidator   r    r`   c                 C   s*   t | tsdS | dk rdS | dkrdS dS )r(   Fr/   	   Tr   r   r   r   r   &fontInfoOpenTypeOS2WidthClassValidator   s   
rb   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   r4   r   r   r
   r   r   r   *fontInfoVersion2OpenTypeOS2PanoseValidator   s   
rf   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.   Frc   r   Trd   re   r   r   r   *fontInfoVersion3OpenTypeOS2PanoseValidator  s   
rg   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 )r(   Fr0   r         Trd   )r   r
   classID
subclassIDr   r   r   'fontInfoOpenTypeOS2FamilyClassValidator  s   
rl   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 )r(   Frh   r0   Tr   r   r   r4   r   re   r   r   r    fontInfoPostscriptBluesValidator+     
ro   c                 C   rm   )r(   Frc   r0   Trn   re   r   r   r   %fontInfoPostscriptOtherBluesValidator;  rp   rq   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 )r(   FrF   Trn   re   r   r   r    fontInfoPostscriptStemsValidatorK  s   
rr   c                 C   s   t tdd}| |vrdS dS )r(   r/      FT)r   range)r
   r   r   r   r   .fontInfoPostscriptWindowsCharacterSetValidatorY  s   ru   c                 C   s    t tdfd}t| |sdS dS )r.   T)idF)r5   rI   r'   r
   r9   r   r   r   %fontInfoWOFFMetadataUniqueIDValidatorc  s   
rx   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rI   r'   getrw   r   r   r   #fontInfoWOFFMetadataVendorValidatorm     
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   )rz   r{   roler|   r}   r|   r~   )r5   r   r'   r4   rI   r   )r
   r9   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   r5   rI   r   r'   fontInfoWOFFMetadataTextValuer
   r9   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   rv   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   r5   r   r'   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)rz   r|   r}   r|   r~   r   rw   r   r   r   %fontInfoWOFFMetadataLicenseeValidator  s   
r   c                 C   ry   r.   TF)r   languager|   r}   r|   r~   r   rw   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   rv   r   r   )r5   r   rI   r'   *fontInfoWOFFMetadataExtensionNameValidator*fontInfoWOFFMetadataExtensionItemValidator)r
   r9   rz   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)rv   r   r   r   r   )r5   rI   r   r'   r   +fontInfoWOFFMetadataExtensionValueValidator)r
   r9   rz   valr   r   r   r     s   
r   c                 C   ry   r   r   rw   r   r   r   r     r   r   c                 C   ry   r   r   rw   r   r   r   r   (  r   r   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
   identifiersguider   r   r   r   guidelinesValidator>     


r   F)xyanglerz   colorr   c                 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)r'   _guidelineDictPrototyper   identifierValidatorcolorValidator)r
   r   r   r   r   r   r   r   r   r   [  s0   





r   c                 C   r   r   )r   r   r   anchorValidatorr   r   )r
   r   anchorr   r   r   r   anchorsValidator  r   r   )r   r   rz   r   r   c                 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)r'   _anchorDictPrototyper   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   rI   r4   ord)r
   validCharactersMinvalidCharactersMaxcr   r   r   r     s   
r   c              	   C   s   t | tsdS | d}t|dkrdS |D ]A}| }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 rP dS |dkrW 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,rE   Tr   r/   )r   rI   rK   r4   stripr   rL   float)r
   partspart	convertedr   r   r   r     s:   
+
r   s   PNG

T)fileNamexScalexyScaleyxScaleyScalexOffsetyOffsetr   c                 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)r'   _imageDictPrototyper   r   )r
   r   r   r   r   imageValidator3  s   

r   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seekpngSignature)pathdatafileObjf	signatureposr   r   r   pngValidatorC  s   

r   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.Fr0   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   r4   rI   
startswithexistsr   r   )r
   ufoPathOrFileSystem
fileSystembogusFileMessageusedLayerNamesusedDirectoriescontentsentryi	layerNamedirectoryNamefoundDefaultr   r   r   layerContentsValidator]  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   rI   r   r   r   r4   )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   rI   r   )r   r   first
secondDictrW   r
   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   rI   r   r   )r
   reasonr#   bogusGlyphOrderMessager   r   r   r   fontLibValidator1  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   rI   r   )r
   r   r#   r   r   r   glyphLibValidatory  s   
r   __main__)N)NNN)E__doc__rM   ior   fs.baser   fs.osfscollections.abcr   fontTools.ufoLib.utilsr   r   r   r   r   r!   r'   r-   r@   rX   r_   r`   rb   rf   rg   rl   ro   rq   rr   ru   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r5   r   r   rI   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   doctesttestmodr   r   r   r   <module>   s    "<







)

	K






J\+H
&