PKU Efontparts-stable/.buildinfo# Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. config: 7383837b4ed2da26958147f3f66c4579 tags: 0957a7f5604f7fa265ade309e7b795c2 PKUi~fontparts-stable/objects.inv# Sphinx inventory version 2 # Project: FontParts # Version: 0.1 # The remainder of this file is compressed using zlib. xŝ[sF+T}͗r"ovIC k@a@_HLt%E t VYZ~#nݯlM7#VS%ۡ;ءeD =p|Hm8hxT(s]1MM M0M)VNo;M! °A&zA.SEt7$*_ ~B~B~BBBBBibS # Ц tp6Yjѷ{X毽< ѳJغW  pf0rls3\3Кц11*,5R=DZT3lH}Lxt 4MPgo:tyۡ˛]:C9 AM? Q"m * 2Q?  E8k: qy 9>>m!5sA q.2a׈J p`NJXCu cش{3 q6r*HI\͈ܥ<a4oWӶev_VZ1K6$bHŷ*)I82r[#3(Ļ4s[%jFa6bP WMزn=I2Aq%—W@+MC@o^x=]n0Ӕ V[d $g0-aBD!@pQ=z j1@ A&`$B| Xl p*A # 4r$N0prY!DA"56qeѼP΢jbzE{yQn5rL/fG$ǃԴ/D00:L:ֺ$zPkEU': Odo*KTH2g/Eb8] "bRWT**̇>fQthV"|.dzC~4CK;a)#"ӵ2IX\}YxLȣQ@Nq+JsY}=4*y)U7Uxn̥YO6ۨ}  kIg)2'͓FoyA`.; TA~\=T(ő}O5BH2@$OaI SI0z[ wR}q`u4*~(iqbǸvk>ws한* A>cTSaU .s6EٻhĊx'} XO 1j* ꩐fh_€seD'>lӅ45y::OT5CL2:> eMXm@;~aRCjEO`:\ĕ@HRΙgem>E:N `(fa3(t1(Ga!VY%nUooʢ$ꥲ0$+!E};emmvek Z<q>1 K-V1Z ,r!AOB SjpZkA6~g[,[|~rE$v3( LC&P{휏7s%•x W ]7s%ȕx+WM\ qb4Rvy("I@"6Gk3;P@~6er:@MG:\= %rS (Gar\%R!WD!]/BMAqfGADs;0lX ~@;w-PUk0 pK8CF!LG5' O,7][|j UE30#"t Y,/2ԩMb}b3U@(uZA^0Z!C]k^`NS2.b(26 ,dTd0&n`jJYgJ}&Tb(>CP[af8g2ܶ|IЅ OQuל+AK|Ѐ.dPf y&CP(|mKzT_fV"T@oFRo qs*av3!q!p]~'I$z2ytP3٘ voj8oeX9WPz;Ws&xmzmG98q!8GzC@/NJc*-2 vza2wp2yQvJY2OV;S^q(7H hA׍X 1Lzަ{^m{=>Pѧ,XPrG; l1aED@~:=#b'CYLD$PN8^,A qQvG AH 1 wOIDNš4AN@)kPP~xWgWA 2#.#*#{ֿ9Gdd91OMYRk S|lkEDnZqfU@Ð:xCn/wNE$c;Z1}3wL;N{[g w8U$nJ午SoD)i{囑,ɓyh crsYs:u1]jĈ8QQ&|ead\VFtԈ4S ݼ gŚW' (jG1B%PdJNSrcѿ$;UM"r5[c&mâ{>-W^#J! Aqjlυ`m qf7 OXH"n UCDXcхWq#.x:g#~֛{4߶3@oœ3!rae+_7MH 0tk~P"A1t cU!:¯,ʳ ҷ^b f ÀMdj}I> }@9~A~9Bd.0zk$+9[nwsг@V2itv)6]4"7+ڝUKp%.Jͩը7wc~M)sLYQu'{}uKkrWv4ڡ,@xe8wk?UyfU+wfz+5i?ؿɟ:W>j9Sf⽏y0m}cswk"+ ʏWk\9_^˱w)+m)*UW 巆Ƽ"Y"}n׍RDcw}ǿNքnjڦGqdϵ|y۶y7:.|'} e3DH9j ?V ?nӀy3B ZEӀEH{!9GjbNۼ eN3Vm5K!Cw7ӿm}Ϟng} MtFNN׺ޞ93;ŌA`f_4*WQ ǍƠcT}?6ovdrfն~қ}.9;]6nٹbUӏ|6f_)%/ ݔ#~߼\7uv(ofz?X.AmuD,+%|`',>QnXa9#,H蒴 hʉen;Sxje||/жh}\unr mڅ/?MR}w|>{Q߅Cwo2{/?C#s-0ħhwi< zڝyH0;n~ܲ f:*co],W}ܔKEhg"4csE?FI u7mwQx<~Ҷk_>PKFMŌ[O+6{~V}io62'6Ҽ~wS';FhdU+^Zu_hxQi5ˣ-}\i]q1PKU؁fontparts-stable/contents.html FontParts 0.1 documentation

Designers

Getting Started

These need to be ported and updated from RoboFab’s documentation.

For a quick start, here’s the sample code from the introduction ported to fontparts:

from fontParts.world import OpenFont

font = OpenFont("/path/to/my/font.ufo")

for glyph in font:
   glyph.leftMargin = glyph.leftMargin + 10
   glyph.rightMargin = glyph.rightMargin + 10

Find more of the original samples at https://github.com/robotools/robofab/tree/master/Docs/Examples

Object Reference

FontParts scripts are built on with objects that represent fonts, glyphs, contours and so on. The objects are obtained through fontparts-world.

Objects

FontParts scripts are built on with objects that represent fonts, glyphs, contours and so on. The objects are obtained through fontparts-world.

Font

Note

This section needs to contain the following:

  • description of what this is ✓
  • sub-object with basic usage ✓
  • bridge to default layer for glyphs for backwards compatibility ✗
  • glyph interaction with basic usage ✗
Description

The Font object is the central part that connects all glyphs with font information like names, key dimensions etc.

Font objects behave like dictionaries: the glyph name is the key and the returned value is a Glyph object for that glyph. If the glyph does not exist, Font will raise an IndexError.

Font has a couple of important sub-objects which are worth checking out. The font’s kerning is stored in a Kerning object and can be reached as an attribute at Font.kerning. Fontnames, key dimensions, flags etc are stored in a Info object which is available through Font.info. The Font.lib is a Lib object which behaves as a dictionary.

Overview
Copy
BaseFont.copy Copy the font into a new font.
File Operations
BaseFont.path The path to the file this object represents.
BaseFont.save Save the font to path.
BaseFont.generate Generate the font to another format.
Sub-Objects
BaseFont.info The font’s BaseInfo object.
BaseFont.groups The font’s BaseGroups object.
BaseFont.kerning The font’s BaseKerning object.
BaseFont.features The font’s BaseFeatures object.
BaseFont.lib The font’s BaseLib object.
BaseFont.tempLib The font’s BaseLib object.
Layers
BaseFont.layers The font’s BaseLayer objects.
BaseFont.layerOrder A list of layer names indicating order of the layers in the font.
BaseFont.defaultLayer The font’s default layer.
BaseFont.getLayer Get the BaseLayer with name.
BaseFont.newLayer Make a new layer with name and color.
BaseFont.removeLayer Remove the layer with name from the font.
BaseFont.insertLayer Insert layer into the font.
Glyphs
BaseFont.__len__ An int representing number of glyphs in the layer.
BaseFont.keys Get a list of all glyphs in the layer.
BaseFont.glyphOrder The preferred order of the glyphs in the font.
BaseFont.__iter__ Iterate through the BaseGlyph objects in the layer.
BaseFont.__contains__ Test if the layer contains a glyph with name.
BaseFont.__getitem__ Get the BaseGlyph with name from the layer.
BaseFont.newGlyph Make a new glyph with name in the layer.
BaseFont.insertGlyph Insert glyph into the layer.
BaseFont.removeGlyph Remove the glyph with name from the layer.
Reference
class fontParts.base.BaseFont(pathOrObject=None, showInterface=True)[source]

A font object. This object is almost always created with one of the font functions in fontparts-world.

When constructing a font, the object can be created in a new file, from an existing file or from a native object. This is defined with the pathOrObjectArgument. If pathOrObject is a string, the string must represent an existing file. If pathOrObject is an instance of the environment’s unwrapped native font object, wrap it with FontParts. If pathOrObject is None, create a new, empty font. If showInterface is False, the font should be created without graphical interface. The default for showInterface is True.

Copy
BaseFont.copy()[source]

Copy the font into a new font.

>>> copiedFont = font.copy()

This will copy:

  • info
  • groups
  • kerning
  • features
  • lib
  • layers
  • layerOrder
  • defaultLayerName
  • glyphOrder
  • guidelines
File Operations
BaseFont.path

The path to the file this object represents.

>>> print font.path
"/path/to/my/font.ufo"
BaseFont.save(path=None, showProgress=False, formatVersion=None, fileStructure=None)[source]

Save the font to path.

>>> font.save()
>>> font.save("/path/to/my/font-2.ufo")

If path is None, use the font’s original location. The file type must be inferred from the file extension of the given path. If no file extension is given, the environment may fall back to the format of its choice. showProgress indicates if a progress indicator should be displayed during the operation. Environments may or may not implement this behavior. formatVersion indicates the format version that should be used for writing the given file type. For example, if 2 is given for formatVersion and the file type being written if UFO, the file is to be written in UFO 2 format. This value is not limited to UFO format versions. If no format version is given, the original format version of the file should be preserved. If there is no original format version it is implied that the format version is the latest version for the file type as supported by the environment. fileStructure indicates the file structure of the written ufo. The fileStructure can either be None, ‘zip’ or ‘package’, None will use the existing file strucure or the default one for unsaved font. ‘package’ is the default file structure and ‘zip’ will save the font to .ufoz.

Note

Environments may define their own rules governing when a file should be saved into its original location and when it should not. For example, a font opened from a compiled OpenType font may not be written back into the original OpenType font.

BaseFont.close(save=False)[source]

Close the font.

>>> font.close()

save is a boolean indicating if the font should be saved prior to closing. If save is True, the BaseFont.save method will be called. The default is False.

BaseFont.generate(format, path=None, **environmentOptions)[source]

Generate the font to another format.

>>> font.generate("otfcff")
>>> font.generate("otfcff", "/path/to/my/font.otf")

format defines the file format to output. Standard format identifiers can be found in BaseFont.generateFormatToExtension:

Environments are not required to support all of these and environments may define their own format types. path defines the location where the new file should be created. If a file already exists at that location, it will be overwritten by the new file. If path defines a directory, the file will be output as the current file name, with the appropriate suffix for the format, into the given directory. If no path is given, the file will be output into the same directory as the source font with the file named with the current file name, with the appropriate suffix for the format.

Environments may allow unique keyword arguments in this method. For example, if a tool allows decomposing components during a generate routine it may allow this:

>>> font.generate("otfcff", "/p/f.otf", decompose=True)
Sub-Objects
BaseFont.info

The font’s BaseInfo object.

>>> font.info.familyName
"My Family"
BaseFont.groups

The font’s BaseGroups object.

>>> font.groups["myGroup"]
["A", "B", "C"]
BaseFont.kerning

The font’s BaseKerning object.

>>> font.kerning["A", "B"]
-100
BaseFont.features

The font’s BaseFeatures object.

>>> font.features.text
"include(features/substitutions.fea);"
BaseFont.lib

The font’s BaseLib object.

>>> font.lib["org.robofab.hello"]
"world"
Layers
BaseFont.layers

The font’s BaseLayer objects.

>>> for layer in font.layers:
...     layer.name
"My Layer 1"
"My Layer 2"
BaseFont.layerOrder

A list of layer names indicating order of the layers in the font.

>>> font.layerOrder = ["My Layer 2", "My Layer 1"]
>>> font.layerOrder
["My Layer 2", "My Layer 1"]
BaseFont.defaultLayer

The font’s default layer.

>>> layer = font.defaultLayer
>>> font.defaultLayer = otherLayer
BaseFont.getLayer(name)[source]

Get the BaseLayer with name.

>>> layer = font.getLayer("My Layer 2")
BaseFont.newLayer(name, color=None)[source]

Make a new layer with name and color. name must be a String and color must be a Color or None.

>>> layer = font.newLayer("My Layer 3")

The will return the newly created BaseLayer.

BaseFont.removeLayer(name)[source]

Remove the layer with name from the font.

>>> font.removeLayer("My Layer 3")
BaseFont.insertLayer(layer, name=None)[source]

Insert layer into the font.

>>> layer = font.insertLayer(otherLayer, name="layer 2")

This will not insert the layer directly. Rather, a new layer will be created and the data from layer will be copied to to the new layer. name indicates the name that should be assigned to the layer after insertion. If name is not given, the layer’s original name must be used. If the layer does not have a name, an error must be raised. The data that will be inserted from layer is the same data as documented in BaseLayer.copy.

Glyphs

Interacting with glyphs at the font level is a shortcut for interacting with glyphs in the default layer.

>>> glyph = font.newGlyph("A")

Does the same thing as:

>>> glyph = font.getLayer(font.defaultLayerName).newGlyph("A")
BaseFont.__len__()

An int representing number of glyphs in the layer.

>>> len(layer)
256
BaseFont.keys()

Get a list of all glyphs in the layer.

>>> layer.keys()
["B", "C", "A"]

The order of the glyphs is undefined.

BaseFont.glyphOrder

The preferred order of the glyphs in the font.

>>> font.glyphOrder
["C", "B", "A"]
>>> font.glyphOrder = ["A", "B", "C"]
BaseFont.__iter__()

Iterate through the BaseGlyph objects in the layer.

>>> for glyph in layer:
...     glyph.name
"A"
"B"
"C"
BaseFont.__contains__(name)

Test if the layer contains a glyph with name.

>>> "A" in layer
True
BaseFont.__getitem__(name)

Get the BaseGlyph with name from the layer.

>>> glyph = layer["A"]
BaseFont.newGlyph(name, clear=True)

Make a new glyph with name in the layer.

>>> glyph = layer.newGlyph("A")

The newly created BaseGlyph will be returned.

If the glyph exists in the layer and clear is set to False, the existing glyph will be returned, otherwise the default behavior is to clear the exisiting glyph.

BaseFont.insertGlyph(glyph, name=None)

Insert glyph into the layer.

>>> glyph = layer.insertGlyph(otherGlyph, name="A")

This method is deprecated. BaseFont.__setitem__ instead.

BaseFont.removeGlyph(name)

Remove the glyph with name from the layer.

>>> layer.removeGlyph("A")

This method is deprecated. BaseFont.__delitem__ instead.

Guidelines
BaseFont.guidelines

An Immutable List of font-level BaseGuideline objects.

>>> for guideline in font.guidelines:
...     guideline.angle
0
45
90
BaseFont.appendGuideline(position=None, angle=None, name=None, color=None, guideline=None)[source]

Append a new guideline to the font.

>>> guideline = font.appendGuideline((50, 0), 90)
>>> guideline = font.appendGuideline((0, 540), 0, name="overshoot",
>>> color=(0, 0, 0, 0.2))

position must be a Coordinate indicating the position of the guideline. angle indicates the Angle of the guideline. name indicates the name for the guideline. This must be a String or None. color indicates the color for the guideline. This must be a Color or None. This will return the newly created BaseGuidline object.

guideline may be a BaseGuideline object from which attribute values will be copied. If position, angle, name or color are specified as arguments, those values will be used instead of the values in the given guideline object.

BaseFont.removeGuideline(guideline)[source]

Remove guideline from the font.

>>> font.removeGuideline(guideline)
>>> font.removeGuideline(2)

guideline can be a guideline object or an integer representing the guideline index.

BaseFont.clearGuidelines()[source]

Clear all guidelines.

>>> font.clearGuidelines()
Interpolation
BaseFont.isCompatible(other)[source]

Evaluate interpolation compatibility with other.

>>> compatible, report = self.isCompatible(otherFont)
>>> compatible
False
>>> report
[Fatal] Glyph: "test1" + "test2"
[Fatal] Glyph: "test1" contains 1 contours | "test2" contains 2 contours

This will return a bool indicating if the font is compatible for interpolation with other and a String of compatibility notes.

BaseFont.interpolate(factor, minFont, maxFont, round=True, suppressError=True)[source]

Interpolate all possible data in the font.

>>> font.interpolate(0.5, otherFont1, otherFont2)
>>> font.interpolate((0.5, 2.0), otherFont1, otherFont2, round=False)

The interpolation occurs on a 0 to 1.0 range where minFont is located at 0 and maxFont is located at 1.0. factor is the interpolation value. It may be less than 0 and greater than 1.0. It may be a Integer/Float or a tuple of two Integer/Float. If it is a tuple, the first number indicates the x factor and the second number indicates the y factor. round indicates if the result should be rounded to integers. suppressError indicates if incompatible data should be ignored or if an error should be raised when such incompatibilities are found.

Normalization
BaseFont.round()[source]

Round all approriate data to integers.

>>> font.round()

This is the equivalent of calling the round method on:

  • info
  • kerning
  • the default layer
  • font-level guidelines

This applies only to the default layer.

BaseFont.autoUnicodes()[source]

Use heuristics to set Unicode values in all glyphs.

>>> font.autoUnicodes()

Environments will define their own heuristics for automatically determining values.

This applies only to the default layer.

Environment
BaseFont.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BaseFont.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()

Info

Description

The Info object contains all names, numbers, URLs, dimensions, values, etc. that would otherwise clutter up the font object. You don’t have to create a Info object yourself, Font makes one when it is created.

Info validates any value set for a Info <BaseInfo> item, but does not check if the data is sane (i.e., you can set valid but incorrect data).

Overview
BaseInfo.copy Copy this object into a new object of the same type.
BaseInfo.font The info’s parent font.
BaseInfo.interpolate Interpolate all pairs between minInfo and maxInfo.
BaseInfo.round Round the following attributes to integers:
BaseInfo.update Update this object with the values from otherInfo.
BaseInfo.naked Return the environment’s native object that has been wrapped by this object.
BaseInfo.changed Tell the environment that something has changed in the object.
Reference
class fontParts.base.BaseInfo(*args, **kwargs)[source]
Copy
BaseInfo.copy()

Copy this object into a new object of the same type. The returned object will not have a parent object.

Parents
BaseInfo.font

The info’s parent font.

Interpolation
BaseInfo.interpolate(factor, minInfo, maxInfo, round=True, suppressError=True)[source]

Interpolate all pairs between minInfo and maxInfo. The interpolation occurs on a 0 to 1.0 range where minInfo is located at 0 and maxInfo is located at 1.0.

factor is the interpolation value. It may be less than 0 and greater than 1.0. It may be a number (integer, float) or a tuple of two numbers. If it is a tuple, the first number indicates the x factor and the second number indicates the y factor.

round indicates if the result should be rounded to integers.

suppressError indicates if incompatible data should be ignored or if an error should be raised when such incompatibilities are found.

Normalization
BaseInfo.round()[source]

Round the following attributes to integers:

  • unitsPerEm
  • descender
  • xHeight
  • capHeight
  • ascender
  • openTypeHeadLowestRecPPEM
  • openTypeHheaAscender
  • openTypeHheaDescender
  • openTypeHheaLineGap
  • openTypeHheaCaretSlopeRise
  • openTypeHheaCaretSlopeRun
  • openTypeHheaCaretOffset
  • openTypeOS2WidthClass
  • openTypeOS2WeightClass
  • openTypeOS2TypoAscender
  • openTypeOS2TypoDescender
  • openTypeOS2TypoLineGap
  • openTypeOS2WinAscent
  • openTypeOS2WinDescent
  • openTypeOS2SubscriptXSize
  • openTypeOS2SubscriptYSize
  • openTypeOS2SubscriptXOffset
  • openTypeOS2SubscriptYOffset
  • openTypeOS2SuperscriptXSize
  • openTypeOS2SuperscriptYSize
  • openTypeOS2SuperscriptXOffset
  • openTypeOS2SuperscriptYOffset
  • openTypeOS2StrikeoutSize
  • openTypeOS2StrikeoutPosition
  • openTypeVheaVertTypoAscender
  • openTypeVheaVertTypoDescender
  • openTypeVheaVertTypoLineGap
  • openTypeVheaCaretSlopeRise
  • openTypeVheaCaretSlopeRun
  • openTypeVheaCaretOffset
  • postscriptSlantAngle
  • postscriptUnderlineThickness
  • postscriptUnderlinePosition
  • postscriptBlueValues
  • postscriptOtherBlues
  • postscriptFamilyBlues
  • postscriptFamilyOtherBlues
  • postscriptStemSnapH
  • postscriptStemSnapV
  • postscriptBlueFuzz
  • postscriptBlueShift
  • postscriptDefaultWidthX
  • postscriptNominalWidthX
Update
BaseInfo.update(other)[source]

Update this object with the values from otherInfo.

Environment
BaseInfo.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BaseInfo.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()

Groups

Description

Groups are collections of glyphs. Groups are used for many things, from OpenType features, kerning, or just keeping track of a collection of related glyphs. The name of the group must be at least one character, with no limit to the maximum length for the name, nor any limit on the characters used in a name. With the exception of the kerning groups defined below, glyphs may be in more than one group and they may appear within the same group more than once. Glyphs in the groups are not required to be in the font.

Groups behave like a Python dictionary. Anything you can do with a dictionary in Python, you can do with Groups.

font = CurrentFont()
for name, members in font.groups.items():
    print(name)
    print(members)

It is important to understand that any changes to the returned group contents will not be reflected in the groups object. This means that the following will not update the font’s groups:

group = list(font.groups["myGroup"])
group.remove("A")

If one wants to make a change to the group contents, one should do the following instead:

group = list(font.groups["myGroup"])
group.remove("A")
font.groups["myGroup"] = group
Kerning Groups

Groups may be used as members of kerning pairs in BaseKerning. These groups are divided into two types: groups that appear on the first side of a kerning pair and groups that appear on the second side of a kerning pair.

