Implementation of BaseLayerSet and RLayerSet.
git-svn-id: http://svn.robofab.com/branches/ufo3k@531 b5fa9d6c-a76f-4ffd-b3cb-f825fc41095c
This commit is contained in:
parent
38b8c8fb68
commit
2185d7df25
@ -264,8 +264,21 @@ class BaseFont(RBaseObject):
|
||||
|
||||
class BaseLayerSet(RBaseObject):
|
||||
|
||||
# layer creation, destruction and retrieval
|
||||
|
||||
def getLayer(self, layerName):
|
||||
raise NotImplementedError
|
||||
|
||||
def __contains__(self, layerName):
|
||||
raise NotImplementedError
|
||||
|
||||
has_key = __contains__
|
||||
|
||||
def __getitem__(self, layerName):
|
||||
pass
|
||||
raise NotImplementedError
|
||||
|
||||
def __iter__(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def newLayer(self, layerName):
|
||||
raise NotImplementedError
|
||||
@ -301,10 +314,6 @@ class BaseLayer(RBaseObject):
|
||||
|
||||
"""Base class for all Layer objects."""
|
||||
|
||||
def __init__(self):
|
||||
RBaseObject.__init__(self)
|
||||
self.changed = False # if the object needs to be saved
|
||||
|
||||
# XXX def __repr__(self):
|
||||
|
||||
def getGlyph(self, glyphName):
|
||||
|
@ -7,11 +7,12 @@ To Do:
|
||||
- in BaseKerning.__init__ use if kerningDict is None
|
||||
- make BaseGroups subclass BaseObject like BaseKerning does?
|
||||
- add __contains__ to all dict-like base objects
|
||||
- get right of BaseGroups.findGlyph
|
||||
- get rid of BaseGroups.findGlyph
|
||||
- BaseObject.naked expects the wrapped object to be stored at ._object.
|
||||
this is not always true.
|
||||
- what should be done about the PSHint objects?
|
||||
- the repr methods in ObjectsBase use odd font.info name values
|
||||
- how will obj.copy() work here?
|
||||
|
||||
|
||||
I'm trying to find a way to make it possible for defcon based
|
||||
@ -26,7 +27,8 @@ a basic defcon font or a defcon.Font (or subclass) object to be wrapped.
|
||||
import os
|
||||
from defcon import Font as DefconFont
|
||||
from robofab import RoboFabError, RoboFabWarning
|
||||
from robofab.objects.objectsBase import RBaseObject, BaseFont, BaseKerning, BaseGroups, BaseInfo, BaseFeatures, BaseLib,\
|
||||
from robofab.objects.objectsBase import RBaseObject, BaseFont, BaseLayerSet, \
|
||||
BaseKerning, BaseGroups, BaseInfo, BaseFeatures, BaseLib,\
|
||||
BaseGlyph, BaseContour, BaseSegment, BasePoint, BaseBPoint, BaseAnchor, BaseGuide, BaseComponent, \
|
||||
relativeBCPIn, relativeBCPOut, absoluteBCPIn, absoluteBCPOut, _box,\
|
||||
_interpolate, _interpolatePt, roundPt, addPt,\
|
||||
@ -97,6 +99,7 @@ class RFont(BaseFont):
|
||||
self._object = path
|
||||
else:
|
||||
self._object = DefconFont(path)
|
||||
self._layers = None
|
||||
self._info = None
|
||||
self._kerning = None
|
||||
self._groups = None
|
||||
@ -106,6 +109,9 @@ class RFont(BaseFont):
|
||||
|
||||
# Object Classes
|
||||
|
||||
def layersClass(self):
|
||||
return RLayerSet
|
||||
|
||||
def infoClass(self):
|
||||
return RInfo
|
||||
|
||||
@ -123,6 +129,13 @@ class RFont(BaseFont):
|
||||
|
||||
# Sub-Objects
|
||||
|
||||
def _get_layers(self):
|
||||
if self._layers is None:
|
||||
self._layers = self.layersClass()(self._object.layers)
|
||||
return self._layers
|
||||
|
||||
layers = property(_get_layers)
|
||||
|
||||
def _get_info(self):
|
||||
if self._info is None:
|
||||
self._info = self.infoClass()(self._object.info)
|
||||
@ -170,12 +183,10 @@ class RFont(BaseFont):
|
||||
# return 0
|
||||
# else:
|
||||
# return -1
|
||||
#
|
||||
# def __len__(self):
|
||||
# if self._glyphSet is None:
|
||||
# return 0
|
||||
# return len(self._glyphSet)
|
||||
#
|
||||
|
||||
def __len__(self):
|
||||
return len(self._object)
|
||||
|
||||
# def _loadData(self, path):
|
||||
# from ufoLib import UFOReader
|
||||
# reader = UFOReader(path)
|
||||
@ -576,7 +587,133 @@ class RFont(BaseFont):
|
||||
# raise KeyError, glyphName
|
||||
# return n
|
||||
#
|
||||
#
|
||||
|
||||
# --------
|
||||
# LayerSet
|
||||
# --------
|
||||
|
||||
class RLayerSet(BaseLayerSet):
|
||||
|
||||
def __init__(self, layerSet):
|
||||
super(RLayerSet, self).__init__()
|
||||
self._object = layerSet
|
||||
|
||||
def layerClass(self):
|
||||
return RLayer
|
||||
|
||||
# layer creation, destruction and retrieval
|
||||
|
||||
def __contains__(self, layerName):
|
||||
return layerName in self._object
|
||||
|
||||
has_key = __contains__
|
||||
|
||||
def getLayer(self, layerName):
|
||||
if layerName not in self._object:
|
||||
raise KeyError("Font does not have a layer named %s." % layerName)
|
||||
return self.layerClass()(self._object[layerName])
|
||||
|
||||
def __getitem__(self, layerName):
|
||||
return self.getLayer(layerName)
|
||||
|
||||
def __iter__(self):
|
||||
for layerName in self.getLayerOrder():
|
||||
yield self.getLayer(layerName)
|
||||
|
||||
def newLayer(self, layerName):
|
||||
assert layerName not in self._object
|
||||
self._object.newLayer(layerName)
|
||||
return self.getLayer(layerName)
|
||||
|
||||
def removeLayer(self, layerName):
|
||||
layer = self.getLayer(layerName)
|
||||
del self._object[layerName]
|
||||
|
||||
# layer names
|
||||
|
||||
def keys(self):
|
||||
return self._object.layerOrder()
|
||||
|
||||
def getLayerOrder(self):
|
||||
return self._object.layerOrder()
|
||||
|
||||
def setLayerOrder(self, order):
|
||||
self._object.layerOrder = order
|
||||
|
||||
# default layer
|
||||
|
||||
def getDefaultLayer(self):
|
||||
layerName = self._object.defaultLayer.name
|
||||
return self[layerName]
|
||||
|
||||
def setDefaultLayer(self, layer):
|
||||
naked = layer.naked()
|
||||
found = False
|
||||
for l in self._object:
|
||||
if l == naked:
|
||||
found = True
|
||||
break
|
||||
assert found, "The layer being set as the default must already belong to the font."
|
||||
self._object.setDefaultLayer(naked)
|
||||
|
||||
# -----
|
||||
# Layer
|
||||
# -----
|
||||
|
||||
class BaseLayer(RBaseObject):
|
||||
|
||||
"""Base class for all Layer objects."""
|
||||
|
||||
def __init__(self):
|
||||
RBaseObject.__init__(self)
|
||||
self.changed = False # if the object needs to be saved
|
||||
|
||||
# XXX def __repr__(self):
|
||||
|
||||
def getGlyph(self, glyphName):
|
||||
raise NotImplementedError
|
||||
|
||||
def newGlyph(self, glyphName, clear=True):
|
||||
raise NotImplementedError
|
||||
|
||||
def insertGlyph(self, glyph, name=None):
|
||||
raise NotImplementedError
|
||||
|
||||
def removeGlyph(self, glyphName):
|
||||
raise NotImplementedError
|
||||
|
||||
# dict behavior
|
||||
|
||||
def keys(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def has_key(self):
|
||||
raise NotImplementedError
|
||||
|
||||
# dynamic data extraction
|
||||
|
||||
def getCharacterMapping(self):
|
||||
"""Create a dictionary of unicode -> [glyphname, ...] mappings.
|
||||
Note that this dict is created each time this method is called,
|
||||
which can make it expensive for larger fonts. All glyphs are loaded.
|
||||
Note that one glyph can have multiple unicode values,
|
||||
and a unicode value can have multiple glyphs pointing to it."""
|
||||
return dict(self._object.unicodeData)
|
||||
|
||||
def getReverseComponentMapping(self):
|
||||
"""
|
||||
Get a reversed map of component references in the font.
|
||||
{
|
||||
'A' : ['Aacute', 'Aring']
|
||||
'acute' : ['Aacute']
|
||||
'ring' : ['Aring']
|
||||
etc.
|
||||
}
|
||||
"""
|
||||
return self._object.componentReferences
|
||||
|
||||
|
||||
|
||||
#class RGlyph(BaseGlyph):
|
||||
#
|
||||
# _title = "RGlyph"
|
||||
@ -1395,6 +1532,7 @@ if __name__ == "__main__":
|
||||
from defcon.test.testTools import getTestFontPath
|
||||
font = RFont(getTestFontPath())
|
||||
print font
|
||||
print font.layers
|
||||
print font.info
|
||||
print font.groups
|
||||
print font.kerning
|
||||
|
Loading…
x
Reference in New Issue
Block a user