Kerning groups must begin with standard prefixes. The prefix for groups intended for use in the first side of a kerning pair is public.kern1.. The prefix for groups intended for use in the second side of a kerning pair is public.kern2.. One or more characters must follow the prefix.

Kerning groups must strictly adhere to the following rules:

  1. Kerning group names must begin with the appropriate prefix.
  2. Only kerning groups are allowed to use the kerning group prefixes in their names.
  3. Kerning groups are not required to appear in the kerning pairs.
  4. Glyphs must not appear in more than one kerning group per side.

These rules come from the Unified Font Object, more information on implementation details for application developers can be found there.

Overview
BaseGroups.copy Copy this object into a new object of the same type.
BaseGroups.font The Groups’ parent BaseFont.
BaseGroups.__contains__ Tests to see if a group name is in the Groups.
BaseGroups.__delitem__ Removes groupName from the Groups.
BaseGroups.__getitem__ Returns the contents of the named group.
BaseGroups.__iter__ Iterates through the Groups, giving the key for each iteration.
BaseGroups.__len__ Returns the number of groups in Groups as an int..
BaseGroups.__setitem__ Sets the groupName to the list of glyphNames.
BaseGroups.clear Removes all group information from Groups, resetting the Groups to an empty dictionary.
BaseGroups.get Returns the contents of the named group.
BaseGroups.items Returns a list of tuple of each group name and group members.
BaseGroups.keys Returns a list of all the group names in Groups.
BaseGroups.pop Removes the groupName from the Groups and returns the list of group members.
BaseGroups.update Updates the Groups based on otherGroups.
BaseGroups.values Returns a list of each named group’s members.
BaseGroups.findGlyph Returns a list of the group or groups associated with glyphName.
BaseGroups.naked Return the environment’s native object that has been wrapped by this object.
BaseGroups.changed Tell the environment that something has changed in the object.
Reference
class fontParts.base.BaseGroups(*args, **kwargs)[source]

A Groups object. This object normally created as part of a BaseFont. An orphan Groups object can be created like this:

>>> groups = RGroups()

This object behaves like a Python dictionary. Most of the dictionary functionality comes from BaseDict, look at that object for the required environment implementation details.

Groups uses normalizers.normalizeGroupKey to normalize the key of the dict, and normalizers.normalizeGroupValue to normalize the value of the dict.

Copy
BaseGroups.copy()

Copy this object into a new object of the same type. The returned object will not have a parent object.

Parents
Dictionary
BaseGroups.__contains__(groupName)[source]

Tests to see if a group name is in the Groups. groupName will be a String. This returns a bool indicating if the groupName is in the Groups.

>>> "myGroup" in font.groups
True
BaseGroups.__delitem__(groupName)[source]

Removes groupName from the Groups. groupName is a String.:

>>> del font.groups["myGroup"]
BaseGroups.__getitem__(groupName)[source]

Returns the contents of the named group. groupName is a String. The returned value will be a Immutable List of the group contents.:

>>> font.groups["myGroup"]
("A", "B", "C")

It is important to understand that any changes to the returned group contents will not be reflected in the Groups object. If one wants to make a change to the group contents, one should do the following:

>>> group = font.groups["myGroup"]
>>> group.remove("A")
>>> font.groups["myGroup"] = group
BaseGroups.__iter__()[source]

Iterates through the Groups, giving the key for each iteration. The order that the Groups will iterate though is not fixed nor is it ordered.:

>>> for groupName in font.groups:
>>>     print groupName
"myGroup"
"myGroup3"
"myGroup2"
BaseGroups.__len__()[source]

Returns the number of groups in Groups as an int.:

>>> len(font.groups)
5
BaseGroups.__setitem__(groupName, glyphNames)[source]

Sets the groupName to the list of glyphNames. groupName is the group name as a String and glyphNames is a list of glyph names as String.

>>> font.groups["myGroup"] = ["A", "B", "C"]
BaseGroups.clear()[source]

Removes all group information from Groups, resetting the Groups to an empty dictionary.

>>> font.groups.clear()
BaseGroups.get(groupName, default=None)[source]

Returns the contents of the named group. groupName is a String, and the returned values will either be Immutable List of group contents or None if no group was found.

>>> font.groups["myGroup"]
("A", "B", "C")

It is important to understand that any changes to the returned group contents will not be reflected in the Groups object. If one wants to make a change to the group contents, one should do the following:

>>> group = font.groups["myGroup"]
>>> group.remove("A")
>>> font.groups["myGroup"] = group
BaseGroups.items()[source]

Returns a list of tuple of each group name and group members. Group names are String and group members are a Immutable List of String. The initial list will be unordered.

>>> font.groups.items()
[("myGroup", ("A", "B", "C"), ("myGroup2", ("D", "E", "F"))]
BaseGroups.keys()[source]

Returns a list of all the group names in Groups. This list will be unordered.:

>>> font.groups.keys()
["myGroup4", "myGroup1", "myGroup5"]
BaseGroups.pop(groupName, default=None)[source]

Removes the groupName from the Groups and returns the list of group members. If no group is found, default is returned. groupName is a String. This must return either default or a Immutable List of glyph names as String.

>>> font.groups.pop("myGroup")
("A", "B", "C")
BaseGroups.update(otherGroups)[source]

Updates the Groups based on otherGroups. otherGroups* is a dict of groups information. If a group from otherGroups is in Groups, the group members will be replaced by the group members from otherGroups. If a group from otherGroups is not in the Groups, it is added to the Groups. If Groups contain a group name that is not in otherGroups*, it is not changed.

>>> font.groups.update(newGroups)
BaseGroups.values()[source]

Returns a list of each named group’s members. This will be a list of lists, the group members will be a Immutable List of String. The initial list will be unordered.

>>> font.groups.items()
[("A", "B", "C"), ("D", "E", "F")]
Queries
BaseGroups.findGlyph(glyphName)[source]

Returns a list of the group or groups associated with glyphName. glyphName will be an String. If no group is found to contain glyphName an empty list will be returned.

>>> font.groups.findGlyph("A")
["A_accented"]
Environment
BaseGroups.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BaseGroups.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()

Kerning

Description

Kerning groups must begin with standard prefixes. The prefix for groups intended for use in the first side of a kerning pair is public.kern1.. The prefix for groups intended for use in the second side of a kerning pair is public.kern2.. One or more characters must follow the prefix.

Kerning groups must strictly adhere to the following rules:

  1. Kerning group names must begin with the appropriate prefix.
  2. Only kerning groups are allowed to use the kerning group prefixes in their names.
  3. Kerning groups are not required to appear in the kerning pairs.
  4. Glyphs must not appear in more than one kerning group per side.

These rules come from the Unified Font Object, more information on implementation details for application developers can be found there.

Overview
Copy
BaseKerning.copy Copy this object into a new object of the same type.
Parents
BaseKerning.font The Kerning’s parent BaseFont.
Dictionary
BaseKerning.__len__ Returns the number of pairs in Kerning as an int..
BaseKerning.keys Returns a list of all the pairs in Kerning.
BaseKerning.items Returns a list of tuples of each pair and value.
BaseKerning.values Returns a list of each pair’s values, the values will be Integer/Floats.
BaseKerning.__contains__ Tests to see if a pair is in the Kerning.
BaseKerning.__setitem__ Sets the pair to the list of value.
BaseKerning.__getitem__ Returns the kerning value of the pair.
BaseKerning.get Returns the value for the kerning pair.
BaseKerning.find Returns the value for the kerning pair - even if the pair only exists implicitly (one or both sides may be members of a kerning group).
BaseKerning.__delitem__ Removes pair from the Kerning.
BaseKerning.pop Removes the pair from the Kerning and returns the value as an int.
BaseKerning.__iter__ Iterates through the Kerning, giving the pair for each iteration.
BaseKerning.update Updates the Kerning based on otherKerning.
BaseKerning.clear Removes all information from Kerning, resetting the Kerning to an empty dictionary.
Transformations
BaseKerning.scaleBy Scales all kerning values by factor.
Interpolation
BaseKerning.interpolate Interpolates all pairs between two BaseKerning objects:
Normalization
BaseKerning.round Rounds the kerning values to increments of multiple, which will be an int.
Environment
BaseKerning.naked Return the environment’s native object that has been wrapped by this object.
BaseKerning.changed Tell the environment that something has changed in the object.
Reference
class fontParts.base.BaseKerning(*args, **kwargs)[source]

A Kerning object. This object normally created as part of a BaseFont. An orphan Kerning object can be created like this:

>>> groups = RKerning()

This object behaves like a Python dictionary. Most of the dictionary functionality comes from BaseDict, look at that object for the required environment implementation details.

Kerning uses normalizers.normalizeKerningKey to normalize the key of the dict, and normalizers.normalizeKerningValue to normalize the the value of the dict.

Copy
BaseKerning.copy()

Copy this object into a new object of the same type. The returned object will not have a parent object.

Parents
BaseKerning.font

The Kerning’s parent BaseFont.

Dictionary
BaseKerning.__len__()[source]

Returns the number of pairs in Kerning as an int.:

>>> len(font.kerning)
5
BaseKerning.keys()[source]

Returns a list of all the pairs in Kerning. This list will be unordered.:

>>> font.kerning.keys()
[("A", "Y"), ("A", "V"), ("A", "W")]
BaseKerning.items()[source]

Returns a list of tuples of each pair and value. Pairs are a tuple of two Strings and values are Integer/Float.

The initial list will be unordered.

>>> font.kerning.items()
[(("A", "V"), -30), (("A", "W"), -10)]
BaseKerning.values()[source]

Returns a list of each pair’s values, the values will be Integer/Floats.

The list will be unordered.

>>> font.kerning.items()
[-20, -15, 5, 3.5]
BaseKerning.__contains__(pair)[source]

Tests to see if a pair is in the Kerning. pair will be a tuple of two Strings.

This returns a bool indicating if the pair is in the Kerning.

>>> ("A", "V") in font.kerning
True
BaseKerning.__setitem__(pair, value)[source]

Sets the pair to the list of value. pair is the pair as a tuple of two Strings and value

is a Integer/Float.

>>> font.kerning[("A", "V")] = -20
>>> font.kerning[("A", "W")] = -10.5
BaseKerning.__getitem__(pair)[source]

Returns the kerning value of the pair. pair is a tuple of two Strings.

The returned value will be a Integer/Float.:

>>> font.kerning[("A", "V")]
-15

It is important to understand that any changes to the returned value will not be reflected in the Kerning object. If one wants to make a change to the value, one should do the following:

>>> value = font.kerning[("A", "V")]
>>> value += 10
>>> font.kerning[("A", "V")] = value
BaseKerning.get(pair, default=None)[source]

Returns the value for the kerning pair. pair is a tuple of two Strings, and the returned values will either be Integer/Float or None if no pair was found.

>>> font.kerning[("A", "V")]
-25

It is important to understand that any changes to the returned value will not be reflected in the Kerning object. If one wants to make a change to the value, one should do the following:

>>> value = font.kerning[("A", "V")]
>>> value += 10
>>> font.kerning[("A", "V")] = value
BaseKerning.find(pair, default=None)[source]

Returns the value for the kerning pair - even if the pair only exists implicitly (one or both sides may be members of a kerning group).

pair is a tuple of two Strings, and the returned values will either be Integer/Float or None if no pair was found.

>>> font.kerning[("A", "V")]
-25
BaseKerning.__delitem__(pair)[source]

Removes pair from the Kerning. pair is a tuple of two Strings.:

>>> del font.kerning[("A","V")]
BaseKerning.pop(pair, default=None)[source]

Removes the pair from the Kerning and returns the value as an int. If no pair is found, default is returned. pair is a tuple of two Strings. This must return either

default or a Integer/Float.

>>> font.kerning.pop(("A", "V"))
-20
>>> font.kerning.pop(("A", "W"))
-10.5
BaseKerning.__iter__()[source]

Iterates through the Kerning, giving the pair for each iteration. The order that the Kerning will iterate though is not fixed nor is it ordered.:

>>> for pair in font.kerning:
>>>     print pair
("A", "Y")
("A", "V")
("A", "W")
BaseKerning.update(otherKerning)[source]

Updates the Kerning based on otherKerning. otherKerning is a dict of kerning information. If a pair from otherKerning is in Kerning, the pair value will be replaced by the value from otherKerning. If a pair from otherKerning is not in the Kerning, it is added to the pairs. If Kerning contains a pair that is not in otherKerning, it is not changed.

>>> font.kerning.update(newKerning)
BaseKerning.clear()[source]

Removes all information from Kerning, resetting the Kerning to an empty dictionary.

>>> font.kerning.clear()
Transformations
BaseKerning.scaleBy(factor)[source]

Scales all kerning values by factor. factor will be an Integer/Float, tuple or list. The first value of the factor will be used to scale the kerning values.

>>> myKerning.scaleBy(2)
>>> myKerning.scaleBy((2,3))
Interpolation
BaseKerning.interpolate(factor, minKerning, maxKerning, round=True, suppressError=True)[source]

Interpolates all pairs between two BaseKerning objects:

>>> myKerning.interpolate(kerningOne, kerningTwo)

minKerning and maxKerning. The interpolation occurs on a 0 to 1.0 range where minKerning is located at 0 and maxKerning is located at 1.0. The kerning data is replaced by the interpolated kerning.

  • factor is the interpolation value. It may be less than 0 and greater than 1.0. It may be an Integer/Float, tuple or list. If it is a tuple or list, the first number indicates the x factor and the second number indicates the y factor.
  • round is a bool indicating if the result should be rounded to ints. The default behavior is to round interpolated kerning.
  • suppressError is a bool indicating if incompatible data should be ignored or if an error should be raised when such incompatibilities are found. The default behavior is to ignore incompatible data.
Normalization
BaseKerning.round(multiple=1)[source]

Rounds the kerning values to increments of multiple, which will be an int.

The default behavior is to round to increments of 1.

Environment
BaseKerning.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BaseKerning.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()

Features

Description

Features is text in the Adobe Font Development Kit for OpenType .fea syntax that describes the OpenType features of your font. The OpenType Cookbook is a great place to start learning how to write features. Your features must be self-contained; for example, any glyph or mark classes must be defined within the file. No assumption should be made about the validity of the syntax, and FontParts does not check the validity of the syntax.

Note

It is important to note that the features file may contain data that is a duplicate of or data that is in conflict with the data in BaseKerning, BaseGroups, and BaseInfo. Synchronization is up to the user and application developers.

font = CurrentFont()
print(font.features)
Overview
BaseFeatures.copy Copy this object into a new object of the same type.
BaseFeatures.font The features’ parent BaseFont.
BaseFeatures.text The .fea formated text representing the features.It must be a String..
Reference
class fontParts.base.BaseFeatures(*args, **kwargs)[source]
Copy
BaseFeatures.copy()

Copy this object into a new object of the same type. The returned object will not have a parent object.

Parents
BaseFeatures.font

The features’ parent BaseFont.

Attributes
BaseFeatures.text

The .fea formated text representing the features. It must be a String.

Lib

Overview
BaseLib.copy Copy this object into a new object of the same type.
BaseLib.glyph The lib’s parent glyph.
BaseLib.font The lib’s parent font.
BaseLib.__len__ Returns the number of keys in Lib as an int..
BaseLib.keys Returns a list of all the key names in Lib.
BaseLib.items Returns a list of tuple of each key name and key items.
BaseLib.values Returns a list of each named key’s members.
BaseLib.__contains__ Tests to see if a lib name is in the Lib.
BaseLib.__setitem__ Sets the key to the list of items.
BaseLib.__getitem__ Returns the contents of the named lib.
BaseLib.get Returns the contents of the named key.
BaseLib.__delitem__ Removes key from the Lib.
BaseLib.pop Removes the key from the Lib and returns the list of key members.
BaseLib.__iter__ Iterates through the Lib, giving the key for each iteration.
BaseLib.update Updates the Lib based on otherLib.
BaseLib.clear Removes all keys from Lib, resetting the Lib to an empty dictionary.
BaseLib.naked Return the environment’s native object that has been wrapped by this object.
BaseLib.changed Tell the environment that something has changed in the object.
Reference
class fontParts.base.BaseLib(*args, **kwargs)[source]

A Lib object. This object normally created as part of a BaseFont. An orphan Lib object can be created like this:

>>> lib = RLib()

This object behaves like a Python dictionary. Most of the dictionary functionality comes from BaseDict, look at that object for the required environment implementation details.

Lib uses normalizers.normalizeLibKey to normalize the key of the dict, and normalizers.normalizeLibValue to normalize the value of the dict.

Copy
BaseLib.copy()

Copy this object into a new object of the same type. The returned object will not have a parent object.

Parents
BaseLib.glyph

The lib’s parent glyph.

BaseLib.font

The lib’s parent font.

Dictionary
BaseLib.__len__()[source]

Returns the number of keys in Lib as an int.:

>>> len(font.lib)
5
BaseLib.keys()[source]

Returns a list of all the key names in Lib. This list will be unordered.:

>>> font.lib.keys()
["public.glyphOrder", "org.robofab.scripts.SomeData",
 "public.postscriptNames"]
BaseLib.items()[source]

Returns a list of tuple of each key name and key items. Keys are String and key members are a list of String. The initial list will be unordered.

>>> font.lib.items()
[("public.glyphOrder", ["A", "B", "C"]),
 ("public.postscriptNames", {'be': 'uni0431', 'ze': 'uni0437'})]
BaseLib.values()[source]

Returns a list of each named key’s members. This will be a list of lists, the key members will be a list of String. The initial list will be unordered.

>>> font.lib.items()
[["A", "B", "C"], {'be': 'uni0431', 'ze': 'uni0437'}]
BaseLib.__contains__(key)[source]

Tests to see if a lib name is in the Lib. key will be a String. This returns a bool indicating if the key is in the Lib.

>>> "public.glyphOrder" in font.lib
True
BaseLib.__setitem__(key, items)[source]

Sets the key to the list of items. key is the lib name as a String and items is a list of items as String.

>>> font.lib["public.glyphOrder"] = ["A", "B", "C"]
BaseLib.__getitem__(key)[source]

Returns the contents of the named lib. key is a String. The returned value will be a list of the lib contents.:

>>> font.lib["public.glyphOrder"]
["A", "B", "C"]

It is important to understand that any changes to the returned lib contents will not be reflected in the Lib object. If one wants to make a change to the lib contents, one should do the following:

>>> lib = font.lib["public.glyphOrder"]
>>> lib.remove("A")
>>> font.lib["public.glyphOrder"] = lib
BaseLib.get(key, default=None)[source]

Returns the contents of the named key. key is a String, and the returned values will either be list of key contents or None if no key was found.

>>> font.lib["public.glyphOrder"]
["A", "B", "C"]

It is important to understand that any changes to the returned key contents will not be reflected in the Lib object. If one wants to make a change to the key contents, one should do the following:

>>> lib = font.lib["public.glyphOrder"]
>>> lib.remove("A")
>>> font.lib["public.glyphOrder"] = lib
BaseLib.__delitem__(key)[source]

Removes key from the Lib. key is a String.:

>>> del font.lib["public.glyphOrder"]
BaseLib.pop(key, default=None)[source]

Removes the key from the Lib and returns the list of key members. If no key is found, default is returned. key is a String. This must return either default or a list of items as String.

>>> font.lib.pop("public.glyphOrder")
["A", "B", "C"]
BaseLib.__iter__()[source]

Iterates through the Lib, giving the key for each iteration. The order that the Lib will iterate though is not fixed nor is it ordered.:

>>> for key in font.lib:
>>>     print key
"public.glyphOrder"
"org.robofab.scripts.SomeData"
"public.postscriptNames"
BaseLib.update(otherLib)[source]

Updates the Lib based on otherLib. otherLib* is a dict of keys. If a key from otherLib is in Lib the key members will be replaced by the key members from otherLib. If a key from otherLib is not in the Lib, it is added to the Lib. If Lib contain a key name that is not in otherLib*, it is not changed.

>>> font.lib.update(newLib)
BaseLib.clear()[source]

Removes all keys from Lib, resetting the Lib to an empty dictionary.

>>> font.lib.clear()
Environment
BaseLib.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BaseLib.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()

Layer

Note

This section needs to contain the following:

  • description of what this is
  • sub-object with basic usage
  • glyph interaction with basic usage
Overview
Copy
BaseLayer.copy Copy the layer into a new layer that does not belong to a font.
Parents
BaseLayer.font The layer’s parent BaseFont.
Attributes
BaseLayer.name The name of the layer.
BaseLayer.color The layer’s color.
Sub-Objects
BaseLayer.lib The layer’s BaseLib object.
BaseLayer.tempLib The layer’s BaseLib object.
Glyphs
BaseLayer.__len__ An int representing number of glyphs in the layer.
BaseLayer.keys Get a list of all glyphs in the layer.
BaseLayer.__iter__ Iterate through the BaseGlyph objects in the layer.
BaseLayer.__contains__ Test if the layer contains a glyph with name.
BaseLayer.__getitem__ Get the BaseGlyph with name from the layer.
BaseLayer.newGlyph Make a new glyph with name in the layer.
BaseLayer.insertGlyph Insert glyph into the layer.
BaseLayer.removeGlyph Remove the glyph with name from the layer.
Interpolation
BaseLayer.isCompatible Evaluate interpolation compatibility with other.
BaseLayer.interpolate Interpolate all possible data in the layer.
Normalization
BaseLayer.round Round all approriate data to integers.
BaseLayer.autoUnicodes Use heuristics to set Unicode values in all glyphs.
Environment
BaseLayer.naked Return the environment’s native object that has been wrapped by this object.
BaseLayer.changed Tell the environment that something has changed in the object.
Reference
class fontParts.base.BaseLayer(*args, **kwargs)[source]
Copy
BaseLayer.copy()[source]

Copy the layer into a new layer that does not belong to a font.

>>> copiedLayer = layer.copy()

This will copy:

  • name
  • color
  • lib
  • glyphs
Parents
BaseLayer.font

The layer’s parent BaseFont.

>>> font = layer.font
Attributes
BaseLayer.name

The name of the layer.

>>> layer.name
"foreground"
>>> layer.name = "top"
BaseLayer.color

The layer’s color.

>>> layer.color
None
>>> layer.color = (1, 0, 0, 0.5)
Sub-Objects
BaseLayer.lib

The layer’s BaseLib object.

>>> layer.lib["org.robofab.hello"]
"world"
Glyphs
BaseLayer.__len__()

An int representing number of glyphs in the layer.

>>> len(layer)
256
BaseLayer.keys()

Get a list of all glyphs in the layer.

>>> layer.keys()
["B", "C", "A"]

The order of the glyphs is undefined.

BaseLayer.__iter__()

Iterate through the BaseGlyph objects in the layer.

>>> for glyph in layer:
...     glyph.name
"A"
"B"
"C"
BaseLayer.__contains__(name)

Test if the layer contains a glyph with name.

>>> "A" in layer
True
BaseLayer.__getitem__(name)

Get the BaseGlyph with name from the layer.

>>> glyph = layer["A"]
BaseLayer.newGlyph(name, clear=True)

Make a new glyph with name in the layer.

>>> glyph = layer.newGlyph("A")

The newly created BaseGlyph will be returned.

If the glyph exists in the layer and clear is set to False, the existing glyph will be returned, otherwise the default behavior is to clear the exisiting glyph.

BaseLayer.insertGlyph(glyph, name=None)

Insert glyph into the layer.

>>> glyph = layer.insertGlyph(otherGlyph, name="A")

This method is deprecated. BaseFont.__setitem__ instead.

BaseLayer.removeGlyph(name)

Remove the glyph with name from the layer.

>>> layer.removeGlyph("A")

This method is deprecated. BaseFont.__delitem__ instead.

Interpolation
BaseLayer.isCompatible(other)[source]

Evaluate interpolation compatibility with other.

>>> compat, report = self.isCompatible(otherLayer)
>>> compat
False
>>> report
A
-
[Fatal] The glyphs do not contain the same number of contours.

This will return a bool indicating if the layer is compatible for interpolation with other and a String of compatibility notes.

BaseLayer.interpolate(factor, minLayer, maxLayer, round=True, suppressError=True)[source]

Interpolate all possible data in the layer.

>>> layer.interpolate(0.5, otherLayer1, otherLayer2)
>>> layer.interpolate((0.5, 2.0), otherLayer1, otherLayer2, round=False)

The interpolation occurs on a 0 to 1.0 range where minLayer is located at 0 and maxLayer is located at 1.0. factor is the interpolation value. It may be less than 0 and greater than 1.0. It may be a Integer/Float or a tuple of two Integer/Float. If it is a tuple, the first number indicates the x factor and the second number indicates the y factor. round indicates if the result should be rounded to integers. suppressError indicates if incompatible data should be ignored or if an error should be raised when such incompatibilities are found.

Normalization
BaseLayer.round()[source]

Round all approriate data to integers.

>>> layer.round()

This is the equivalent of calling the round method on:

  • all glyphs in the layer
BaseLayer.autoUnicodes()[source]

Use heuristics to set Unicode values in all glyphs.

>>> layer.autoUnicodes()

Environments will define their own heuristics for automatically determining values.

Environment
BaseLayer.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BaseLayer.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()

Glyph

BaseGlyph(*args, **kwargs) A glyph object.
BaseGlyph.addImage([path, data, scale, …]) Set the image in the glyph.
BaseGlyph.anchors An Immutable List of all anchors in the glyph.
BaseGlyph.appendAnchor([name, position, …]) Append an anchor to this glyph.
BaseGlyph.appendComponent([baseGlyph, …]) Append a component to this glyph.
BaseGlyph.appendContour(contour[, offset]) Append a contour containing the same data as contour to this glyph.
BaseGlyph.appendGlyph(other[, offset]) Append the data from other to new objects in this glyph.
BaseGlyph.appendGuideline([position, angle, …]) Append a guideline to this glyph.
BaseGlyph.area The area of the glyph as a Integer/Float or, in the case of empty glyphs None.
BaseGlyph.autoContourOrder() Automatically order the contours based on heuristics.
BaseGlyph.autoUnicodes() Use heuristics to set the Unicode values in the glyph.
BaseGlyph.bottomMargin The glyph’s bottom margin.
BaseGlyph.bounds The bounds of the glyph in the form (x minimum, y minimum, x maximum, y maximum) or, in the case of empty glyphs None.
BaseGlyph.box Deprecated Glyph.box
BaseGlyph.center([padding])
BaseGlyph.changed(*args, **kwargs) Tell the environment that something has changed in the object.
BaseGlyph.clear([contours, components, …]) Clear the glyph.
BaseGlyph.clearAnchors() Clear all anchors in the glyph.
BaseGlyph.clearComponents() Clear all components in the glyph.
BaseGlyph.clearContours() Clear all contours in the glyph.
BaseGlyph.clearGuidelines() Clear all guidelines in the glyph.
BaseGlyph.clearHGuides()
BaseGlyph.clearImage() Remove the image from the glyph.
BaseGlyph.clearVGuides()
BaseGlyph.compatibilityReporterClass alias of fontParts.base.compatibility.GlyphCompatibilityReporter
BaseGlyph.components An Immutable List of all components in the glyph.
BaseGlyph.contours An Immutable List of all contours in the glyph.
BaseGlyph.copy() Copy this glyph’s data into a new glyph object.
BaseGlyph.copyAttributes
BaseGlyph.copyClass
BaseGlyph.copyData(source) Subclasses may override this method.
BaseGlyph.correctDirection([trueType]) Correct the winding direction of the contours following the PostScript recommendations.
BaseGlyph.decompose() Decompose all components in the glyph to contours.
BaseGlyph.draw(pen[, contours, components]) Draw the glyph’s outline data (contours and components) to the given type-pen.
BaseGlyph.drawPoints(pen[, contours, components]) Draw the glyph’s outline data (contours and components) to the given type-pointpen.
BaseGlyph.dumpToGLIF([glyphFormatVersion]) This will return the glyph’s contents as a string in GLIF format.
BaseGlyph.font The glyph’s parent font.
BaseGlyph.fromMathGlyph(mathGlyph[, …]) Replaces the contents of this glyph with the contents of mathGlyph.
BaseGlyph.getAnchors()
BaseGlyph.getComponents()
BaseGlyph.getLayer(name) Get the type-glyph-layer with name in this glyph.
BaseGlyph.getParent()
BaseGlyph.getPen() Return a type-pen object for adding outline data to the glyph.
BaseGlyph.getPointPen() Return a type-pointpen object for adding outline data to the glyph.
BaseGlyph.guidelines An Immutable List of all guidelines in the glyph.
BaseGlyph.height The glyph’s height.
BaseGlyph.image The BaseImage for the glyph.
BaseGlyph.interpolate(factor, minGlyph, maxGlyph) Interpolate the contents of this glyph at location factor in a linear interpolation between minGlyph and maxGlyph.
BaseGlyph.isCompatible(other) Evaluate the interpolation compatibility of this glyph and other.
BaseGlyph.isEmpty() This will return type-bool indicating if there are contours and/or components in the glyph.
BaseGlyph.layer The glyph’s parent layer.
BaseGlyph.layers Immutable tuple of the glyph’s layers.
BaseGlyph.leftMargin The glyph’s left margin.
BaseGlyph.lib The BaseLib for the glyph.
BaseGlyph.loadFromGLIF(glifData) Reads glifData, in GLIF format, into this glyph.
BaseGlyph.mark Deprecated Mark color
BaseGlyph.markColor The glyph’s mark color.
BaseGlyph.move(*args, **kwargs)
BaseGlyph.moveBy(value) Move the object.
BaseGlyph.naked() Return the environment’s native object that has been wrapped by this object.
BaseGlyph.name The glyph’s name.
BaseGlyph.newLayer(name) Make a new layer with name in this glyph.
BaseGlyph.note The glyph’s note.
BaseGlyph.pointInside(point) Determine if point is in the black or white of the glyph.
BaseGlyph.raiseNotImplementedError() This exception needs to be raised frequently by the base classes.
BaseGlyph.readGlyphFromString(glifData)
BaseGlyph.removeAnchor(anchor) Remove anchor from the glyph.
BaseGlyph.removeComponent(component) Remove component from the glyph.
BaseGlyph.removeContour(contour) Remove contour from the glyph.
BaseGlyph.removeGuideline(guideline) Remove guideline from the glyph.
BaseGlyph.removeLayer(layer) Remove layer from this glyph.
BaseGlyph.removeOverlap() Perform a remove overlap operation on the contours.
BaseGlyph.rightMargin The glyph’s right margin.
BaseGlyph.rotate(*args, **kwargs)
BaseGlyph.rotateBy(value[, origin]) Rotate the object.
BaseGlyph.round() Round coordinates to the nearest integer.
BaseGlyph.scale(*args, **kwargs)
BaseGlyph.scaleBy(value[, origin, width, height]) Scale the object.
BaseGlyph.selected The object’s selection state.
BaseGlyph.selectedAnchors An Immutable List of anchors selected in the glyph.
BaseGlyph.selectedComponents An Immutable List of components selected in the glyph.
BaseGlyph.selectedContours An Immutable List of contours selected in the glyph.
BaseGlyph.selectedGuidelines An Immutable List of guidelines selected in the glyph.
BaseGlyph.setChanged()
BaseGlyph.setParent(parent)
BaseGlyph.skew(*args, **kwargs)
BaseGlyph.skewBy(value[, origin]) Skew the object.
BaseGlyph.tempLib The BaseLib for the glyph.
BaseGlyph.toMathGlyph([…]) Returns the glyph as an object that follows the MathGlyph protocol.
BaseGlyph.topMargin The glyph’s top margin.
BaseGlyph.transform(*args, **kwargs)
BaseGlyph.transformBy(matrix[, origin]) Transform the object.
BaseGlyph.translate(*args, **kwargs)
BaseGlyph.unicode The glyph’s primary unicode value.
BaseGlyph.unicodes The glyph’s unicode values in order from most to least important.
BaseGlyph.update()
BaseGlyph.width The glyph’s width.
BaseGlyph.writeGlyphToString([…])
Description

The Glyph object represents a glyph, its parts and associated data.

Glyph can be used as a list of Contour objects.

When a Glyph is obtained from a Font object, the font is the parent object of the glyph.

Overview
Copy
BaseGlyph.copy Copy this glyph’s data into a new glyph object.
Parents
BaseGlyph.layer The glyph’s parent layer.
BaseGlyph.font The glyph’s parent font.
Identification
BaseGlyph.name The glyph’s name.
BaseGlyph.unicodes The glyph’s unicode values in order from most to least important.
BaseGlyph.unicode The glyph’s primary unicode value.
Metrics
BaseGlyph.width The glyph’s width.
BaseGlyph.leftMargin The glyph’s left margin.
BaseGlyph.rightMargin The glyph’s right margin.
BaseGlyph.height The glyph’s height.
BaseGlyph.bottomMargin The glyph’s bottom margin.
BaseGlyph.topMargin The glyph’s top margin.
Queries
BaseGlyph.bounds The bounds of the glyph in the form (x minimum, y minimum, x maximum, y maximum) or, in the case of empty glyphs None.
BaseGlyph.pointInside Determine if point is in the black or white of the glyph.
Pens and Drawing
BaseGlyph.getPen Return a type-pen object for adding outline data to the glyph.
BaseGlyph.getPointPen Return a type-pointpen object for adding outline data to the glyph.
BaseGlyph.draw Draw the glyph’s outline data (contours and components) to the given type-pen.
BaseGlyph.drawPoints Draw the glyph’s outline data (contours and components) to the given type-pointpen.
Layers
BaseGlyph.layers Immutable tuple of the glyph’s layers.
BaseGlyph.getLayer Get the type-glyph-layer with name in this glyph.
BaseGlyph.newLayer Make a new layer with name in this glyph.
BaseGlyph.removeLayer Remove layer from this glyph.
Global
BaseGlyph.clear Clear the glyph.
BaseGlyph.appendGlyph Append the data from other to new objects in this glyph.
Contours
BaseGlyph.contours An Immutable List of all contours in the glyph.
BaseGlyph.__len__ The number of contours in the glyph.
BaseGlyph.__iter__ Iterate through all contours in the glyph.
BaseGlyph.__getitem__ Get the contour located at index from the glyph.
BaseGlyph.appendContour Append a contour containing the same data as contour to this glyph.
BaseGlyph.removeContour Remove contour from the glyph.
BaseGlyph.clearContours Clear all contours in the glyph.
BaseGlyph.removeOverlap Perform a remove overlap operation on the contours.
Components
BaseGlyph.components An Immutable List of all components in the glyph.
BaseGlyph.appendComponent Append a component to this glyph.
BaseGlyph.removeComponent Remove component from the glyph.
BaseGlyph.clearComponents Clear all components in the glyph.
BaseGlyph.decompose Decompose all components in the glyph to contours.
Anchors
BaseGlyph.anchors An Immutable List of all anchors in the glyph.
BaseGlyph.appendAnchor Append an anchor to this glyph.
BaseGlyph.removeAnchor Remove anchor from the glyph.
BaseGlyph.clearAnchors Clear all anchors in the glyph.
Guidelines
BaseGlyph.guidelines An Immutable List of all guidelines in the glyph.
BaseGlyph.appendGuideline Append a guideline to this glyph.
BaseGlyph.removeGuideline Remove guideline from the glyph.
BaseGlyph.clearGuidelines Clear all guidelines in the glyph.
Image
BaseGlyph.image The BaseImage for the glyph.
BaseGlyph.addImage Set the image in the glyph.
BaseGlyph.clearImage Remove the image from the glyph.
Note
BaseGlyph.note The glyph’s note.
BaseGlyph.markColor The glyph’s mark color.
Sub-Objects
BaseGlyph.lib The BaseLib for the glyph.
BaseGlyph.tempLib The BaseLib for the glyph.
Transformations
BaseGlyph.transformBy Transform the object.
BaseGlyph.moveBy Move the object.
BaseGlyph.scaleBy Scale the object.
BaseGlyph.rotateBy Rotate the object.
BaseGlyph.skewBy Skew the object.
Interpolation
BaseGlyph.isCompatible Evaluate the interpolation compatibility of this glyph and other.
BaseGlyph.interpolate Interpolate the contents of this glyph at location factor in a linear interpolation between minGlyph and maxGlyph.
Normalization
BaseGlyph.round Round coordinates to the nearest integer.
BaseGlyph.autoUnicodes Use heuristics to set the Unicode values in the glyph.
Environment
BaseGlyph.naked Return the environment’s native object that has been wrapped by this object.
BaseGlyph.changed Tell the environment that something has changed in the object.
Reference
class fontParts.base.BaseGlyph(*args, **kwargs)[source]

A glyph object. This object will almost always be created by retrieving it from a font object.

Copy
BaseGlyph.copy()[source]

Copy this glyph’s data into a new glyph object. This new glyph object will not belong to a font.

>>> copiedGlyph = glyph.copy()

This will copy:

  • name
  • unicodes
  • width
  • height
  • note
  • markColor
  • lib
  • contours
  • components
  • anchors
  • guidelines
  • image
Parents
BaseGlyph.layer

The glyph’s parent layer.

>>> layer = glyph.layer
BaseGlyph.font

The glyph’s parent font.

>>> font = glyph.font
Identification
BaseGlyph.name

The glyph’s name. This will be a String.

>>> glyph.name
"A"
>>> glyph.name = "A.alt"
BaseGlyph.unicodes

The glyph’s unicode values in order from most to least important.

>>> glyph.unicodes
(65,)
>>> glyph.unicodes = [65, 66]
>>> glyph.unicodes = []

The values in the returned tuple will be type-int. When setting you may use a list of type-int or type-hex values.

BaseGlyph.unicode

The glyph’s primary unicode value.

>>> glyph.unicode
65
>>> glyph.unicode = None

This is equivalent to glyph.unicodes[0]. Setting a glyph.unicode value will reset glyph.unicodes to a tuple containing that value or an empty tuple if value is None.

>>> glyph.unicodes
(65, 67)
>>> glyph.unicode = 65
>>> glyph.unicodes
(65,)
>>> glyph.unicode = None
>>> glyph.unicodes
()

The returned value will be an type-int or None. When setting you may send type-int or type-hex values or None.

Metrics
BaseGlyph.width

The glyph’s width.

>>> glyph.width
500
>>> glyph.width = 200

The value will be a Integer/Float.

BaseGlyph.leftMargin

The glyph’s left margin.

>>> glyph.leftMargin
35
>>> glyph.leftMargin = 45

The value will be a Integer/Float or None if the glyph has no outlines.

BaseGlyph.rightMargin

The glyph’s right margin.

>>> glyph.rightMargin
35
>>> glyph.rightMargin = 45

The value will be a Integer/Float or None if the glyph has no outlines.

BaseGlyph.height

The glyph’s height.

>>> glyph.height
500
>>> glyph.height = 200

The value will be a Integer/Float.

BaseGlyph.bottomMargin

The glyph’s bottom margin.

>>> glyph.bottomMargin
35
>>> glyph.bottomMargin = 45

The value will be a Integer/Float or None if the glyph has no outlines.

BaseGlyph.topMargin

The glyph’s top margin.

>>> glyph.topMargin
35
>>> glyph.topMargin = 45

The value will be a Integer/Float or None if the glyph has no outlines.

Queries
BaseGlyph.bounds

The bounds of the glyph in the form (x minimum, y minimum, x maximum, y maximum) or, in the case of empty glyphs None.

>>> glyph.bounds
(10, 30, 765, 643)
BaseGlyph.pointInside(point)[source]

Determine if point is in the black or white of the glyph.

>>> glyph.pointInside((40, 65))
True

point must be a Coordinate.

Pens and Drawing
BaseGlyph.getPen()[source]

Return a type-pen object for adding outline data to the glyph.

>>> pen = glyph.getPen()
BaseGlyph.getPointPen()[source]

Return a type-pointpen object for adding outline data to the glyph.

>>> pointPen = glyph.getPointPen()
BaseGlyph.draw(pen, contours=True, components=True)[source]

Draw the glyph’s outline data (contours and components) to the given type-pen.

>>> glyph.draw(pen)

If contours is set to False, the glyph’s contours will not be drawn.

>>> glyph.draw(pen, contours=False)

If components is set to False, the glyph’s components will not be drawn.

>>> glyph.draw(pen, components=False)
BaseGlyph.drawPoints(pen, contours=True, components=True)[source]

Draw the glyph’s outline data (contours and components) to the given type-pointpen.

>>> glyph.drawPoints(pointPen)

If contours is set to False, the glyph’s contours will not be drawn.

>>> glyph.drawPoints(pointPen, contours=False)

If components is set to False, the glyph’s components will not be drawn.

>>> glyph.drawPoints(pointPen, components=False)
Layers

Layer interaction in glyphs is very similar to the layer interaction in fonts. When you ask a glyph for a layer, you get a glyph layer in return. A glyph layer lets you do anything that you can do to a glyph. In fact a glyph layer is really just a glyph.

>>> bgdGlyph = glyph.newLayer('background')
>>> bgdGlyph.appendGlyph(glyph)
>>> bgdGlyph.appendGuideline((10, 10), 45)
BaseGlyph.layers

Immutable tuple of the glyph’s layers.

>>> glyphLayers = glyph.layers

This will return a tuple of all type-glyph-layer in the glyph.

BaseGlyph.getLayer(name)[source]

Get the type-glyph-layer with name in this glyph.

>>> glyphLayer = glyph.getLayer("foreground")
BaseGlyph.newLayer(name)[source]

Make a new layer with name in this glyph.

>>> glyphLayer = glyph.newLayer("background")

This will return the new type-glyph-layer. If the layer already exists in this glyph, it will be cleared.

BaseGlyph.removeLayer(layer)[source]

Remove layer from this glyph.

>>> glyph.removeLayer("background")

Layer can be a type-glyph-layer or a String representing a layer name.

Global
BaseGlyph.clear(contours=True, components=True, anchors=True, guidelines=True, image=True)[source]

Clear the glyph.

>>> glyph.clear()

This clears:

  • contours
  • components
  • anchors
  • guidelines
  • image

It’s possible to turn off the clearing of portions of the glyph with the listed arguments.

>>> glyph.clear(guidelines=False)
BaseGlyph.appendGlyph(other, offset=None)[source]

Append the data from other to new objects in this glyph.

>>> glyph.appendGlyph(otherGlyph)

This will append:

  • contours
  • components
  • anchors
  • guidelines

offset indicates the x and y shift values that should be applied to the appended data. It must be a Coordinate value or None. If None is given, the offset will be (0, 0).

>>> glyph.appendGlyph(otherGlyph, (100, 0))
Contours
BaseGlyph.contours

An Immutable List of all contours in the glyph.

>>> contours = glyph.contours

The list will contain BaseContour objects.

BaseGlyph.__len__()[source]

The number of contours in the glyph.

>>> len(glyph)
2
BaseGlyph.__iter__()[source]

Iterate through all contours in the glyph.

>>> for contour in glyph:
...     contour.reverse()
BaseGlyph.__getitem__(index)[source]

Get the contour located at index from the glyph.

>>> contour = glyph[0]

The returned value will be a BaseContour object.

BaseGlyph.appendContour(contour, offset=None)[source]

Append a contour containing the same data as contour to this glyph.

>>> contour = glyph.appendContour(contour)

This will return a BaseContour object representing the new contour in the glyph. offset indicates the x and y shift values that should be applied to the appended data. It must be a Coordinate value or None. If None is given, the offset will be (0, 0).

>>> contour = glyph.appendContour(contour, (100, 0))
BaseGlyph.removeContour(contour)[source]

Remove contour from the glyph.

>>> glyph.removeContour(contour)

contour may be a BaseContour or an type-int representing a contour index.

BaseGlyph.clearContours()[source]

Clear all contours in the glyph.

>>> glyph.clearContours()
BaseGlyph.removeOverlap()[source]

Perform a remove overlap operation on the contours.

>>> glyph.removeOverlap()

The behavior of this may vary across environments.

Components
BaseGlyph.components

An Immutable List of all components in the glyph.

>>> components = glyph.components

The list will contain BaseComponent objects.

BaseGlyph.appendComponent(baseGlyph=None, offset=None, scale=None, component=None)[source]

Append a component to this glyph.

>>> component = glyph.appendComponent("A")

This will return a BaseComponent object representing the new component in the glyph. offset indicates the x and y shift values that should be applied to the appended component. It must be a Coordinate value or None. If None is given, the offset will be (0, 0).

>>> component = glyph.appendComponent("A", offset=(10, 20))

scale indicates the x and y scale values that should be applied to the appended component. It must be a type-scale value or None. If None is given, the scale will be (1.0, 1.0).

>>> component = glyph.appendComponent("A", scale=(1.0, 2.0))

component may be a BaseComponent object from which attribute values will be copied. If baseGlyph, offset or scale are specified as arguments, those values will be used instead of the values in the given component object.

BaseGlyph.removeComponent(component)[source]

Remove component from the glyph.

>>> glyph.removeComponent(component)

component may be a BaseComponent or an type-int representing a component index.

BaseGlyph.clearComponents()[source]

Clear all components in the glyph.

>>> glyph.clearComponents()
BaseGlyph.decompose()[source]

Decompose all components in the glyph to contours.

>>> glyph.decompose()
Anchors
BaseGlyph.anchors

An Immutable List of all anchors in the glyph.

>>> anchors = glyph.anchors

The list will contain BaseAnchor objects.

BaseGlyph.appendAnchor(name=None, position=None, color=None, anchor=None)[source]

Append an anchor to this glyph.

>>> anchor = glyph.appendAnchor("top", (10, 20))

This will return a BaseAnchor object representing the new anchor in the glyph. name indicated the name to be assigned to the anchor. It must be a String or None. position indicates the x and y location to be applied to the anchor. It must be a Coordinate value. color indicates the color to be applied to the anchor. It must be a Color or None.

>>> anchor = glyph.appendAnchor("top", (10, 20), color=(1, 0, 0, 1))

anchor may be a BaseAnchor object from which attribute values will be copied. If name, position or color are specified as arguments, those values will be used instead of the values in the given anchor object.

BaseGlyph.removeAnchor(anchor)[source]

Remove anchor from the glyph.

>>> glyph.removeAnchor(anchor)

anchor may be an BaseAnchor or an type-int representing an anchor index.

BaseGlyph.clearAnchors()[source]

Clear all anchors in the glyph.

>>> glyph.clearAnchors()
Guidelines
BaseGlyph.guidelines

An Immutable List of all guidelines in the glyph.

>>> guidelines = glyph.guidelines

The list will contain BaseGuideline objects.

BaseGlyph.appendGuideline(position=None, angle=None, name=None, color=None, guideline=None)[source]

Append a guideline to this glyph.

>>> guideline = glyph.appendGuideline((100, 0), 90)

This will return a BaseGuideline object representing the new guideline in the glyph. position indicates the x and y location to be used as the center point of the anchor. It must be a Coordinate value. angle indicates the angle of the guideline, in degrees. This must be a Integer/Float between 0 and 360. name indicates an name to be assigned to the guideline. It must be a String or None.

>>> guideline = glyph.appendGuideline((100, 0), 90, name="left")

color indicates the color to be applied to the guideline. It must be a Color or None.

>>> guideline = glyph.appendGuideline((100, 0), 90, color=(1, 0, 0, 1))

guideline may be a BaseGuideline object from which attribute values will be copied. If position, angle, name or color are specified as arguments, those values will be used instead of the values in the given guideline object.

BaseGlyph.removeGuideline(guideline)[source]

Remove guideline from the glyph.

>>> glyph.removeGuideline(guideline)

guideline may be a BaseGuideline or an type-int representing an guideline index.

BaseGlyph.clearGuidelines()[source]

Clear all guidelines in the glyph.

>>> glyph.clearGuidelines()
Image
BaseGlyph.image

The BaseImage for the glyph.

BaseGlyph.addImage(path=None, data=None, scale=None, position=None, color=None)[source]

Set the image in the glyph. This will return the assigned BaseImage. The image data can be defined via path to an image file:

>>> image = glyph.addImage(path="/path/to/my/image.png")

The image data can be defined with raw image data via data.

>>> image = glyph.addImage(data=someImageData)

If path and data are both provided, a FontPartsError will be raised. The supported image formats will vary across environments. Refer to BaseImage for complete details.

scale indicates the x and y scale values that should be applied to the image. It must be a type-scale value or None.

>>> image = glyph.addImage(path="/p/t/image.png", scale=(0.5, 1.0))

position indicates the x and y location of the lower left point of the image.

>>> image = glyph.addImage(path="/p/t/image.png", position=(10, 20))

color indicates the color to be applied to the image. It must be a Color or None.

>>> image = glyph.addImage(path="/p/t/image.png", color=(1, 0, 0, 0.5))
BaseGlyph.clearImage()[source]

Remove the image from the glyph.

>>> glyph.clearImage()
Note
BaseGlyph.note

The glyph’s note.

>>> glyph.note
"P.B. said this looks 'awesome.'"
>>> glyph.note = "P.B. said this looks 'AWESOME.'"

The value may be a String or None.

BaseGlyph.markColor

The glyph’s mark color.

>>> glyph.markColor
(1, 0, 0, 0.5)
>>> glyph.markColor = None

The value may be a Color or None.

Sub-Objects
BaseGlyph.lib

The BaseLib for the glyph.

>>> lib = glyph.lib
Transformations
BaseGlyph.transformBy(matrix, origin=None)

Transform the object.

>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0))
>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0), origin=(500, 500))

matrix must be a Transformation Matrix. origin defines the point at with the transformation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseGlyph.moveBy(value)

Move the object.

>>> obj.moveBy((10, 0))

value must be an iterable containing two Integer/Float values defining the x and y values to move the object by.

BaseGlyph.scaleBy(value, origin=None, width=False, height=False)[source]

Scale the object.

>>> obj.scaleBy(2.0)
>>> obj.scaleBy((0.5, 2.0), origin=(500, 500))

value must be an iterable containing two Integer/Float values defining the x and y values to scale the object by. origin defines the point at with the scale should originate. It must be a Coordinate or None. The default is (0, 0).

width indicates if the glyph’s width should be scaled. height indicates if the glyph’s height should be scaled.

The origin must not be specified when scaling the width or height.

BaseGlyph.rotateBy(value, origin=None)

Rotate the object.

>>> obj.rotateBy(45)
>>> obj.rotateBy(45, origin=(500, 500))

value must be a Integer/Float values defining the angle to rotate the object by. origin defines the point at with the rotation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseGlyph.skewBy(value, origin=None)

Skew the object.

>>> obj.skewBy(11)
>>> obj.skewBy((25, 10), origin=(500, 500))

value must be rone of the following:

  • single Integer/Float indicating the value to skew the x direction by.
  • iterable cointaining type Integer/Float defining the values to skew the x and y directions by.

origin defines the point at with the skew should originate. It must be a Coordinate or None. The default is (0, 0).

Interpolation
BaseGlyph.isCompatible(other)[source]

Evaluate the interpolation compatibility of this glyph and other.

>>> compatible, report = self.isCompatible(otherGlyph)
>>> compatible
False

This will return a type-bool indicating if this glyph is compatible with other and a GlyphCompatibilityReporter containing a detailed report about compatibility errors.

BaseGlyph.interpolate(factor, minGlyph, maxGlyph, round=True, suppressError=True)[source]

Interpolate the contents of this glyph at location factor in a linear interpolation between minGlyph and maxGlyph.

>>> glyph.interpolate(0.5, otherGlyph1, otherGlyph2)

factor may be a Integer/Float or a tuple containing two Integer/Float values representing x and y factors.

>>> glyph.interpolate((0.5, 1.0), otherGlyph1, otherGlyph2)

minGlyph must be a BaseGlyph and will be located at 0.0 in the interpolation range. maxGlyph must be a BaseGlyph and will be located at 1.0 in the interpolation range. If round is True, the contents of the glyph will be rounded to integers after the interpolation is performed.

>>> glyph.interpolate(0.5, otherGlyph1, otherGlyph2, round=True)

This method assumes that minGlyph and maxGlyph are completely compatible with each other for interpolation. If not, any errors encountered will raise a FontPartsError. If suppressError is True, no exception will be raised and errors will be silently ignored.

Normalization
BaseGlyph.round()[source]

Round coordinates to the nearest integer.

>>> glyph.round()

This applies to the following:

  • width
  • height
  • contours
  • components
  • anchors
  • guidelines
BaseGlyph.autoUnicodes()[source]

Use heuristics to set the Unicode values in the glyph.

>>> glyph.autoUnicodes()

Environments will define their own heuristics for automatically determining values.

Environment
BaseGlyph.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BaseGlyph.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()

Contour

Description

A Contour is a single path of any number of points. A Glyph usually consists of a couple of contours, and this is the object that represents each one. The Contour object offers access to the outline matter in various ways. The parent of Contour is usually Glyph.

Overview
Copy
BaseContour.copy Copy this object into a new object of the same type.
Parents
BaseContour.glyph The contour’s parent BaseGlyph.
BaseContour.layer The contour’s parent layer.
BaseContour.font The contour’s parent font.
Identification
BaseContour.identifier The unique identifier for the object.
BaseContour.index The index of the contour within the parent glyph’s contours.
Winding Direction
BaseContour.clockwise Boolean indicating if the contour’s winding direction is clockwise.
BaseContour.reverse Reverse the direction of the contour.
Queries
BaseContour.bounds The bounds of the contour: (xMin, yMin, xMax, yMax) or None.
BaseContour.pointInside Determine if point is in the black or white of the contour.
Pens and Drawing
BaseContour.draw Draw the contour’s outline data to the given type-pen.
BaseContour.drawPoints Draw the contour’s outline data to the given type-point-pen.
Segments
BaseContour.segments
BaseContour.__len__
BaseContour.__iter__
BaseContour.__getitem__
BaseContour.appendSegment Append a segment to the contour.
BaseContour.insertSegment Insert a segment into the contour.
BaseContour.removeSegment Remove segment from the contour.
BaseContour.setStartSegment Set the first segment on the contour.
BaseContour.autoStartSegment Automatically calculate and set the first segment in this contour.
bPoints
BaseContour.bPoints
BaseContour.appendBPoint Append a bPoint to the contour.
BaseContour.insertBPoint Insert a bPoint at index in the contour.
Points
BaseContour.points
BaseContour.appendPoint Append a point to the contour.
BaseContour.insertPoint Insert a point into the contour.
BaseContour.removePoint Remove the point from the contour.
Transformations
BaseContour.transformBy Transform the object.
BaseContour.moveBy Move the object.
BaseContour.scaleBy Scale the object.
BaseContour.rotateBy Rotate the object.
BaseContour.skewBy Skew the object.
Normalization
BaseContour.round Round coordinates in all points to integers.
Environment
BaseContour.naked Return the environment’s native object that has been wrapped by this object.
BaseContour.changed Tell the environment that something has changed in the object.
Reference
class fontParts.base.BaseContour(*args, **kwargs)[source]
Copy
BaseContour.copy()

Copy this object into a new object of the same type. The returned object will not have a parent object.

Parents
BaseContour.glyph

The contour’s parent BaseGlyph.

BaseContour.layer

The contour’s parent layer.

BaseContour.font

The contour’s parent font.

Identification
BaseContour.identifier

The unique identifier for the object. This value will be an Identifier or a None. This attribute is read only.

>>> object.identifier
'ILHGJlygfds'

To request an identifier if it does not exist use object.getIdentifier()

BaseContour.index

The index of the contour within the parent glyph’s contours.

>>> contour.index
1
>>> contour.index = 0

The value will always be a type-int.

Winding Direction
BaseContour.clockwise

Boolean indicating if the contour’s winding direction is clockwise.

BaseContour.reverse()[source]

Reverse the direction of the contour.

Queries
BaseContour.bounds

The bounds of the contour: (xMin, yMin, xMax, yMax) or None.

BaseContour.pointInside(point)[source]

Determine if point is in the black or white of the contour.

>>> contour.pointInside((40, 65))
True

point must be a Coordinate.

Pens and Drawing
BaseContour.draw(pen)[source]

Draw the contour’s outline data to the given type-pen.

>>> contour.draw(pen)
BaseContour.drawPoints(pen)[source]

Draw the contour’s outline data to the given type-point-pen.

>>> contour.drawPoints(pointPen)
Segments
BaseContour.segments
BaseContour.__len__()[source]
BaseContour.__iter__()[source]
BaseContour.__getitem__(index)[source]
BaseContour.appendSegment(type=None, points=None, smooth=False, segment=None)[source]

Append a segment to the contour.

BaseContour.insertSegment(index, type=None, points=None, smooth=False, segment=None)[source]

Insert a segment into the contour.

BaseContour.removeSegment(segment, preserveCurve=False)[source]

Remove segment from the contour. If preserveCurve is set to True an attempt will be made to preserve the shape of the curve if the environment supports that functionality.

BaseContour.setStartSegment(segment)[source]

Set the first segment on the contour. segment can be a segment object or an index.

BaseContour.autoStartSegment()[source]

Automatically calculate and set the first segment in this contour.

The behavior of this may vary accross environments.

bPoints
BaseContour.bPoints
BaseContour.appendBPoint(type=None, anchor=None, bcpIn=None, bcpOut=None, bPoint=None)[source]

Append a bPoint to the contour.

BaseContour.insertBPoint(index, type=None, anchor=None, bcpIn=None, bcpOut=None, bPoint=None)[source]

Insert a bPoint at index in the contour.

Points
BaseContour.points
BaseContour.appendPoint(position=None, type='line', smooth=False, name=None, identifier=None, point=None)[source]

Append a point to the contour.

BaseContour.insertPoint(index, position=None, type='line', smooth=False, name=None, identifier=None, point=None)[source]

Insert a point into the contour.

BaseContour.removePoint(point, preserveCurve=False)[source]

Remove the point from the contour. point can be a point object or an index. If preserveCurve is set to True an attempt will be made to preserve the shape of the curve if the environment supports that functionality.

Transformations
BaseContour.transformBy(matrix, origin=None)

Transform the object.

>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0))
>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0), origin=(500, 500))

matrix must be a Transformation Matrix. origin defines the point at with the transformation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseContour.moveBy(value)

Move the object.

>>> obj.moveBy((10, 0))

value must be an iterable containing two Integer/Float values defining the x and y values to move the object by.

BaseContour.scaleBy(value, origin=None)

Scale the object.

>>> obj.scaleBy(2.0)
>>> obj.scaleBy((0.5, 2.0), origin=(500, 500))

value must be an iterable containing two Integer/Float values defining the x and y values to scale the object by. origin defines the point at with the scale should originate. It must be a Coordinate or None. The default is (0, 0).

BaseContour.rotateBy(value, origin=None)

Rotate the object.

>>> obj.rotateBy(45)
>>> obj.rotateBy(45, origin=(500, 500))

value must be a Integer/Float values defining the angle to rotate the object by. origin defines the point at with the rotation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseContour.skewBy(value, origin=None)

Skew the object.

>>> obj.skewBy(11)
>>> obj.skewBy((25, 10), origin=(500, 500))

value must be rone of the following:

  • single Integer/Float indicating the value to skew the x direction by.
  • iterable cointaining type Integer/Float defining the values to skew the x and y directions by.

origin defines the point at with the skew should originate. It must be a Coordinate or None. The default is (0, 0).

Normalization
BaseContour.round()[source]

Round coordinates in all points to integers.

Environment
BaseContour.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BaseContour.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()

Segment

Description

A Contour object is a list of segments. A Segment is a list of points with some special attributes and methods.

Overview
Parents
BaseSegment.contour The segment’s parent contour.
BaseSegment.glyph The segment’s parent glyph.
BaseSegment.layer The segment’s parent layer.
BaseSegment.font The segment’s parent font.
Identification
BaseSegment.index The index of the segment within the ordered list of the parent contour’s segments.
Attributes
BaseSegment.type The segment type.
BaseSegment.smooth Boolean indicating if the segment is smooth or not.
Points
BaseSegment.points A list of points in the segment.
BaseSegment.onCurve The on curve point in the segment.
BaseSegment.offCurve The off curve points in the segment.
Transformations
BaseSegment.transformBy Transform the object.
BaseSegment.moveBy Move the object.
BaseSegment.scaleBy Scale the object.
BaseSegment.rotateBy Rotate the object.
BaseSegment.skewBy Skew the object.
Normalization
BaseSegment.round Round coordinates in all points.
Environment
BaseSegment.naked Return the environment’s native object that has been wrapped by this object.
BaseSegment.changed Tell the environment that something has changed in the object.
Reference
class fontParts.base.BaseSegment(*args, **kwargs)[source]
Parents
BaseSegment.contour

The segment’s parent contour.

BaseSegment.glyph

The segment’s parent glyph.

BaseSegment.layer

The segment’s parent layer.

BaseSegment.font

The segment’s parent font.

Identification
BaseSegment.index

The index of the segment within the ordered list of the parent contour’s segments.

Attributes
BaseSegment.type

The segment type. The possible types are move, line, curve, qcurve.

BaseSegment.smooth

Boolean indicating if the segment is smooth or not.

Points
BaseSegment.points

A list of points in the segment.

BaseSegment.onCurve

The on curve point in the segment.

BaseSegment.offCurve

The off curve points in the segment.

Transformations
BaseSegment.transformBy(matrix, origin=None)

Transform the object.

>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0))
>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0), origin=(500, 500))

matrix must be a Transformation Matrix. origin defines the point at with the transformation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseSegment.moveBy(value)

Move the object.

>>> obj.moveBy((10, 0))

value must be an iterable containing two Integer/Float values defining the x and y values to move the object by.

BaseSegment.scaleBy(value, origin=None)

Scale the object.

>>> obj.scaleBy(2.0)
>>> obj.scaleBy((0.5, 2.0), origin=(500, 500))

value must be an iterable containing two Integer/Float values defining the x and y values to scale the object by. origin defines the point at with the scale should originate. It must be a Coordinate or None. The default is (0, 0).

BaseSegment.rotateBy(value, origin=None)

Rotate the object.

>>> obj.rotateBy(45)
>>> obj.rotateBy(45, origin=(500, 500))

value must be a Integer/Float values defining the angle to rotate the object by. origin defines the point at with the rotation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseSegment.skewBy(value, origin=None)

Skew the object.

>>> obj.skewBy(11)
>>> obj.skewBy((25, 10), origin=(500, 500))

value must be rone of the following:

  • single Integer/Float indicating the value to skew the x direction by.
  • iterable cointaining type Integer/Float defining the values to skew the x and y directions by.

origin defines the point at with the skew should originate. It must be a Coordinate or None. The default is (0, 0).

Normalization
BaseSegment.round()[source]

Round coordinates in all points.

Environment
BaseSegment.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BaseSegment.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()

bPoint

Description

The bPoint is a point object which mimics the old “Bezier Point” from RoboFog. It has attributes for bcpIn, anchor, bcpOut and type. The coordinates in bcpIn and bcpOut are relative to the position of the anchor. For instance, if the bcpIn is 20 units to the left of the anchor, its coordinates would be (-20,0), regardless of the coordinates of the anchor itself. Also: bcpIn will be (0,0) when it is “on top of the anchor”, i.e. when there is no bcp it will still have a value. The parent of a bPoint is usually a Contour.

Overview
Parents
BaseBPoint.contour The bPoint’s parent contour.
BaseBPoint.glyph The bPoint’s parent glyph.
BaseBPoint.layer The bPoint’s parent layer.
BaseBPoint.font The bPoint’s parent font.
Identification
BaseBPoint.index The index of the bPoint within the ordered list of the parent contour’s bPoints.
Attributes
BaseBPoint.type The bPoint type.
Points
BaseBPoint.anchor The anchor point.
BaseBPoint.bcpIn The incoming off curve.
BaseBPoint.bcpOut The outgoing off curve.
Transformations
BaseBPoint.transformBy Transform the object.
BaseBPoint.moveBy Move the object.
BaseBPoint.scaleBy Scale the object.
BaseBPoint.rotateBy Rotate the object.
BaseBPoint.skewBy Skew the object.
Normalization
BaseBPoint.round Round coordinates.
Environment
BaseBPoint.naked Return the environment’s native object that has been wrapped by this object.
BaseBPoint.changed Tell the environment that something has changed in the object.
Reference
class fontParts.base.BaseBPoint(*args, **kwargs)[source]
Parents
BaseBPoint.contour

The bPoint’s parent contour.

BaseBPoint.glyph

The bPoint’s parent glyph.

BaseBPoint.layer

The bPoint’s parent layer.

BaseBPoint.font

The bPoint’s parent font.

Identification
BaseBPoint.index

The index of the bPoint within the ordered list of the parent contour’s bPoints. None if the bPoint does not belong to a contour.

Attributes
BaseBPoint.type

The bPoint type.

Points
BaseBPoint.anchor

The anchor point.

BaseBPoint.bcpIn

The incoming off curve.

BaseBPoint.bcpOut

The outgoing off curve.

Transformations
BaseBPoint.transformBy(matrix, origin=None)

Transform the object.

>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0))
>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0), origin=(500, 500))

matrix must be a Transformation Matrix. origin defines the point at with the transformation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseBPoint.moveBy(value)

Move the object.

>>> obj.moveBy((10, 0))

value must be an iterable containing two Integer/Float values defining the x and y values to move the object by.

BaseBPoint.scaleBy(value, origin=None)

Scale the object.

>>> obj.scaleBy(2.0)
>>> obj.scaleBy((0.5, 2.0), origin=(500, 500))

value must be an iterable containing two Integer/Float values defining the x and y values to scale the object by. origin defines the point at with the scale should originate. It must be a Coordinate or None. The default is (0, 0).

BaseBPoint.rotateBy(value, origin=None)

Rotate the object.

>>> obj.rotateBy(45)
>>> obj.rotateBy(45, origin=(500, 500))

value must be a Integer/Float values defining the angle to rotate the object by. origin defines the point at with the rotation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseBPoint.skewBy(value, origin=None)

Skew the object.

>>> obj.skewBy(11)
>>> obj.skewBy((25, 10), origin=(500, 500))

value must be rone of the following:

  • single Integer/Float indicating the value to skew the x direction by.
  • iterable cointaining type Integer/Float defining the values to skew the x and y directions by.

origin defines the point at with the skew should originate. It must be a Coordinate or None. The default is (0, 0).

Normalization
BaseBPoint.round()[source]

Round coordinates.

Environment
BaseBPoint.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BaseBPoint.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()

Point

Description

Point represents one single point with a particular coordinate in a contour. It is used to access off-curve and on-curve points alike. Its cousin BPoint also provides access to incoming and outgoing bcps. Point is exclusively only one single point.

glyph = CurrentGlyph()
for contour in glyph:
    for point in contour.points:
        print(point)
Overview
Copy
BasePoint.copy Copy this object into a new object of the same type.
Parents
BasePoint.contour The point’s parent BaseContour.
BasePoint.glyph The point’s parent BaseGlyph.
BasePoint.layer The point’s parent BaseLayer.
BasePoint.font The point’s parent BaseFont.
Identification
BasePoint.name The name of the point.
BasePoint.identifier The unique identifier for the object.
BasePoint.index The index of the point within the ordered list of the parent glyph’s point.
Coordinate
BasePoint.x The x coordinate of the point.
BasePoint.y The y coordinate of the point.
Type
BasePoint.type The point type defined with a String.
BasePoint.smooth A bool indicating if the point is smooth or not.
Transformations
BasePoint.transformBy Transform the object.
BasePoint.moveBy Move the object.
BasePoint.scaleBy Scale the object.
BasePoint.rotateBy Rotate the object.
BasePoint.skewBy Skew the object.
Normalization
BasePoint.round Round the point’s coordinate.
Environment
BasePoint.naked Return the environment’s native object that has been wrapped by this object.
BasePoint.changed Tell the environment that something has changed in the object.
Reference
Copy
BasePoint.copy()

Copy this object into a new object of the same type. The returned object will not have a parent object.

Parents
BasePoint.contour

The point’s parent BaseContour.

BasePoint.glyph

The point’s parent BaseGlyph.

BasePoint.layer

The point’s parent BaseLayer.

BasePoint.font

The point’s parent BaseFont.

Identification
BasePoint.name

The name of the point. This will be a String or None.

>>> point.name
'my point'
>>> point.name = None
BasePoint.identifier

The unique identifier for the object. This value will be an Identifier or a None. This attribute is read only.

>>> object.identifier
'ILHGJlygfds'

To request an identifier if it does not exist use object.getIdentifier()

BasePoint.index

The index of the point within the ordered list of the parent glyph’s point. This attribute is read only.

>>> point.index
0
Coordinate
BasePoint.x

The x coordinate of the point. It must be an Integer/Float.

>>> point.x
100
>>> point.x = 101
BasePoint.y

The y coordinate of the point. It must be an Integer/Float.

>>> point.y
100
>>> point.y = 101
Type
BasePoint.type

The point type defined with a String. The possible types are:

move An on-curve move to.
line An on-curve line to.
curve An on-curve cubic curve to.
qcurve An on-curve quadratic curve to.
offcurve An off-curve.
BasePoint.smooth

A bool indicating if the point is smooth or not.

>>> point.smooth
False
>>> point.smooth = True
Transformations
BasePoint.transformBy(matrix, origin=None)

Transform the object.

>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0))
>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0), origin=(500, 500))

matrix must be a Transformation Matrix. origin defines the point at with the transformation should originate. It must be a Coordinate or None. The default is (0, 0).

BasePoint.moveBy(value)

Move the object.

>>> obj.moveBy((10, 0))

value must be an iterable containing two Integer/Float values defining the x and y values to move the object by.

BasePoint.scaleBy(value, origin=None)

Scale the object.

>>> obj.scaleBy(2.0)
>>> obj.scaleBy((0.5, 2.0), origin=(500, 500))

value must be an iterable containing two Integer/Float values defining the x and y values to scale the object by. origin defines the point at with the scale should originate. It must be a Coordinate or None. The default is (0, 0).

BasePoint.rotateBy(value, origin=None)

Rotate the object.

>>> obj.rotateBy(45)
>>> obj.rotateBy(45, origin=(500, 500))

value must be a Integer/Float values defining the angle to rotate the object by. origin defines the point at with the rotation should originate. It must be a Coordinate or None. The default is (0, 0).

BasePoint.skewBy(value, origin=None)

Skew the object.

>>> obj.skewBy(11)
>>> obj.skewBy((25, 10), origin=(500, 500))

value must be rone of the following:

  • single Integer/Float indicating the value to skew the x direction by.
  • iterable cointaining type Integer/Float defining the values to skew the x and y directions by.

origin defines the point at with the skew should originate. It must be a Coordinate or None. The default is (0, 0).

Normalization
BasePoint.round()[source]

Round the point’s coordinate.

>>> point.round()

This applies to the following:

  • x
  • y
Environment
BasePoint.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BasePoint.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()

Component

Description

A component can be a part of a glyph, and it is a reference to another glyph in the same font. With components you can make glyphs depend on other glyphs. Changes to the base glyph will reflect in the component as well.

The parent of a component is usually a glyph. Components can be decomposed: they replace themselves with the actual outlines from the base glyph. When that happens, the link between the original and the component is broken: changes to the base glyph will no longer reflect in the glyph that had the component.

Overview
Parents
BaseComponent.glyph The component’s parent glyph.
BaseComponent.layer The component’s parent layer.
BaseComponent.font The component’s parent font.
Copy
BaseComponent.copy Copy this object into a new object of the same type.
Identification
BaseComponent.identifier The unique identifier for the object.
BaseComponent.index The index of the component within the ordered list of the parent glyph’s components.
Attributes
BaseComponent.baseGlyph The name of the glyph the component references.
BaseComponent.transformation The component’s transformation matrix.
BaseComponent.offset The component’s offset.
BaseComponent.scale The component’s scale.
Queries
BaseComponent.bounds The bounds of the component: (xMin, yMin, xMax, yMax) or None.
BaseComponent.pointInside Determine if point is in the black or white of the component.
Pens and Drawing
BaseComponent.draw Draw the component with the given Pen.
BaseComponent.drawPoints Draw the contour with the given PointPen.
Transformations
BaseComponent.transformBy Transform the object.
BaseComponent.moveBy Move the object.
BaseComponent.scaleBy Scale the object.
BaseComponent.rotateBy Rotate the object.
BaseComponent.skewBy Skew the object.
Normalization
BaseComponent.decompose Decompose the component.
BaseComponent.round Round offset coordinates.
Environment
BaseComponent.naked Return the environment’s native object that has been wrapped by this object.
BaseComponent.changed Tell the environment that something has changed in the object.
Reference
class fontParts.base.BaseComponent(*args, **kwargs)[source]
Parents
BaseComponent.glyph

The component’s parent glyph.

BaseComponent.layer

The component’s parent layer.

BaseComponent.font

The component’s parent font.

Copy
BaseComponent.copy()

Copy this object into a new object of the same type. The returned object will not have a parent object.

Identification
BaseComponent.identifier

The unique identifier for the object. This value will be an Identifier or a None. This attribute is read only.

>>> object.identifier
'ILHGJlygfds'

To request an identifier if it does not exist use object.getIdentifier()

BaseComponent.index

The index of the component within the ordered list of the parent glyph’s components.

Attributes
BaseComponent.baseGlyph

The name of the glyph the component references.

BaseComponent.transformation

The component’s transformation matrix.

BaseComponent.offset

The component’s offset.

BaseComponent.scale

The component’s scale.

Queries
BaseComponent.bounds

The bounds of the component: (xMin, yMin, xMax, yMax) or None.

BaseComponent.pointInside(point)[source]

Determine if point is in the black or white of the component.

point must be an (x, y) tuple.

Pens and Drawing
BaseComponent.draw(pen)[source]

Draw the component with the given Pen.

BaseComponent.drawPoints(pen)[source]

Draw the contour with the given PointPen.

Transformations
BaseComponent.transformBy(matrix, origin=None)

Transform the object.

>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0))
>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0), origin=(500, 500))

matrix must be a Transformation Matrix. origin defines the point at with the transformation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseComponent.moveBy(value)

Move the object.

>>> obj.moveBy((10, 0))

value must be an iterable containing two Integer/Float values defining the x and y values to move the object by.

BaseComponent.scaleBy(value, origin=None)

Scale the object.

>>> obj.scaleBy(2.0)
>>> obj.scaleBy((0.5, 2.0), origin=(500, 500))

value must be an iterable containing two Integer/Float values defining the x and y values to scale the object by. origin defines the point at with the scale should originate. It must be a Coordinate or None. The default is (0, 0).

BaseComponent.rotateBy(value, origin=None)

Rotate the object.

>>> obj.rotateBy(45)
>>> obj.rotateBy(45, origin=(500, 500))

value must be a Integer/Float values defining the angle to rotate the object by. origin defines the point at with the rotation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseComponent.skewBy(value, origin=None)

Skew the object.

>>> obj.skewBy(11)
>>> obj.skewBy((25, 10), origin=(500, 500))

value must be rone of the following:

  • single Integer/Float indicating the value to skew the x direction by.
  • iterable cointaining type Integer/Float defining the values to skew the x and y directions by.

origin defines the point at with the skew should originate. It must be a Coordinate or None. The default is (0, 0).

Normalization
BaseComponent.decompose()[source]

Decompose the component.

BaseComponent.round()[source]

Round offset coordinates.

Environment
BaseComponent.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BaseComponent.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()

Anchor

Description

Anchors are single points in a glyph which are not part of a contour. They can be used as reference positions for doing things like assembling components. In most font editors, anchors have a special appearance and can be edited.

glyph = CurrentGlyph()
for anchor in glyph.anchors:
    print(anchor)
Overview
Copy
BaseAnchor.copy Copy this object into a new object of the same type.
Parents
BaseAnchor.glyph The anchor’s parent BaseGlyph.
BaseAnchor.layer The anchor’s parent BaseLayer.
BaseAnchor.font The anchor’s parent BaseFont.
Identification
BaseAnchor.name The name of the anchor.
BaseAnchor.color The anchor’s color.
BaseAnchor.identifier The unique identifier for the object.
BaseAnchor.index The index of the anchor within the ordered list of the parent glyph’s anchors.
Coordinate
BaseAnchor.x The x coordinate of the anchor.
BaseAnchor.y The y coordinate of the anchor.
Transformations
BaseAnchor.transformBy Transform the object.
BaseAnchor.moveBy Move the object.
BaseAnchor.scaleBy Scale the object.
BaseAnchor.rotateBy Rotate the object.
BaseAnchor.skewBy Skew the object.
Normalization
BaseAnchor.round Round the anchor’s coordinate.
Environment
BaseAnchor.naked Return the environment’s native object that has been wrapped by this object.
BaseAnchor.changed Tell the environment that something has changed in the object.
Reference
class fontParts.base.BaseAnchor(*args, **kwargs)[source]

An anchor object. This object is almost always created with BaseGlyph.appendAnchor. An orphan anchor can be created like this:

>>> anchor = RAnchor()
Copy
BaseAnchor.copy()

Copy this object into a new object of the same type. The returned object will not have a parent object.

Parents
BaseAnchor.glyph

The anchor’s parent BaseGlyph.

BaseAnchor.layer

The anchor’s parent BaseLayer.

BaseAnchor.font

The anchor’s parent BaseFont.

Identification
BaseAnchor.name

The name of the anchor. This will be a String or None.

>>> anchor.name
'my anchor'
>>> anchor.name = None
BaseAnchor.color

The anchor’s color. This will be a Color or None.

>>> anchor.color
None
>>> anchor.color = (1, 0, 0, 0.5)
BaseAnchor.identifier

The unique identifier for the object. This value will be an Identifier or a None. This attribute is read only.

>>> object.identifier
'ILHGJlygfds'

To request an identifier if it does not exist use object.getIdentifier()

BaseAnchor.index

The index of the anchor within the ordered list of the parent glyph’s anchors. This attribute is read only.

>>> anchor.index
0
Coordinate
BaseAnchor.x

The x coordinate of the anchor. It must be an Integer/Float.

>>> anchor.x
100
>>> anchor.x = 101
BaseAnchor.y

The y coordinate of the anchor. It must be an Integer/Float.

>>> anchor.y
100
>>> anchor.y = 101
Transformations
BaseAnchor.transformBy(matrix, origin=None)

Transform the object.

>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0))
>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0), origin=(500, 500))

matrix must be a Transformation Matrix. origin defines the point at with the transformation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseAnchor.moveBy(value)

Move the object.

>>> obj.moveBy((10, 0))

value must be an iterable containing two Integer/Float values defining the x and y values to move the object by.

BaseAnchor.scaleBy(value, origin=None)

Scale the object.

>>> obj.scaleBy(2.0)
>>> obj.scaleBy((0.5, 2.0), origin=(500, 500))

value must be an iterable containing two Integer/Float values defining the x and y values to scale the object by. origin defines the point at with the scale should originate. It must be a Coordinate or None. The default is (0, 0).

BaseAnchor.rotateBy(value, origin=None)

Rotate the object.

>>> obj.rotateBy(45)
>>> obj.rotateBy(45, origin=(500, 500))

value must be a Integer/Float values defining the angle to rotate the object by. origin defines the point at with the rotation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseAnchor.skewBy(value, origin=None)

Skew the object.

>>> obj.skewBy(11)
>>> obj.skewBy((25, 10), origin=(500, 500))

value must be rone of the following:

  • single Integer/Float indicating the value to skew the x direction by.
  • iterable cointaining type Integer/Float defining the values to skew the x and y directions by.

origin defines the point at with the skew should originate. It must be a Coordinate or None. The default is (0, 0).

Normalization
BaseAnchor.round()[source]

Round the anchor’s coordinate.

>>> anchor.round()

This applies to the following:

  • x
  • y
Environment
BaseAnchor.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BaseAnchor.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()

Image

Overview
BaseImage.copy Copy this object into a new object of the same type.
BaseImage.glyph The image’s parent BaseGlyph.
BaseImage.layer The image’s parent BaseLayer.
BaseImage.font The image’s parent BaseFont.
BaseImage.data The image’s raw byte data.
BaseImage.color The image’s color.
BaseImage.transformation The image’s Transformation Matrix.
BaseImage.offset The image’s offset.
BaseImage.scale The image’s scale.
BaseImage.transformBy Transform the object.
BaseImage.moveBy Move the object.
BaseImage.scaleBy Scale the object.
BaseImage.rotateBy Rotate the object.
BaseImage.skewBy Skew the object.
BaseImage.round Round offset coordinates.
BaseImage.naked Return the environment’s native object that has been wrapped by this object.
BaseImage.changed Tell the environment that something has changed in the object.
Reference
class fontParts.base.BaseImage(*args, **kwargs)[source]
Copy
BaseImage.copy()

Copy this object into a new object of the same type. The returned object will not have a parent object.

Parents
BaseImage.glyph

The image’s parent BaseGlyph.

BaseImage.layer

The image’s parent BaseLayer.

BaseImage.font

The image’s parent BaseFont.

Attributes
BaseImage.data

The image’s raw byte data. The possible formats are defined by each environment.

BaseImage.color

The image’s color. This will be a Color or None.

>>> image.color
None
>>> image.color = (1, 0, 0, 0.5)
BaseImage.transformation

The image’s Transformation Matrix. This defines the image’s position, scale, and rotation.

>>> image.transformation
(1, 0, 0, 1, 0, 0)
>>> image.transformation = (2, 0, 0, 2, 100, -50)
BaseImage.offset

The image’s offset. This is a shortcut to the offset values in transformation. This must be an iterable containing two Integer/Float values defining the x and y values to offset the image by.

>>> image.offset
(0, 0)
>>> image.offset = (100, -50)
BaseImage.scale

The image’s scale. This is a shortcut to the scale values in transformation. This must be an iterable containing two Integer/Float values defining the x and y values to scale the image by.

>>> image.scale
(1, 1)
>>> image.scale = (2, 2)
Transformations
BaseImage.transformBy(matrix, origin=None)

Transform the object.

>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0))
>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0), origin=(500, 500))

matrix must be a Transformation Matrix. origin defines the point at with the transformation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseImage.moveBy(value)

Move the object.

>>> obj.moveBy((10, 0))

value must be an iterable containing two Integer/Float values defining the x and y values to move the object by.

BaseImage.scaleBy(value, origin=None)

Scale the object.

>>> obj.scaleBy(2.0)
>>> obj.scaleBy((0.5, 2.0), origin=(500, 500))

value must be an iterable containing two Integer/Float values defining the x and y values to scale the object by. origin defines the point at with the scale should originate. It must be a Coordinate or None. The default is (0, 0).

BaseImage.rotateBy(value, origin=None)

Rotate the object.

>>> obj.rotateBy(45)
>>> obj.rotateBy(45, origin=(500, 500))

value must be a Integer/Float values defining the angle to rotate the object by. origin defines the point at with the rotation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseImage.skewBy(value, origin=None)

Skew the object.

>>> obj.skewBy(11)
>>> obj.skewBy((25, 10), origin=(500, 500))

value must be rone of the following:

  • single Integer/Float indicating the value to skew the x direction by.
  • iterable cointaining type Integer/Float defining the values to skew the x and y directions by.

origin defines the point at with the skew should originate. It must be a Coordinate or None. The default is (0, 0).

Normalization
BaseImage.round()[source]

Round offset coordinates.

Environment
BaseImage.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BaseImage.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()

Guideline

Description

Guidelines are reference lines in a glyph that are not part of a contour or the generated font data. They are defined by a point and an angle; the guideline extends from the point in both directions on the specified angle. They are most often used to keep track of design information for a font (‘my overshoots should be here’) or to measure positions in a glyph (‘line the ends of my serifs on this line’). They can also be used as reference positions for doing things like assembling components. In most font editors, guidelines have a special appearance and can be edited.

glyph = CurrentGlyph()
for guideline in glyph.guidelines:
    print(guideline)
Overview
Copy
BaseGuideline.copy Copy this object into a new object of the same type.
Parents
BaseGuideline.glyph The guideline’s parent BaseGlyph.
BaseGuideline.layer The guideline’s parent BaseLayer.
BaseGuideline.font The guideline’s parent BaseFont.
Identification
BaseGuideline.name The name of the guideline.
BaseGuideline.color
BaseGuideline.identifier The unique identifier for the object.
BaseGuideline.index The index of the guideline within the ordered list of the parent glyph’s guidelines.
Attributes
BaseGuideline.x The x coordinate of the guideline.
BaseGuideline.y The y coordinate of the guideline.
BaseGuideline.angle The angle of the guideline.
Transformations
BaseGuideline.transformBy Transform the object.
BaseGuideline.moveBy Move the object.
BaseGuideline.scaleBy Scale the object.
BaseGuideline.rotateBy Rotate the object.
BaseGuideline.skewBy Skew the object.
Normalization
BaseGuideline.round Round the guideline’s coordinate.
Environment
BaseGuideline.naked Return the environment’s native object that has been wrapped by this object.
BaseGuideline.changed Tell the environment that something has changed in the object.
Reference
class fontParts.base.BaseGuideline(*args, **kwargs)[source]

A guideline object. This object is almost always created with BaseGlyph.appendGuideline. An orphan guideline can be created like this:

>>> guideline = RGuideline()
Copy
BaseGuideline.copy()

Copy this object into a new object of the same type. The returned object will not have a parent object.

Parents
BaseGuideline.glyph

The guideline’s parent BaseGlyph.

BaseGuideline.layer

The guideline’s parent BaseLayer.

BaseGuideline.font

The guideline’s parent BaseFont.

Identification
BaseGuideline.name

The name of the guideline. This will be a String or None.

>>> guideline.name
'my guideline'
>>> guideline.name = None
BaseGuideline.color

” The guideline’s color. This will be a Color or None.

>>> guideline.color
None
>>> guideline.color = (1, 0, 0, 0.5)
BaseGuideline.identifier

The unique identifier for the object. This value will be an Identifier or a None. This attribute is read only.

>>> object.identifier
'ILHGJlygfds'

To request an identifier if it does not exist use object.getIdentifier()

BaseGuideline.index

The index of the guideline within the ordered list of the parent glyph’s guidelines. This attribute is read only.

>>> guideline.index
0
Attributes
BaseGuideline.x

The x coordinate of the guideline. It must be an Integer/Float.

>>> guideline.x
100
>>> guideline.x = 101
BaseGuideline.y

The y coordinate of the guideline. It must be an Integer/Float.

>>> guideline.y
100
>>> guideline.y = 101
BaseGuideline.angle

The angle of the guideline. It must be an Angle. Please check how normalizers.normalizeRotationAngle handles the angle. There is a special case, when angle is None. If so, when x and y are not 0, the angle will be 0. If x is 0 but y is not, the angle will be 0. If y is 0 and x is not, the angle will be 90. If both x and y are 0, the angle will be 0.

>>> guideline.angle
45.0
>>> guideline.angle = 90
Transformations
BaseGuideline.transformBy(matrix, origin=None)

Transform the object.

>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0))
>>> obj.transformBy((0.5, 0, 0, 2.0, 10, 0), origin=(500, 500))

matrix must be a Transformation Matrix. origin defines the point at with the transformation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseGuideline.moveBy(value)

Move the object.

>>> obj.moveBy((10, 0))

value must be an iterable containing two Integer/Float values defining the x and y values to move the object by.

BaseGuideline.scaleBy(value, origin=None)

Scale the object.

>>> obj.scaleBy(2.0)
>>> obj.scaleBy((0.5, 2.0), origin=(500, 500))

value must be an iterable containing two Integer/Float values defining the x and y values to scale the object by. origin defines the point at with the scale should originate. It must be a Coordinate or None. The default is (0, 0).

BaseGuideline.rotateBy(value, origin=None)

Rotate the object.

>>> obj.rotateBy(45)
>>> obj.rotateBy(45, origin=(500, 500))

value must be a Integer/Float values defining the angle to rotate the object by. origin defines the point at with the rotation should originate. It must be a Coordinate or None. The default is (0, 0).

BaseGuideline.skewBy(value, origin=None)

Skew the object.

>>> obj.skewBy(11)
>>> obj.skewBy((25, 10), origin=(500, 500))

value must be rone of the following:

  • single Integer/Float indicating the value to skew the x direction by.
  • iterable cointaining type Integer/Float defining the values to skew the x and y directions by.

origin defines the point at with the skew should originate. It must be a Coordinate or None. The default is (0, 0).

Normalization
BaseGuideline.round()[source]

Round the guideline’s coordinate.

>>> guideline.round()

This applies to the following:

  • x
  • y

It does not apply to

  • angle
Environment
BaseGuideline.naked()

Return the environment’s native object that has been wrapped by this object.

>>> loweLevelObj = obj.naked()
BaseGuideline.changed(*args, **kwargs)

Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

>>> obj.changed()
info layer features point image component lib contour guideline kerning lib font segment anchor bPoint glyph

Common Value Types

FontParts scripts are built on with objects that represent fonts, glyphs, contours and so on. The objects are obtained through fontparts-world.

FontParts uses some common value types.

String

Unicode (unencoded) or string. Internally everything is a unicode string.

Integer/Float

Integers and floats are interchangeable in FontParts (unless the specification states that only one is allowed).

Coordinate

An immutable iterable containing two Integer/Float representing:

  1. x
  2. y

Angle

XXX define the angle specifications here. Direction, degrees, etc. This will always be a float.

Identifier

A String following the UFO identifier conventions.

Color

An immutable iterable containing four Integer/Float representing:

  1. red
  2. green
  3. blue
  4. alpha

Values are from 0 to 1.0.

Transformation Matrix

An immutable iterable defining a 2x2 transformation plus offset (aka Affine transform). The default is (1, 0, 0, 1, 0, 0).

Immutable List

This must be an immutable, ordered iterable like a tuple.

fontParts.world

Note

We still need to decide if we need a world module or if we should recommend namespace injection.

fontParts.world.AllFonts(sortOptions=None)[source]

Get a list of all open fonts. Optionally, provide a value for sortOptions to sort the fonts. See world.FontList.sortBy for options.

from fontParts.world import *

fonts = AllFonts()
for font in fonts:
    # do something

fonts = AllFonts("magic")
for font in fonts:
    # do something

fonts = AllFonts(["familyName", "styleName"])
for font in fonts:
    # do something
fontParts.world.NewFont(familyName=None, styleName=None, showInterface=True)[source]

Create a new font. familyName will be assigned to font.info.familyName and styleName will be assigned to font.info.styleName. These are optional and default to None. If showInterface is False, the font should be created without graphical interface. The default for showInterface is True.

from fontParts.world import *

font = NewFont()
font = NewFont(familyName="My Family", styleName="My Style")
font = NewFont(showInterface=False)
fontParts.world.OpenFont(path, showInterface=True)[source]

Open font located at path. If showInterface is False, the font should be opened without graphical interface. The default for showInterface is True.

from fontParts.world import *

font = OpenFont("/path/to/my/font.ufo")
font = OpenFont("/path/to/my/font.ufo", showInterface=False)
fontParts.world.OpenFonts(directory=None, showInterface=True, fileExtensions=None)[source]

Open all fonts with the given fileExtensions located in directory. If directory is None, a dialog for selecting a directory will be opened. directory may also be a list of directories. If showInterface is False, the font should be opened without graphical interface. The default for showInterface is True.

The fonts are located within the directory using the glob <https://docs.python.org/library/glob.html>`_ module. The patterns are created with os.path.join(glob, "*" + fileExtension) for every file extension in fileExtensions. If fileExtensions if None the environment will use its default fileExtensions.

from fontParts.world import *

fonts = OpenFonts()
fonts = OpenFonts(showInterface=False)
fontParts.world.CurrentFont()[source]

Get the “current” font.

fontParts.world.CurrentLayer()[source]

Get the “current” layer from CurrentGlyph.

from fontParts.world import *

layer = CurrentLayer()
fontParts.world.CurrentGlyph()[source]

Get the “current” glyph from CurrentFont.

from fontParts.world import *

glyph = CurrentGlyph()
fontParts.world.CurrentContours()[source]

Get the “currently” selected contours from CurrentGlyph.

from fontParts.world import *

contours = CurrentContours()

This returns an immutable list, even when nothing is selected.

fontParts.world.CurrentSegments()[source]

Get the “currently” selected segments from CurrentContours.

from fontParts.world import *

segments = CurrentSegments()

This returns an immutable list, even when nothing is selected.

fontParts.world.CurrentPoints()[source]

Get the “currently” selected points from CurrentContours.

from fontParts.world import *

points = CurrentPoints()

This returns an immutable list, even when nothing is selected.

fontParts.world.CurrentComponents()[source]

Get the “currently” selected components from CurrentGlyph.

from fontParts.world import *

components = CurrentComponents()

This returns an immutable list, even when nothing is selected.

fontParts.world.CurrentAnchors()[source]

Get the “currently” selected anchors from CurrentGlyph.

from fontParts.world import *

anchors = CurrentAnchors()

This returns an immutable list, even when nothing is selected.

fontParts.world.CurrentGuidelines()[source]

Get the “currently” selected guidelines from CurrentGlyph. This will include both font level and glyph level guidelines.

from fontParts.world import *

guidelines = CurrentGuidelines()

This returns an immutable list, even when nothing is selected.

fontParts.world.FontList(fonts=None)[source]

Get a list with font specific methods.

from fontParts.world import *

fonts = FontList()

Refer to BaseFontList for full documentation.

class fontParts.world.BaseFontList[source]

Developers

Implementing FontParts

The whole point of FontParts is to present a common API to scripters. So, obviously, the way to implement it is to develop an API that is compliant with the object documentation. That’s going to be a non-trivial amount of work, so we offer a less laborious alternative: we provide a set of base objects that can be subclassed and privately mapped to an environment’s native API. If you don’t want to use these base objects, you can implement the API all on your own. You just have to make sure that your implementation is compatible.

Testing

A test suite is provided to test any implementation, either subclassed from the base objects or implemented independently. The suite has been designed to be environment and format agnostic. Environment developers only need to implement a function that provides objects for testing and a simple Python script that sends the function to the test suite.

Testing an environment

The main thing that an environment needs to implement is the test object generator. This should create an object for the requested class identifier.

def MyAppObjectGenerator(classIdentifier):
    unrequested = []
    obj = myApp.foo.bar.something.hi(classIdentifier)
    return obj, unrequested

If an environment does not allow orphan objects, parent objects may create the parent objects and store them in a list. The function must return the generated objects and the list of unrequested objects (or an empty list if no parent objects were generated).

The class identifiers are as follows:

  • font
  • info
  • groups
  • kerning
  • features
  • lib
  • layer
  • glyph
  • contour
  • segment
  • bpoint
  • point
  • component
  • anchor
  • image
  • guideline

Once an environment has developed this function, all that remains is to pass the function to the test runner:

from fontParts.test import testEnvironment

if __name__ == "__main__":
    testEnvironment(MyAppObjectGenerator)

This can then be executed and the report will be printed.

It is up to each environment to ensure that the bridge from the environment’s native objects to the fontParts wrappers is working properly. This has to be done on an environment by environment basis since the native objects are not consistently implemented.

Subclassing fontObjects.base

The base objects have been designed to provide common behavior, normalization and type consistency for environments and scripters alike. Environments wrap their native objects with subclasses of fontParts’ base objects and implement the necessary translation to the native API. Once this is done, the environment will inherit all of the base behavior from fontParts.

Environments will need to implement their own subclasses of:

Font

Must Override
BaseFont._close(**kwargs)[source]

This is the environment implementation of BaseFont.close.

Subclasses must override this method.

BaseFont._generate(format, path, environmentOptions, **kwargs)[source]

This is the environment implementation of BaseFont.generate. format will be a String defining the output format. Refer to the BaseFont.generate documentation for the standard format identifiers. If the value given for format is not supported by the environment, the environment must raise FontPartsError. path will be a String defining the location where the file should be created. It will have been normalized with normalizers.normalizeFilePath. environmentOptions will be a dictionary of names validated with BaseFont._isValidGenerateEnvironmentOption nd the given values. These values will not have been passed through any normalization functions.

Subclasses must override this method.

BaseFont._getGuideline(index, **kwargs)[source]

This must return a BaseGuideline object. index will be a valid index.

Subclasses must override this method.

BaseFont._get_defaultLayer()[source]
BaseFont._get_features()[source]

This is the environment implementation of BaseFont.features. This must return an instance of a BaseFeatures subclass.

Subclasses must override this method.

BaseFont._get_glyphOrder()[source]

This is the environment implementation of BaseFont.glyphOrder. This must return an Immutable List containing glyph names representing the glyph order in the font. The value will be normalized with normalizers.normalizeGlyphOrder.

Subclasses must override this method.

BaseFont._get_groups()[source]

This is the environment implementation of BaseFont.groups. This must return an instance of a BaseGroups subclass.

Subclasses must override this method.

BaseFont._get_info()[source]

This is the environment implementation of BaseFont.info. This must return an instance of a BaseInfo subclass.

Subclasses must override this method.

BaseFont._get_kerning()[source]

This is the environment implementation of BaseFont.kerning. This must return an instance of a BaseKerning subclass.

Subclasses must override this method.

BaseFont._get_layerOrder(**kwargs)[source]

This is the environment implementation of BaseFont.layerOrder. This must return an Immutable List defining the order of the layers in the font. The contents of the list must be layer names as String. The list will be normalized with normalizers.normalizeLayerOrder.

Subclasses must override this method.

BaseFont._get_layers(**kwargs)[source]

This is the environment implementation of BaseFont.layers. This must return an Immutable List containing instances of BaseLayer subclasses. The items in the list should be in the order defined by BaseFont.layerOrder.

Subclasses must override this method.

BaseFont._get_lib()[source]

This is the environment implementation of BaseFont.lib. This must return an instance of a BaseLib subclass.

Subclasses must override this method.

BaseFont._get_path(**kwargs)[source]

This is the environment implementation of BaseFont.path.

This must return a String defining the location of the file or None indicating that the font does not have a file representation. If the returned value is not None it will be normalized with normalizers.normalizeFilePath.

Subclasses must override this method.

BaseFont._init(pathOrObject=None, showInterface=True, **kwargs)[source]

Initialize this object. This should wrap a native font object based on the values for pathOrObject:

None Create a new font.
string Open the font file located at the given location.
native font object Wrap the given object.

If showInterface is False, the font should be created without graphical interface.

Subclasses must override this method.

BaseFont._lenGuidelines(**kwargs)[source]

This must return an integer indicating the number of font-level guidelines in the font.

Subclasses must override this method.

BaseFont._newLayer(name, color, **kwargs)[source]

This is the environment implementation of BaseFont.newLayer. name will be a String representing a valid layer name. The value will have been normalized with normalizers.normalizeLayerName and name will not be the same as the name of an existing layer. color will be a Color or None. If the value is not None the value will have been normalized with normalizers.normalizeColor. This must return an instance of a BaseLayer subclass that represents the new layer.

Subclasses must override this method.

BaseFont._removeGuideline(index, **kwargs)[source]

This is the environment implementation of BaseFont.removeGuideline. index will be a valid index.

Subclasses must override this method.

BaseFont._removeLayer(name, **kwargs)[source]

This is the environment implementation of BaseFont.removeLayer. name will be a String defining the name of an existing layer. The value will have been normalized with normalizers.normalizeLayerName.

Subclasses must override this method.

BaseFont._save(path=None, showProgress=False, formatVersion=None, fileStructure=None, **kwargs)[source]

This is the environment implementation of BaseFont.save. path will be a String or None. If path is not None, the value will have been normalized with normalizers.normalizeFilePath. showProgress will be a bool indicating if the environment should display a progress bar during the operation. Environments are not required to display a progress bar even if showProgess is True. formatVersion will be Integer/Float or None indicating the file format version to write the data into. It will have been normalized with normalizers.normalizeFileFormatVersion.

Subclasses must override this method.

BaseFont._set_defaultLayer(layer)[source]
BaseFont._set_glyphOrder(value)[source]

This is the environment implementation of BaseFont.glyphOrder. value will be a list of String. It will have been normalized with normalizers.normalizeGlyphOrder.

Subclasses must override this method.

BaseFont._set_layerOrder(value, **kwargs)[source]

This is the environment implementation of BaseFont.layerOrder. value will be a list of String representing layer names. The list will have been normalized with normalizers.normalizeLayerOrder.

Subclasses must override this method.

May Override
BaseFont._appendGuideline(position, angle, name=None, color=None, identifier=None, **kwargs)[source]

This is the environment implementation of BaseFont.appendGuideline. position will be a valid Coordinate. angle will be a valid angle. name will be a valid String or None. color will be a valid Color or None. This must return the newly created BaseGuideline object.

Subclasses may override this method.

BaseFont._autoUnicodes()[source]

This is the environment implementation of BaseFont.autoUnicodes.

Subclasses may override this method.

BaseFont._clearGuidelines()[source]

This is the environment implementation of BaseFont.clearGuidelines.

Subclasses may override this method.

BaseFont._contains(name, **kwargs)

This is the environment implementation of BaseLayer.__contains__ and BaseFont.__contains__ This must return bool indicating if the layer has a glyph with the defined name. name will be a :ref-type-string` representing a glyph name. It will have been normalized with normalizers.normalizeGlyphName.

Subclasses may override this method.

BaseFont._getItem(name, **kwargs)[source]

This is the environment implementation of BaseFont.__getitem__. name will be a String defining an existing glyph in the default layer. The value will have been normalized with normalizers.normalizeGlyphName.

Subclasses may override this method.

BaseFont._getLayer(name, **kwargs)[source]

This is the environment implementation of BaseFont.getLayer. name will be a String. It will have been normalized with normalizers.normalizeLayerName and it will have been verified as an existing layer. This must return an instance of BaseLayer.

Subclasses may override this method.

BaseFont._get_guidelines()[source]

This is the environment implementation of BaseFont.guidelines. This must return an Immutable List of BaseGuideline objects.

Subclasses may override this method.

BaseFont._insertGlyph(glyph, name, **kwargs)

This is the environment implementation of BaseLayer.__setitem__ and BaseFont.__setitem__. This must return an instance of a BaseGlyph subclass. glyph will be a glyph object with the attributes necessary for copying as defined in BaseGlyph.copy An environment must not insert glyph directly. Instead the data from glyph should be copied to a new glyph instead. name will be a String representing a glyph name. It will have been normalized with normalizers.normalizeGlyphName. name will have been tested to make sure that no glyph with the same name exists in the layer.

Subclasses may override this method.

BaseFont._interpolate(factor, minFont, maxFont, round=True, suppressError=True)[source]

This is the environment implementation of BaseFont.interpolate.

Subclasses may override this method.

BaseFont._isCompatible(other, reporter)[source]

This is the environment implementation of BaseFont.isCompatible.

Subclasses may override this method.

BaseFont._iter(**kwargs)

This is the environment implementation of BaseLayer.__iter__ and BaseFont.__iter__ This must return an iterator that returns instances of a BaseGlyph subclass.

Subclasses may override this method.

BaseFont._keys(**kwargs)[source]

This is the environment implementation of BaseFont.keys. This must return an Immutable List of all glyph names in the default layer.

Subclasses may override this method.

BaseFont._len(**kwargs)

This is the environment implementation of BaseLayer.__len__ and BaseFont.__len__ This must return an int indicating the number of glyphs in the layer.

Subclasses may override this method.

BaseFont._newGlyph(name, **kwargs)[source]

This is the environment implementation of BaseFont.newGlyph. name will be a String representing a valid glyph name. The value will have been tested to make sure that an existing glyph in the default layer does not have an identical name. The value will have been normalized with normalizers.normalizeGlyphName. This must return an instance of BaseGlyph representing the new glyph.

Subclasses may override this method.

BaseFont._removeGlyph(name, **kwargs)[source]

This is the environment implementation of BaseFont.removeGlyph. name will be a String representing an existing glyph in the default layer. The value will have been normalized with normalizers.normalizeGlyphName.

Subclasses may override this method.

BaseFont._round()[source]

This is the environment implementation of BaseFont.round.

Subclasses may override this method.

Info

Must Override
May Override
BaseInfo._getAttr(attr)[source]

Subclasses may override this method.

If a subclass does not override this method, it must implement ‘_get_attributeName’ methods for all Info methods.

BaseInfo._init(*args, **kwargs)

Subclasses may override this method.

BaseInfo._interpolate(factor, minInfo, maxInfo, round=True, suppressError=True)[source]

Subclasses may override this method.

BaseInfo._round(**kwargs)[source]

Subclasses may override this method.

BaseInfo._setAttr(attr, value)[source]

Subclasses may override this method.

If a subclass does not override this method, it must implement ‘_set_attributeName’ methods for all Info methods.

BaseInfo.copyData(source)

Subclasses may override this method. If so, they should call the super.

Groups

Must Override
BaseGroups._contains(key)

Subclasses must override this method.

BaseGroups._delItem(key)

Subclasses must override this method.

BaseGroups._getItem(key)

Subclasses must override this method.

BaseGroups._items()

Subclasses must override this method.

BaseGroups._setItem(key, value)

Subclasses must override this method.

May Override
BaseGroups._clear()

Subclasses may override this method.

BaseGroups._findGlyph(glyphName)[source]

This is the environment implementation of BaseGroups.findGlyph. glyphName will be an String.

Subclasses may override this method.

BaseGroups._get(key, default=None)

Subclasses may override this method.

BaseGroups._init(*args, **kwargs)

Subclasses may override this method.

BaseGroups._iter()

Subclasses may override this method.

BaseGroups._keys()

Subclasses may override this method.

BaseGroups._len()

Subclasses may override this method.

BaseGroups._pop(key, default=None)

Subclasses may override this method.

BaseGroups._update(other)

Subclasses may override this method.

BaseGroups._values()

Subclasses may override this method.

Kerning

Must Override
BaseKerning._contains(key)

Subclasses must override this method.

BaseKerning._delItem(key)

Subclasses must override this method.

BaseKerning._getItem(key)

Subclasses must override this method.

BaseKerning._items()

Subclasses must override this method.

BaseKerning._setItem(key, value)

Subclasses must override this method.

May Override
BaseKerning._clear()

Subclasses may override this method.

BaseKerning._get(key, default=None)

Subclasses may override this method.

BaseKerning._init(*args, **kwargs)

Subclasses may override this method.

BaseKerning._interpolate(factor, minKerning, maxKerning, round=True, suppressError=True)[source]

This is the environment implementation of BaseKerning.interpolate.

  • factor will be an Integer/Float, tuple or list.
  • minKerning will be a BaseKerning object.
  • maxKerning will be a BaseKerning object.
  • round will be a bool indicating if the interpolated kerning should be rounded.
  • suppressError will be a bool indicating if incompatible data should be ignored.

Subclasses may override this method.

BaseKerning._iter()

Subclasses may override this method.

BaseKerning._keys()

Subclasses may override this method.

BaseKerning._len()

Subclasses may override this method.

BaseKerning._pop(key, default=None)

Subclasses may override this method.

BaseKerning._round(multiple=1)[source]

This is the environment implementation of BaseKerning.round. multiple will be an int.

Subclasses may override this method.

BaseKerning._scale(factor)[source]

This is the environment implementation of BaseKerning.scaleBy. factor will be a tuple.

Subclasses may override this method.

BaseKerning._update(other)

Subclasses may override this method.

BaseKerning._values()

Subclasses may override this method.

Features

Must Override
BaseFeatures._get_text()[source]

This is the environment implementation of BaseFeatures.text. This must return a String.

Subclasses must override this method.

BaseFeatures._set_text(value)[source]

This is the environment implementation of BaseFeatures.text. value will be a String.

Subclasses must override this method.

May Override
BaseFeatures._init(*args, **kwargs)

Subclasses may override this method.

BaseFeatures.copyData(source)

Subclasses may override this method. If so, they should call the super.

Lib

Must Override
BaseLib._contains(key)

Subclasses must override this method.

BaseLib._delItem(key)

Subclasses must override this method.

BaseLib._getItem(key)

Subclasses must override this method.

BaseLib._items()

Subclasses must override this method.

BaseLib._setItem(key, value)

Subclasses must override this method.

May Override
BaseLib._clear()

Subclasses may override this method.

BaseLib._get(key, default=None)

Subclasses may override this method.

BaseLib._init(*args, **kwargs)

Subclasses may override this method.

BaseLib._iter()

Subclasses may override this method.

BaseLib._keys()

Subclasses may override this method.

BaseLib._len()

Subclasses may override this method.

BaseLib._pop(key, default=None)

Subclasses may override this method.

BaseLib._update(other)

Subclasses may override this method.

BaseLib._values()

Subclasses may override this method.

Layer

Must Override
BaseLayer._getItem(name, **kwargs)

This is the environment implementation of BaseLayer.__getitem__ and BaseFont.__getitem__ This must return an instance of a BaseGlyph subclass. name will be a String representing a name of a glyph that is in the layer. It will have been normalized with normalizers.normalizeGlyphName.

Subclasses must override this method.

BaseLayer._get_color()[source]

This is the environment implementation of BaseLayer.color. This must return a Color defining the color assigned to the layer. If the layer does not have an assigned color, the returned value must be None. It will be normalized with normalizers.normalizeColor.

Subclasses must override this method.

BaseLayer._get_lib()[source]

This is the environment implementation of BaseLayer.lib. This must return an instance of a BaseLib subclass.

BaseLayer._get_name()[source]

This is the environment implementation of BaseLayer.name. This must return a String defining the name of the layer. If the layer is the default layer, the returned value must be None. It will be normalized with normalizers.normalizeLayerName.

Subclasses must override this method.

BaseLayer._keys(**kwargs)

This is the environment implementation of BaseLayer.keys and BaseFont.keys This must return an Immutable List of the names representing all glyphs in the layer. The order is not defined.

Subclasses must override this method.

BaseLayer._newGlyph(name, **kwargs)

This is the environment implementation of BaseLayer.newGlyph and BaseFont.newGlyph This must return an instance of a BaseGlyph subclass. name will be a String representing a glyph name. It will have been normalized with normalizers.normalizeGlyphName. The name will have been tested to make sure that no glyph with the same name exists in the layer.

Subclasses must override this method.

BaseLayer._removeGlyph(name, **kwargs)

This is the environment implementation of BaseLayer.removeGlyph and BaseFont.removeGlyph. name will be a String representing a glyph name of a glyph that is in the layer. It will have been normalized with normalizers.normalizeGlyphName. The newly created BaseGlyph must be returned.

Subclasses must override this method.

BaseLayer._set_color(value, **kwargs)[source]

This is the environment implementation of BaseLayer.color. value will be a Color or None defining the color to assign to the layer. It will have been normalized with normalizers.normalizeColor.

Subclasses must override this method.

BaseLayer._set_name(value, **kwargs)[source]

This is the environment implementation of BaseLayer.name. value will be a String defining the name of the layer. It will have been normalized with normalizers.normalizeLayerName. No layer with the same name will exist.

Subclasses must override this method.

May Override
BaseLayer._autoUnicodes()[source]

This is the environment implementation of BaseLayer.autoUnicodes.

Subclasses may override this method.

BaseLayer._contains(name, **kwargs)

This is the environment implementation of BaseLayer.__contains__ and BaseFont.__contains__ This must return bool indicating if the layer has a glyph with the defined name. name will be a :ref-type-string` representing a glyph name. It will have been normalized with normalizers.normalizeGlyphName.

Subclasses may override this method.

BaseLayer._init(*args, **kwargs)

Subclasses may override this method.

BaseLayer._insertGlyph(glyph, name, **kwargs)

This is the environment implementation of BaseLayer.__setitem__ and BaseFont.__setitem__. This must return an instance of a BaseGlyph subclass. glyph will be a glyph object with the attributes necessary for copying as defined in BaseGlyph.copy An environment must not insert glyph directly. Instead the data from glyph should be copied to a new glyph instead. name will be a String representing a glyph name. It will have been normalized with normalizers.normalizeGlyphName. name will have been tested to make sure that no glyph with the same name exists in the layer.

Subclasses may override this method.

BaseLayer._interpolate(factor, minLayer, maxLayer, round=True, suppressError=True)[source]

This is the environment implementation of BaseLayer.interpolate.

Subclasses may override this method.

BaseLayer._isCompatible(other, reporter)[source]

This is the environment implementation of BaseLayer.isCompatible.

Subclasses may override this method.

BaseLayer._iter(**kwargs)

This is the environment implementation of BaseLayer.__iter__ and BaseFont.__iter__ This must return an iterator that returns instances of a BaseGlyph subclass.

Subclasses may override this method.

BaseLayer._len(**kwargs)

This is the environment implementation of BaseLayer.__len__ and BaseFont.__len__ This must return an int indicating the number of glyphs in the layer.

Subclasses may override this method.

BaseLayer._round()[source]

This is the environment implementation of BaseLayer.round.

Subclasses may override this method.

Glyph

Must Override
BaseGlyph._addImage(data, transformation=None, color=None)[source]

data will be raw, unnormalized image data. Each environment may have different possible formats, so this is unspecified.

transformation will be a valid transformation matrix.

color will be a color tuple or None.

This must return an Image object. Assigning it to the glyph will be handled by the base class.

Subclasses must override this method.

BaseGlyph._autoUnicodes()[source]

Subclasses must override this method.

BaseGlyph._clearImage(**kwargs)[source]

Subclasses must override this method.

BaseGlyph._getAnchor(index, **kwargs)[source]

This must return a wrapped anchor.

index will be a valid index.

Subclasses must override this method.

BaseGlyph._getComponent(index, **kwargs)[source]

This must return a wrapped component.

index will be a valid index.

Subclasses must override this method.

BaseGlyph._getContour(index, **kwargs)[source]

This must return a wrapped contour.

index will be a valid index.

Subclasses must override this method.

BaseGlyph._getGuideline(index, **kwargs)[source]

This must return a wrapped guideline.

index will be a valid index.

Subclasses must override this method.

BaseGlyph._get_height()[source]

This must return an int or float.

Subclasses must override this method.

BaseGlyph._get_image()[source]

Subclasses must override this method.

BaseGlyph._get_lib()[source]

Subclasses must override this method.

BaseGlyph._get_markColor()[source]

Return the mark color value as a color tuple or None.

Subclasses must override this method.

BaseGlyph._get_name()[source]

Get the name of the glyph. This must return a unicode string.

Subclasses must override this method.

BaseGlyph._get_note()[source]

Subclasses must override this method.

BaseGlyph._get_unicodes()[source]

Get the unicodes assigned to the glyph. This must return a tuple of zero or more integers.

Subclasses must override this method.

BaseGlyph._get_width()[source]

This must return an int or float.

Subclasses must override this method.

BaseGlyph._lenAnchors(**kwargs)[source]

This must return an integer indicating the number of anchors in the glyph.

Subclasses must override this method.

BaseGlyph._lenComponents(**kwargs)[source]

This must return an integer indicating the number of components in the glyph.

Subclasses must override this method.

BaseGlyph._lenContours(**kwargs)[source]

This must return an integer.

Subclasses must override this method.

BaseGlyph._lenGuidelines(**kwargs)[source]

This must return an integer indicating the number of guidelines in the glyph.

Subclasses must override this method.

BaseGlyph._newLayer(name, **kwargs)[source]

name will be a string representing a valid layer name. The name will have been tested to make sure that no layer in the glyph already has the name.

This must returned the new glyph.

Subclasses must override this method.

BaseGlyph._removeAnchor(index, **kwargs)[source]

index will be a valid index.

Subclasses must override this method.

BaseGlyph._removeComponent(index, **kwargs)[source]

index will be a valid index.

Subclasses must override this method.

BaseGlyph._removeContour(index, **kwargs)[source]

index will be a valid index.

Subclasses must override this method.

BaseGlyph._removeGuideline(index, **kwargs)[source]

index will be a valid index.

Subclasses must override this method.

BaseGlyph._removeOverlap()[source]

Subclasses must implement this method.

BaseGlyph._set_height(value)[source]

value will be an int or float.

Subclasses must override this method.

BaseGlyph._set_markColor(value)[source]

value will be a color tuple or None.

Subclasses must override this method.

BaseGlyph._set_name(value)[source]

Set the name of the glyph. This will be a unicode string.

Subclasses must override this method.

BaseGlyph._set_note(value)[source]

Subclasses must override this method.

BaseGlyph._set_unicodes(value)[source]

Assign the unicodes to the glyph. This will be a list of zero or more integers.

Subclasses must override this method.

BaseGlyph._set_width(value)[source]

value will be an int or float.

Subclasses must override this method.

May Override
BaseGlyph.__add__(other)[source]

Subclasses may override this method.

BaseGlyph.__div__(factor)

Subclasses may override this method.

BaseGlyph.__mul__(factor)[source]

Subclasses may override this method.

BaseGlyph.__rmul__(factor)

Subclasses may override this method.

BaseGlyph.__sub__(other)[source]

Subclasses may override this method.

BaseGlyph._appendAnchor(name, position=None, color=None, identifier=None, **kwargs)[source]

name will be a valid anchor name. position will be a valid position (x, y). color will be None or a valid color. identifier will be a valid, nonconflicting identifier.

This must return the new anchor.

Subclasses may override this method.

BaseGlyph._appendComponent(baseGlyph, transformation=None, identifier=None, **kwargs)[source]

baseGlyph will be a valid glyph name. The baseGlyph may or may not be in the layer.

offset will be a valid offset (x, y). scale will be a valid scale (x, y). identifier will be a valid, nonconflicting identifier.

This must return the new component.

Subclasses may override this method.

BaseGlyph._appendContour(contour, offset=None, **kwargs)[source]

contour will be an object with a drawPoints method.

offset will be a valid offset (x, y).

This must return the new contour.

Subclasses may override this method.

BaseGlyph._appendGlyph(other, offset=None)[source]

Subclasses may override this method.

BaseGlyph._appendGuideline(position, angle, name=None, color=None, identifier=None, **kwargs)[source]

position will be a valid position (x, y). angle will be a valid angle. name will be a valid guideline name or None. color will be a valid color or None . identifier will be a valid, nonconflicting identifier.

This must return the new guideline.

Subclasses may override this method.

BaseGlyph._clear(contours=True, components=True, anchors=True, guidelines=True, image=True)[source]

Subclasses may override this method.

BaseGlyph._clearAnchors()[source]

Subclasses may override this method.

BaseGlyph._clearComponents()[source]

Subclasses may override this method.

BaseGlyph._clearContours()[source]

Subclasses may override this method.

BaseGlyph._clearGuidelines()[source]

Subclasses may override this method.

BaseGlyph._decompose()[source]

Subclasses may override this method.

BaseGlyph._getLayer(name, **kwargs)[source]

name will be a string, but there may not be a layer with a name matching the string. If not, a ValueError must be raised.

Subclasses may override this method.

BaseGlyph._get_anchors()[source]

Subclasses may override this method.

BaseGlyph._get_bottomMargin()[source]

This must return an int or float. If the glyph has no outlines, this must return None.

Subclasses may override this method.

BaseGlyph._get_bounds()[source]

Subclasses may override this method.

BaseGlyph._get_components()[source]

Subclasses may override this method.

BaseGlyph._get_contours()[source]

Subclasses may override this method.

BaseGlyph._get_guidelines()[source]

Subclasses may override this method.

BaseGlyph._get_leftMargin()[source]

This must return an int or float. If the glyph has no outlines, this must return None.

Subclasses may override this method.

BaseGlyph._get_rightMargin()[source]

This must return an int or float. If the glyph has no outlines, this must return None.

Subclasses may override this method.

BaseGlyph._get_topMargin()[source]

This must return an int or float. If the glyph has no outlines, this must return None.

Subclasses may override this method.

BaseGlyph._get_unicode()[source]

Get the primary unicode assigned to the glyph. This must return an integer or None.

Subclasses may override this method.

BaseGlyph._init(*args, **kwargs)

Subclasses may override this method.

BaseGlyph._interpolate(factor, minGlyph, maxGlyph, round=True, suppressError=True)[source]

Subclasses may override this method.

BaseGlyph._isCompatible(other, reporter)[source]

This is the environment implementation of BaseGlyph.isCompatible.

Subclasses may override this method.

BaseGlyph._iterContours(**kwargs)[source]

This must return an iterator that returns wrapped contours.

Subclasses may override this method.

BaseGlyph._moveBy(value, **kwargs)

This is the environment implementation of BaseObject.moveBy.

value will be an iterable containing two Integer/Float values defining the x and y values to move the object by. It will have been normalized with normalizers.normalizeTransformationOffset.

Subclasses may override this method.

BaseGlyph._pointInside(point)[source]

Subclasses may override this method.

BaseGlyph._removeLayer(name, **kwargs)[source]

name will be a valid layer name. It will represent an existing layer in the font.

Subclasses may override this method.

BaseGlyph._rotateBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.rotateBy.

value will be a Integer/Float value defining the value to rotate the object by. It will have been normalized with normalizers.normalizeRotationAngle. origin will be a Coordinate defining the point at which the rotation should orginate.

Subclasses may override this method.

BaseGlyph._round()[source]

Subclasses may override this method.

BaseGlyph._scaleBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.scaleBy.

value will be an iterable containing two Integer/Float values defining the x and y values to scale the object by. It will have been normalized with normalizers.normalizeTransformationScale. origin will be a Coordinate defining the point at which the scale should orginate.

Subclasses may override this method.

BaseGlyph._set_bottomMargin(value)[source]

value will be an int or float.

Subclasses may override this method.

BaseGlyph._set_leftMargin(value)[source]

value will be an int or float.

Subclasses may override this method.

BaseGlyph._set_rightMargin(value)[source]

value will be an int or float.

Subclasses may override this method.

BaseGlyph._set_topMargin(value)[source]

value will be an int or float.

Subclasses may override this method.

BaseGlyph._set_unicode(value)[source]

Assign the primary unicode to the glyph. This will be an integer or None.

Subclasses may override this method.

BaseGlyph._skewBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.skewBy.

value will be an iterable containing two Integer/Float values defining the x and y values to skew the object by. It will have been normalized with normalizers.normalizeTransformationSkewAngle. origin will be a Coordinate defining the point at which the skew should orginate.

Subclasses may override this method.

BaseGlyph._transformBy(matrix, **kwargs)[source]

Subclasses may override this method.

Contour

Must Override
BaseContour._getPoint(index, **kwargs)[source]

This must return a wrapped point.

index will be a valid index.

Subclasses must override this method.

BaseContour._get_clockwise()[source]

Subclasses must override this method.

BaseContour._get_identifier()

This is the environment implementation of BaseObject.identifier. This must return an Identifier. If the native object does not have an identifier assigned one should be assigned and returned.

Subclasses must override this method.

BaseContour._insertPoint(index, position, type='line', smooth=False, name=None, identifier=None, **kwargs)[source]

position will be a valid position (x, y). type will be a valid type. smooth will be a valid boolean. name will be a valid name or None. identifier will be a valid identifier or None. The identifier will not have been tested for uniqueness.

Subclasses must override this method.

BaseContour._lenPoints(**kwargs)[source]

This must return an integer indicating the number of points in the contour.

Subclasses must override this method.

BaseContour._removePoint(index, preserveCurve, **kwargs)[source]

index will be a valid index. preserveCurve will be a boolean.

Subclasses must override this method.

BaseContour._set_index(value)[source]

Subclasses must override this method.

May Override
BaseContour._appendBPoint(type, anchor, bcpIn=None, bcpOut=None, **kwargs)[source]

Subclasses may override this method.

BaseContour._appendSegment(type=None, points=None, smooth=False, **kwargs)[source]

Subclasses may override this method.

BaseContour._autoStartSegment(**kwargs)[source]

Subclasses may override this method.

XXX port this from robofab

BaseContour._draw(pen, **kwargs)[source]

Subclasses may override this method.

BaseContour._drawPoints(pen, **kwargs)[source]

Subclasses may override this method.

BaseContour._get_bounds()[source]

Subclasses may override this method.

BaseContour._get_index()[source]

Subclasses may override this method.

BaseContour._get_points()[source]

Subclasses may override this method.

BaseContour._get_segments()[source]

Subclasses may override this method.

BaseContour._init(*args, **kwargs)

Subclasses may override this method.

BaseContour._insertBPoint(index, type, anchor, bcpIn, bcpOut, **kwargs)[source]

Subclasses may override this method.

BaseContour._insertSegment(index=None, type=None, points=None, smooth=False, **kwargs)[source]

Subclasses may override this method.

BaseContour._len__segments(**kwargs)[source]

Subclasses may override this method.

BaseContour._moveBy(value, **kwargs)

This is the environment implementation of BaseObject.moveBy.

value will be an iterable containing two Integer/Float values defining the x and y values to move the object by. It will have been normalized with normalizers.normalizeTransformationOffset.

Subclasses may override this method.

BaseContour._pointInside(point)[source]

Subclasses may override this method.

BaseContour._removeSegment(segment, preserveCurve, **kwargs)[source]

segment will be a valid segment index. preserveCurve will be a boolean.

Subclasses may override this method.

BaseContour._reverse(**kwargs)[source]

Subclasses may override this method.

BaseContour._rotateBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.rotateBy.

value will be a Integer/Float value defining the value to rotate the object by. It will have been normalized with normalizers.normalizeRotationAngle. origin will be a Coordinate defining the point at which the rotation should orginate.

Subclasses may override this method.

BaseContour._round(**kwargs)[source]

Subclasses may override this method.

BaseContour._scaleBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.scaleBy.

value will be an iterable containing two Integer/Float values defining the x and y values to scale the object by. It will have been normalized with normalizers.normalizeTransformationScale. origin will be a Coordinate defining the point at which the scale should orginate.

Subclasses may override this method.

BaseContour._setStartSegment(segmentIndex, **kwargs)[source]

Subclasses may override this method.

BaseContour._set_clockwise(value)[source]

Subclasses may override this method.

BaseContour._skewBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.skewBy.

value will be an iterable containing two Integer/Float values defining the x and y values to skew the object by. It will have been normalized with normalizers.normalizeTransformationSkewAngle. origin will be a Coordinate defining the point at which the skew should orginate.

Subclasses may override this method.

BaseContour._transformBy(matrix, **kwargs)[source]

Subclasses may override this method.

Segment

Must Override
May Override
BaseSegment._getItem(index)[source]

Subclasses may override this method.

BaseSegment._get_base_offCurve()[source]

Subclasses may override this method.

BaseSegment._get_index()[source]

Subclasses may override this method.

BaseSegment._get_offCurve()[source]

Subclasses may override this method.

BaseSegment._get_onCurve()[source]

Subclasses may override this method.

BaseSegment._get_points()[source]

Subclasses may override this method.

BaseSegment._get_smooth()[source]

Subclasses may override this method.

BaseSegment._get_type()[source]

Subclasses may override this method.

BaseSegment._init(*args, **kwargs)

Subclasses may override this method.

BaseSegment._iterPoints(**kwargs)[source]

Subclasses may override this method.

BaseSegment._len(**kwargs)[source]

Subclasses may override this method.

BaseSegment._moveBy(value, **kwargs)

This is the environment implementation of BaseObject.moveBy.

value will be an iterable containing two Integer/Float values defining the x and y values to move the object by. It will have been normalized with normalizers.normalizeTransformationOffset.

Subclasses may override this method.

BaseSegment._rotateBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.rotateBy.

value will be a Integer/Float value defining the value to rotate the object by. It will have been normalized with normalizers.normalizeRotationAngle. origin will be a Coordinate defining the point at which the rotation should orginate.

Subclasses may override this method.

BaseSegment._scaleBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.scaleBy.

value will be an iterable containing two Integer/Float values defining the x and y values to scale the object by. It will have been normalized with normalizers.normalizeTransformationScale. origin will be a Coordinate defining the point at which the scale should orginate.

Subclasses may override this method.

BaseSegment._set_smooth(value)[source]

Subclasses may override this method.

BaseSegment._set_type(newType)[source]

Subclasses may override this method.

BaseSegment._skewBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.skewBy.

value will be an iterable containing two Integer/Float values defining the x and y values to skew the object by. It will have been normalized with normalizers.normalizeTransformationSkewAngle. origin will be a Coordinate defining the point at which the skew should orginate.

Subclasses may override this method.

BaseSegment._transformBy(matrix, **kwargs)[source]

Subclasses may override this method.

BaseSegment.copyData(source)

Subclasses may override this method. If so, they should call the super.

BPoint

Must Override
May Override
BaseBPoint._get_anchor()[source]

Subclasses may override this method.

BaseBPoint._get_bcpIn()[source]

Subclasses may override this method.

BaseBPoint._get_bcpOut()[source]

Subclasses may override this method.

BaseBPoint._get_index()[source]

Subclasses may override this method.

BaseBPoint._get_type()[source]

Subclasses may override this method.

BaseBPoint._init(*args, **kwargs)

Subclasses may override this method.

BaseBPoint._moveBy(value, **kwargs)

This is the environment implementation of BaseObject.moveBy.

value will be an iterable containing two Integer/Float values defining the x and y values to move the object by. It will have been normalized with normalizers.normalizeTransformationOffset.

Subclasses may override this method.

BaseBPoint._rotateBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.rotateBy.

value will be a Integer/Float value defining the value to rotate the object by. It will have been normalized with normalizers.normalizeRotationAngle. origin will be a Coordinate defining the point at which the rotation should orginate.

Subclasses may override this method.

BaseBPoint._scaleBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.scaleBy.

value will be an iterable containing two Integer/Float values defining the x and y values to scale the object by. It will have been normalized with normalizers.normalizeTransformationScale. origin will be a Coordinate defining the point at which the scale should orginate.

Subclasses may override this method.

BaseBPoint._set_anchor(value)[source]

Subclasses may override this method.

BaseBPoint._set_bcpIn(value)[source]

Subclasses may override this method.

BaseBPoint._set_bcpOut(value)[source]

Subclasses may override this method.

BaseBPoint._set_type(value)[source]

Subclasses may override this method.

BaseBPoint._skewBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.skewBy.

value will be an iterable containing two Integer/Float values defining the x and y values to skew the object by. It will have been normalized with normalizers.normalizeTransformationSkewAngle. origin will be a Coordinate defining the point at which the skew should orginate.

Subclasses may override this method.

BaseBPoint._transformBy(matrix, **kwargs)[source]

Subclasses may override this method.

BaseBPoint.copyData(source)

Subclasses may override this method. If so, they should call the super.

Point

Must Override
BasePoint._get_identifier()

This is the environment implementation of BaseObject.identifier. This must return an Identifier. If the native object does not have an identifier assigned one should be assigned and returned.

Subclasses must override this method.

BasePoint._get_name()[source]

This is the environment implementation of BasePoint.name. This must return a String or None. The returned value will be normalized with normalizers.normalizePointName.

Subclasses must override this method.

BasePoint._get_smooth()[source]

This is the environment implementation of BasePoint.smooth. This must return a bool indicating the smooth state.

Subclasses must override this method.

BasePoint._get_type()[source]

This is the environment implementation of BasePoint.type. This must return a String defining the point type.

Subclasses must override this method.

BasePoint._get_x()[source]

This is the environment implementation of BasePoint.x. This must return an Integer/Float.

Subclasses must override this method.

BasePoint._get_y()[source]

This is the environment implementation of BasePoint.y. This must return an Integer/Float.

Subclasses must override this method.

BasePoint._set_name(value)[source]

This is the environment implementation of BasePoint.name. value will be a String or None. It will have been normalized with normalizers.normalizePointName.

Subclasses must override this method.

BasePoint._set_smooth(value)[source]

This is the environment implementation of BasePoint.smooth. value will be a bool indicating the smooth state. It will have been normalized with normalizers.normalizeBoolean.

Subclasses must override this method.

BasePoint._set_type(value)[source]

This is the environment implementation of BasePoint.type. value will be a String defining the point type. It will have been normalized with normalizers.normalizePointType.

Subclasses must override this method.

BasePoint._set_x(value)[source]

This is the environment implementation of BasePoint.x. value will be an Integer/Float.

Subclasses must override this method.

BasePoint._set_y(value)[source]

This is the environment implementation of BasePoint.y. value will be an Integer/Float.

Subclasses must override this method.

May Override
BasePoint._get_index()[source]

Get the point’s index. This must return an int.

Subclasses may override this method.

BasePoint._init(*args, **kwargs)

Subclasses may override this method.

BasePoint._moveBy(value, **kwargs)

This is the environment implementation of BaseObject.moveBy.

value will be an iterable containing two Integer/Float values defining the x and y values to move the object by. It will have been normalized with normalizers.normalizeTransformationOffset.

Subclasses may override this method.

BasePoint._rotateBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.rotateBy.

value will be a Integer/Float value defining the value to rotate the object by. It will have been normalized with normalizers.normalizeRotationAngle. origin will be a Coordinate defining the point at which the rotation should orginate.

Subclasses may override this method.

BasePoint._round(**kwargs)[source]

This is the environment implementation of BasePoint.round.

Subclasses may override this method.

BasePoint._scaleBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.scaleBy.

value will be an iterable containing two Integer/Float values defining the x and y values to scale the object by. It will have been normalized with normalizers.normalizeTransformationScale. origin will be a Coordinate defining the point at which the scale should orginate.

Subclasses may override this method.

BasePoint._skewBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.skewBy.

value will be an iterable containing two Integer/Float values defining the x and y values to skew the object by. It will have been normalized with normalizers.normalizeTransformationSkewAngle. origin will be a Coordinate defining the point at which the skew should orginate.

Subclasses may override this method.

BasePoint._transformBy(matrix, **kwargs)[source]

This is the environment implementation of BasePoint.transformBy.

matrix will be a Transformation Matrix. that has been normalized with normalizers.normalizeTransformationMatrix.

Subclasses may override this method.

BasePoint.copyData(source)

Subclasses may override this method. If so, they should call the super.

Component

Must Override
BaseComponent._decompose()[source]

Subclasses must override this method.

BaseComponent._get_baseGlyph()[source]

Subclasses must override this method.

BaseComponent._get_identifier()

This is the environment implementation of BaseObject.identifier. This must return an Identifier. If the native object does not have an identifier assigned one should be assigned and returned.

Subclasses must override this method.

BaseComponent._get_transformation()[source]

Subclasses must override this method.

BaseComponent._set_baseGlyph(value)[source]

Subclasses must override this method.

BaseComponent._set_index(value)[source]

Subclasses must override this method.

BaseComponent._set_transformation(value)[source]

Subclasses must override this method.

May Override
BaseComponent._draw(pen, **kwargs)[source]

Subclasses may override this method.

BaseComponent._drawPoints(pen, **kwargs)[source]

Subclasses may override this method.

BaseComponent._get_bounds()[source]

Subclasses may override this method.

BaseComponent._get_index()[source]

Subclasses may override this method.

BaseComponent._get_offset()[source]

Subclasses may override this method.

BaseComponent._get_scale()[source]

Subclasses may override this method.

BaseComponent._init(*args, **kwargs)

Subclasses may override this method.

BaseComponent._moveBy(value, **kwargs)

This is the environment implementation of BaseObject.moveBy.

value will be an iterable containing two Integer/Float values defining the x and y values to move the object by. It will have been normalized with normalizers.normalizeTransformationOffset.

Subclasses may override this method.

BaseComponent._pointInside(point)[source]

Subclasses may override this method.

BaseComponent._rotateBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.rotateBy.

value will be a Integer/Float value defining the value to rotate the object by. It will have been normalized with normalizers.normalizeRotationAngle. origin will be a Coordinate defining the point at which the rotation should orginate.

Subclasses may override this method.

BaseComponent._round()[source]

Subclasses may override this method.

BaseComponent._scaleBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.scaleBy.

value will be an iterable containing two Integer/Float values defining the x and y values to scale the object by. It will have been normalized with normalizers.normalizeTransformationScale. origin will be a Coordinate defining the point at which the scale should orginate.

Subclasses may override this method.

BaseComponent._set_offset(value)[source]

Subclasses may override this method.

BaseComponent._set_scale(value)[source]

Subclasses may override this method.

BaseComponent._skewBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.skewBy.

value will be an iterable containing two Integer/Float values defining the x and y values to skew the object by. It will have been normalized with normalizers.normalizeTransformationSkewAngle. origin will be a Coordinate defining the point at which the skew should orginate.

Subclasses may override this method.

BaseComponent._transformBy(matrix, **kwargs)[source]

Subclasses may override this method.

BaseComponent.copyData(source)

Subclasses may override this method. If so, they should call the super.

Anchor

Must Override
BaseAnchor._get_color()[source]

This is the environment implementation of BaseAnchor.color. This must return a Color or None. The returned value will be normalized with normalizers.normalizeColor.

Subclasses must override this method.

BaseAnchor._get_identifier()

This is the environment implementation of BaseObject.identifier. This must return an Identifier. If the native object does not have an identifier assigned one should be assigned and returned.

Subclasses must override this method.

BaseAnchor._get_name()[source]

This is the environment implementation of BaseAnchor.name. This must return a String or None. The returned value will be normalized with normalizers.normalizeAnchorName.

Subclasses must override this method.

BaseAnchor._get_x()[source]

This is the environment implementation of BaseAnchor.x. This must return an Integer/Float.

Subclasses must override this method.

BaseAnchor._get_y()[source]

This is the environment implementation of BaseAnchor.y. This must return an Integer/Float.

Subclasses must override this method.

BaseAnchor._set_color(value)[source]

This is the environment implementation of BaseAnchor.color. value will be a Color or None. It will have been normalized with normalizers.normalizeColor.

Subclasses must override this method.

BaseAnchor._set_name(value)[source]

This is the environment implementation of BaseAnchor.name. value will be a String or None. It will have been normalized with normalizers.normalizeAnchorName.

Subclasses must override this method.

BaseAnchor._set_x(value)[source]

This is the environment implementation of BaseAnchor.x. value will be an Integer/Float.

Subclasses must override this method.

BaseAnchor._set_y(value)[source]

This is the environment implementation of BaseAnchor.y. value will be an Integer/Float.

Subclasses must override this method.

May Override
BaseAnchor._init(*args, **kwargs)

Subclasses may override this method.

BaseAnchor._moveBy(value, **kwargs)

This is the environment implementation of BaseObject.moveBy.

value will be an iterable containing two Integer/Float values defining the x and y values to move the object by. It will have been normalized with normalizers.normalizeTransformationOffset.

Subclasses may override this method.

BaseAnchor._rotateBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.rotateBy.

value will be a Integer/Float value defining the value to rotate the object by. It will have been normalized with normalizers.normalizeRotationAngle. origin will be a Coordinate defining the point at which the rotation should orginate.

Subclasses may override this method.

BaseAnchor._scaleBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.scaleBy.

value will be an iterable containing two Integer/Float values defining the x and y values to scale the object by. It will have been normalized with normalizers.normalizeTransformationScale. origin will be a Coordinate defining the point at which the scale should orginate.

Subclasses may override this method.

BaseAnchor._skewBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.skewBy.

value will be an iterable containing two Integer/Float values defining the x and y values to skew the object by. It will have been normalized with normalizers.normalizeTransformationSkewAngle. origin will be a Coordinate defining the point at which the skew should orginate.

Subclasses may override this method.

BaseAnchor._transformBy(matrix, **kwargs)[source]

This is the environment implementation of BaseAnchor.transformBy.

matrix will be a Transformation Matrix. that has been normalized with normalizers.normalizeTransformationMatrix.

Subclasses may override this method.

BaseAnchor.copyData(source)

Subclasses may override this method. If so, they should call the super.

Guideline

Must Override
BaseGuideline._get_angle()[source]

This is the environment implementation of BaseGuideline.angle. This must return an Angle.

Subclasses must override this method.

BaseGuideline._get_color()[source]

This is the environment implementation of BaseGuideline.color. This must return a Color or None. The returned value will be normalized with normalizers.normalizeColor.

Subclasses must override this method.

BaseGuideline._get_identifier()

This is the environment implementation of BaseObject.identifier. This must return an Identifier. If the native object does not have an identifier assigned one should be assigned and returned.

Subclasses must override this method.

BaseGuideline._get_name()[source]

This is the environment implementation of BaseGuideline.name. This must return a String or None. The returned value will be normalized with normalizers.normalizeGuidelineName.

Subclasses must override this method.

BaseGuideline._get_x()[source]

This is the environment implementation of BaseGuideline.x. This must return an Integer/Float.

Subclasses must override this method.

BaseGuideline._get_y()[source]

This is the environment implementation of BaseGuideline.y. This must return an Integer/Float.

Subclasses must override this method.

BaseGuideline._set_angle(value)[source]

This is the environment implementation of BaseGuideline.angle. value will be an Angle.

Subclasses must override this method.

BaseGuideline._set_color(value)[source]

This is the environment implementation of BaseGuideline.color. value will be a Color or None. It will have been normalized with normalizers.normalizeColor.

Subclasses must override this method.

BaseGuideline._set_name(value)[source]

This is the environment implementation of BaseGuideline.name. value will be a String or None. It will have been normalized with normalizers.normalizeGuidelineName.

Subclasses must override this method.

BaseGuideline._set_x(value)[source]

This is the environment implementation of BaseGuideline.x. value will be an Integer/Float.

Subclasses must override this method.

BaseGuideline._set_y(value)[source]

This is the environment implementation of BaseGuideline.y. value will be an Integer/Float.

Subclasses must override this method.

May Override
BaseGuideline._get_index()[source]

Get the guideline’s index. This must return an int.

Subclasses may override this method.

BaseGuideline._init(*args, **kwargs)

Subclasses may override this method.

BaseGuideline._moveBy(value, **kwargs)

This is the environment implementation of BaseObject.moveBy.

value will be an iterable containing two Integer/Float values defining the x and y values to move the object by. It will have been normalized with normalizers.normalizeTransformationOffset.

Subclasses may override this method.

BaseGuideline._rotateBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.rotateBy.

value will be a Integer/Float value defining the value to rotate the object by. It will have been normalized with normalizers.normalizeRotationAngle. origin will be a Coordinate defining the point at which the rotation should orginate.

Subclasses may override this method.

BaseGuideline._round(**kwargs)[source]

This is the environment implementation of BaseGuideline.round.

Subclasses may override this method.

BaseGuideline._scaleBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.scaleBy.

value will be an iterable containing two Integer/Float values defining the x and y values to scale the object by. It will have been normalized with normalizers.normalizeTransformationScale. origin will be a Coordinate defining the point at which the scale should orginate.

Subclasses may override this method.

BaseGuideline._skewBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.skewBy.

value will be an iterable containing two Integer/Float values defining the x and y values to skew the object by. It will have been normalized with normalizers.normalizeTransformationSkewAngle. origin will be a Coordinate defining the point at which the skew should orginate.

Subclasses may override this method.

BaseGuideline._transformBy(matrix, **kwargs)[source]

This is the environment implementation of BaseGuideline.transformBy.

matrix will be a Transformation Matrix. that has been normalized with normalizers.normalizeTransformationMatrix.

Subclasses may override this method.

BaseGuideline.copyData(source)

Subclasses may override this method. If so, they should call the super.

Image

Must Override
BaseImage._get_color()[source]

Return the color value as a color tuple or None.

Subclasses must override this method.

BaseImage._get_data()[source]

This must return raw byte data.

Subclasses must override this method.

BaseImage._get_transformation()[source]

Subclasses must override this method.

BaseImage._set_color(value)[source]

value will be a color tuple or None.

Subclasses must override this method.

BaseImage._set_data(value)[source]

value will be raw byte data.

Subclasses must override this method.

BaseImage._set_transformation(value)[source]

Subclasses must override this method.

May Override
BaseImage._get_offset()[source]

Subclasses may override this method.

BaseImage._get_scale()[source]

Subclasses may override this method.

BaseImage._init(*args, **kwargs)

Subclasses may override this method.

BaseImage._moveBy(value, **kwargs)

This is the environment implementation of BaseObject.moveBy.

value will be an iterable containing two Integer/Float values defining the x and y values to move the object by. It will have been normalized with normalizers.normalizeTransformationOffset.

Subclasses may override this method.

BaseImage._rotateBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.rotateBy.

value will be a Integer/Float value defining the value to rotate the object by. It will have been normalized with normalizers.normalizeRotationAngle. origin will be a Coordinate defining the point at which the rotation should orginate.

Subclasses may override this method.

BaseImage._round()[source]

Subclasses may override this method.

BaseImage._scaleBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.scaleBy.

value will be an iterable containing two Integer/Float values defining the x and y values to scale the object by. It will have been normalized with normalizers.normalizeTransformationScale. origin will be a Coordinate defining the point at which the scale should orginate.

Subclasses may override this method.

BaseImage._set_offset(value)[source]

Subclasses may override this method.

BaseImage._set_scale(value)[source]

Subclasses may override this method.

BaseImage._skewBy(value, origin=None, **kwargs)

This is the environment implementation of BaseObject.skewBy.

value will be an iterable containing two Integer/Float values defining the x and y values to skew the object by. It will have been normalized with normalizers.normalizeTransformationSkewAngle. origin will be a Coordinate defining the point at which the skew should orginate.

Subclasses may override this method.

BaseImage._transformBy(matrix, **kwargs)[source]

Subclasses may override this method.

BaseImage.copyData(source)

Subclasses may override this method. If so, they should call the super.

Each of these require their own specific environment overrides, but the general structure follows this form:

from fontParts.base import BaseSomething

class MySomething(BaseSomething):

    # Initialization.
    # This will be called when objects are initialized.
    # The behavior, args and kwargs may be designed by the
    # subclass to implement specific behaviors.

    def _init(self, myObj):
        self.myObj = myObj

    # Comparison.
    # The __eq__ method must be implemented by subclasses.
    # It must return a boolean indicating if the lower level
    # objects are the same object. This does not mean that two
    # objects that have the same content should be considered
    # equal. It means that the object must be the same. The
    # corrilary __ne__ is optional to define.
    #
    # Note that the base implentation of fontParts provides
    # __eq__ and __ne__ methods that test the naked objects
    # for equality. Depending on environmental needs this can
    # be overridden.

    def __eq__(self, other):
        return self.myObj == other.myObj

    def __ne__(self, other):
        return self.myObj != other.myObj

    # Properties.
    # Properties are get and set through standard method names.
    # Within these methods, the subclass may do whatever is
    #   necessary to get/set the value from/to the environment.

    def _get_something(self):
        return self.myObj.getSomething()

    def _set_something(self, value):
        self.myObj.setSomething(value)

    # Methods.
    # Generally, the public methods call internal methods with
    # the same name, but preceded with an underscore. Subclasses
    # may implement the internal method. Any values passed to
    # the internal methods will have been normalized and will
    # be a standard type.

    def _whatever(self, value):
        self.myObj.doWhatever(value)

    # Copying.
    # Copying is handled in most cases by the base objects.
    # If subclasses have a special class that should be used
    # when creating a copy of an object, the class must be
    # defined with the copyClass attribute. If anything special
    # needs to be done during the copying process, the subclass
    # can implement the copyData method. This method will be
    # called automatically. The subclass must call the base class
    # method with super.

    copyClass = MyObjectWithoutUI

    def copyData(self, source):
        super(MySomething, self).copyData(source)
        self.myObj.internalThing = source.internalThing

    # Environment updating.
    # If the environment requires the scripter to manually
    # notify the environment that the object has been changed,
    # the subclass must implement the changed method. Please
    # try to avoid requiring this.

    def changed(self):
        myEnv.goUpdateYourself()

    # Wrapped objects.
    # It is very useful for scripters to have access to the
    # lower level, wrapped object. Subclasses implement this
    # with the naked method.

    def naked(self):
        return self.myObj

All methods that must be overridden are labeled with “Subclasses must override this method.” in the method’s documentation string. If a method may optionally be overridden, the documentation string is labeled with “Subclasses may override this method.” All other methods, attributes and properties must not be overridden.

An example implementation that wraps the defcon library with fontParts is located in fontParts/objects/fontshell.

Data Normalization

When possible, incoming and outgoing values are checked for type validity and are coerced to a common type for return. This is done with a set of functions located here:

These are done in a central place rather than within the objects for consitency. There are many cases where a (x, y) tuple is defined and than rewriting all of the code to check if there are exactly two values, that each is an int or a float and so on before finally making sure that the value to be returned is a tuple not an instance of list, OrderedDict or some native object we consolidate the code into a single function and call that.

Environment Specific Methods, Attributes and Arguments

FontParts is designed to be environment agnostic. Therefore, it is a 100% certainty that it doesn’t do something that your environment does. You will want to allow your environment’s something to be accessible through FontParts. We want you to allow this, too. The problem is, how do you implement something in a way that doesn’t conflict with current or future things in FontParts? For example, let’s say that you want to add a support for the “Do Something to the Font” feature you have built in your environment. You add a new method to support this:

class MyFont(BaseFont):

  def doSomething(self, skip=None, double=None):
    # go

This will work. However, if FontParts adds a doSomething method in a later version that does something other than what or accepts different arguments than your method does, it’s not going to work. Either the doSomething method will have to be changed in your implementation or you will not support the FontParts doSomething method. This is going to be lead to you being mad at FontParts, your scripters being mad at you or something else unpleasant.

The solution to this problem is to prevent it from happening in the first place. To do this, environment specific methods, proprties and attributes must be prefixed with an environment specific tag followed by an _ and then your method name. For example:

class MyFont(BaseFont):

  def myapp_doSomething(self, skip=None, double=None):
    # go

This applies to any method, attribute or property additions to the FontParts objects. The environment tag is up to you. The only requirement is that it needs to be unique to your own environment.

Method Arguments

In some cases, you are likely to discover that your environment supports specific options in a method that are not supported by the environment agnostic API. For example, your environment may have an optional heuristic that can be used in the font.autoUnicodes method. However, the font.autoUnicodes method does not have a useHeuristics argument. Unfortunately, Python doesn’t offer a way to handle this in a way that is both flexible for developers and friendly for scripters. The only two options for handling this are:

  1. Create an environment specific clone of the font.autoUnicodes method as myapp_autoUnicodes and add your useHeuristics argument there.
  2. Contact the FontParts developers by opening a GitHub issue requesting support for your argument. If it is generic enough, we may add support for it.

We’re experimenting with a third way to handle this. You can see it as the **environmentOptions argument in the BaseFont.generate method. This may or may not move to other methods. Please contact us if you are interested in this being applied to other methods.

Layers

There are two primary layer models in the font world:

  • font level layers: In this model, all glyphs have the same layers. A good example of this is a chromatic font.
  • glyph level layers: In this model, individual glyphs may have their own unique layers.

fontParts supports both of these models. Both fonts and glyphs have fully developed layer APIs:

font = CurrentFont()
foregroundLayer = font.getLayer("foreground")
backgroundLayer = font.getLayer("background")

glyph = font["A"]
foregroundGlyph = glyph.getLayer("foreground")
backgroundGlyph = glyph.getLayer("background")

A font-level layer is a font-like object. Essentially, a layer has the same glyph management behavior as a font:

font = CurrentFont()
foreground = font.getLayer("foreground")
glyph = foreground.newGlyph("A")

A glyph-level layer is identical to a glyph object:

font = CurrentFont()
glyph = font["A"]
foreground = glyph.getLayer("foreground")
background = glyph.getLayer("background")

When a scripter is addressing a font or glyph without specifying a specific layer, the action is performed on the “default” (or primary) layer. For example, in the original Fontographer there were two layers: foreground and background. The foreground was the primary layer and it contained the primary data that would be compiled into a font binary. In multi-layered glyph editing environments, designers can specify which layer should be considered primary. This layer is the “default” layer in fontParts. Thus:

font = CurrentFont()
glyph1 = font["A"]
glyph2 = font.newGlyph("B")

The glyph1 object will reference the A’s “foreground” layer and the “foreground” layer will contain a new glyph named “B”.

fontParts delegates the implementation to the environment subclasses. Given that an environment can only support font-level layers or glyph-level layers, the following algorithms can be used to simulate the model that the environment doesn’t support.

Simulating glyph-level layers.

  1. Get the parent font.
  2. Iterate through all of the font’s layers.
  3. If the glyph’s name is in the layer, grab the glyph from the layer.
  4. Return all found glyphs.

Simulating font-level layers.

  1. Iterate over all glyphs.
  2. For every layer in the glyph, create a global mapping of layer name to glyphs containing a layer with the same name.

Developing FontParts

You want to help with developing FontParts? Yay!

We are mostly focused on documenting the objects and building a test suite. We’ll eventually need bits of code here and there. If you have an idea for a new API or want to discuss one of the testing APIs, cool.

Proposals

Want to suggest a new font part for FontParts? It’s best to do this as an issue on the FontParts GitHub repository. Please present why you think this needs to be added. Before you do so, please make sure you understand the goals of the project, the existing API and so on.

Bug Reports

Notice a bug when using FontParts? Is it a bug in a specific application? If so, please report the bug to the application developer. If it’s not specific to a particular application, please open an issue on GitHub or, if you really can’t open an issue on GitHub, send a message to the RoboFab mailing list

Coding

Take a look at the open issues and see if there is anything there that you want to work on. Please try to follow the general coding style of the library so that everything has the same level of readability.

This library follows much of PEP8, with a couple of exceptions. You’ll see camelCase. We like camelCase. The standard line length is also 90 characters. If possible, try to keep lines to 80, but 90 comes in handy occasionally. You’ll also notice that some builtin names are redefined in as variables in methods. It’s impossible not to use type in a package dealing with fonts.

Writing Documentation

We really need help with adding the formatted documentation strings to the base objects. The API documentation is generated from those. Here’s a style guide. Please look at the Documentation project on GitHub and see if there is anything you want to work on. If there is, ask to be assigned to that issue, and then follow the style guide. A good place to look for examples of the object documentation is the glyph object.

Test Suite

We also really need help in finishing up the test suite. You can see what needs to be done in the Tests project on GitHub. Pick something you want to write tests for and ask to be assigned to that issue. More information about writing tests is here.

PK{UH'fontparts-stable/_static/up-pressed.pngPNG  IHDRaIDATxc o+ Sb)SbG&W +H,Cق n;"VsT?.#&ھjFcgb ..NG`49l* Ŀ'q< *]Jcyjؖf b0Sԙµ|IENDB`PK{U)RR"fontparts-stable/_static/jquery.js/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ !function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("