Changeset 547

Show
Ignore:
Timestamp:
01/27/12 08:15:48 (4 months ago)
Author:
tal
Message:

Further implementation of these objects by Frederik.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/ufo3k/Lib/robofab/objects/objectsDefcon.py

    r544 r547  
     1#! /usr/local/bin/apppython 
     2 
    13""" 
    24This is the new doc for the objectsRF module. 
     
    1921    Contour subclass). a way around this would be to test isinstance(incoming, self.objClass()) 
    2022    during all insertion methods. 
     23f -------> or defcon should have a copy() and setting all the subclasses correctly  
     24 
    2125- need to work out how selected will work in these objects 
     26f -------> why its a bool, subclasses should overwrite it with a property thing if they wants to use  
     27 
    2228- note somewhere that the various get* methods should not be used externally 
    2329  (they are only public because getGLyph was left public in RFont back in the day) 
     
    2834- what should happen to anchors in BaseGlyph.appendGlyph? 
    2935- what should be done with the anchor mark (used in appendAnchor and probably elsewhere)? 
     36f -------> ignore it or can be converted to a color object 
     37 
    3038 
    3139I'm trying to find a way to make it possible for defcon based 
     
    4452""" 
    4553 
     54 
    4655import os 
     56import weakref 
    4757from defcon import Font as DefconFont 
    4858from robofab import RoboFabError, RoboFabWarning 
     
    876886        def __getitem__(self, index): 
    877887                if index < len(self._object): 
    878                         return self._getContour(index) 
     888                        return self.getContour(index) 
    879889                raise IndexError 
    880890 
     
    972982                self._object.drawPoints(pointPen) 
    973983 
     984# ------- 
     985# Contour 
     986# ------- 
    974987 
    975988class RContour(BaseContour): 
     
    10311044 
    10321045        def getPoint(self, point): 
    1033                 return point 
     1046                rPoint = self.pointClass()(point) 
     1047                rPoint.getSegment = self.getSegment 
     1048                rPoint._setDefconContour(self._object) 
     1049                return rPoint 
    10341050 
    10351051        def _get_points(self): 
     
    10441060 
    10451061        def getSegment(self, points): 
    1046                 return self.segmentClass()(points) 
     1062                segment = self.segmentClass()(points=points) 
     1063                segment.getPoint = self.getPoint 
     1064                segment._RContourClass = self.__class__ 
     1065                segment._setDefconContour(self._object) 
     1066                return segment 
    10471067 
    10481068        def _get_segments(self): 
     
    10971117                self._object.setStartPoint(index) 
    10981118 
    1099  
    11001119        # bPoints 
    11011120 
    1102 #       def _get_bPoints(self): 
    1103 #               bPoints = [] 
    1104 #               for segment in self.segments: 
    1105 #                       segType = segment.type 
    1106 #                       if segType == MOVE: 
    1107 #                               bType = CORNER 
    1108 #                       elif segType == LINE: 
    1109 #                               bType = CORNER 
    1110 #                       elif segType == CURVE: 
    1111 #                               if segment.smooth: 
    1112 #                                       bType = CURVE 
    1113 #                               else: 
    1114 #                                       bType = CORNER 
    1115 #                       else: 
    1116 #                               raise RoboFabError, "encountered unknown segment type" 
    1117 #                       b = RBPoint() 
    1118 #                       b.setParent(segment) 
    1119 #                       bPoints.append(b) 
    1120 #               return bPoints 
    1121 
    1122 #       bPoints = property(_get_bPoints, doc="view the contour as a list of bPoints") 
     1121        def bPointClass(self): 
     1122                return RBPoint 
     1123 
     1124        def getBPoint(self, point): 
     1125                bPoint = self.bPointClass()(point) 
     1126                bPoint.getSegment = self.getSegment 
     1127                bPoint.getPoint = self.getPoint 
     1128                bPoint._RContourClass = self.__class__ 
     1129                bPoint._setDefconContour(self._object) 
     1130                return bPoint 
     1131 
     1132        def _get_bPoints(self): 
     1133                return [self.getBPoint(point) for point in self._object.onCurvePoints] 
     1134         
     1135        bPoints = property(_get_bPoints, doc="view the contour as a list of bPoints") 
    11231136 
    11241137        # Drawing 
     
    11301143                self._object.drawPoints(pointPen) 
    11311144 
    1132  
    1133  
    1134 #class RSegment(BaseSegment): 
    1135 #        
    1136 #       _title = "RoboFabSegment" 
    1137 #        
    1138 #       def __init__(self, segmentType=None, points=[], smooth=False): 
    1139 #               BaseSegment.__init__(self) 
    1140 #               self.selected = False 
    1141 #               self.points = [] 
    1142 #               self.smooth = smooth 
    1143 #               if points: 
    1144 #                       #the points in the segment should be RPoints, so create those objects 
    1145 #                       for point in points[:-1]: 
    1146 #                               x, y = point 
    1147 #                               p = RPoint(x, y, pointType=OFFCURVE) 
    1148 #                               p.setParent(self) 
    1149 #                               self.points.append(p) 
    1150 #                       aX, aY = points[-1] 
    1151 #                       p = RPoint(aX, aY, segmentType) 
    1152 #                       p.setParent(self) 
    1153 #                       self.points.append(p) 
    1154 #                
    1155 #       def _get_type(self): 
    1156 #               return self.points[-1].type 
    1157 #        
    1158 #       def _set_type(self, pointType): 
    1159 #               onCurve = self.points[-1] 
    1160 #               ocType = onCurve.type 
    1161 #               if ocType == pointType: 
    1162 #                       return 
    1163 #               #we are converting a cubic line into a cubic curve 
    1164 #               if pointType == CURVE and  ocType == LINE: 
    1165 #                       onCurve.type = pointType 
    1166 #                       parent = self.getParent() 
    1167 #                       prev = parent._prevSegment(self.index) 
    1168 #                       p1 = RPoint(prev.onCurve.x, prev.onCurve.y, pointType=OFFCURVE) 
    1169 #                       p1.setParent(self) 
    1170 #                       p2 = RPoint(onCurve.x, onCurve.y, pointType=OFFCURVE) 
    1171 #                       p2.setParent(self) 
    1172 #                       self.points.insert(0, p2) 
    1173 #                       self.points.insert(0, p1) 
    1174 #               #we are converting a cubic move to a curve 
    1175 #               elif pointType == CURVE and ocType == MOVE: 
    1176 #                       onCurve.type = pointType 
    1177 #                       parent = self.getParent() 
    1178 #                       prev = parent._prevSegment(self.index) 
    1179 #                       p1 = RPoint(prev.onCurve.x, prev.onCurve.y, pointType=OFFCURVE) 
    1180 #                       p1.setParent(self) 
    1181 #                       p2 = RPoint(onCurve.x, onCurve.y, pointType=OFFCURVE) 
    1182 #                       p2.setParent(self) 
    1183 #                       self.points.insert(0, p2) 
    1184 #                       self.points.insert(0, p1) 
    1185 #               #we are converting a quad curve to a cubic curve 
    1186 #               elif pointType == CURVE and ocType == QCURVE: 
    1187 #                       onCurve.type == CURVE 
    1188 #               #we are converting a cubic curve into a cubic line 
    1189 #               elif pointType == LINE and ocType == CURVE: 
    1190 #                       p = self.points.pop(-1) 
    1191 #                       self.points = [p] 
    1192 #                       onCurve.type = pointType 
    1193 #                       self.smooth = False 
    1194 #               #we are converting a cubic move to a line 
    1195 #               elif pointType == LINE and ocType == MOVE: 
    1196 #                       onCurve.type = pointType 
    1197 #               #we are converting a quad curve to a line: 
    1198 #               elif pointType == LINE and ocType == QCURVE: 
    1199 #                       p = self.points.pop(-1) 
    1200 #                       self.points = [p] 
    1201 #                       onCurve.type = pointType 
    1202 #                       self.smooth = False      
    1203 #               # we are converting to a quad curve where just about anything is legal 
    1204 #               elif pointType == QCURVE: 
    1205 #                       onCurve.type = pointType 
    1206 #               else: 
    1207 #                       raise RoboFabError, 'unknown segment type' 
    1208 #                        
    1209 #       type = property(_get_type, _set_type, doc="type of the segment") 
    1210 #        
    1211 #       def _get_index(self): 
    1212 #               return self.getParent().segments.index(self) 
    1213 #                
    1214 #       index = property(_get_index, doc="index of the segment") 
    1215 #        
    1216 #       def insertPoint(self, index, pointType, point): 
    1217 #               x, y = point 
    1218 #               p = RPoint(x, y, pointType=pointType) 
    1219 #               p.setParent(self) 
    1220 #               self.points.insert(index, p) 
    1221 #               self._hasChanged() 
    1222 #        
    1223 #       def removePoint(self, index): 
    1224 #               del self.points[index] 
    1225 #               self._hasChanged() 
    1226 #                
    1227 
    1228 #class RBPoint(BaseBPoint): 
    1229 #        
    1230 #       _title = "RoboFabBPoint" 
    1231 #                
    1232 #       def _setAnchorChanged(self, value): 
    1233 #               self._anchorPoint.setChanged(value) 
    1234 #        
    1235 #       def _setNextChanged(self, value): 
    1236 #               self._nextOnCurve.setChanged(value)      
    1237 #                
    1238 #       def _get__parentSegment(self): 
    1239 #               return self.getParent() 
    1240 #                
    1241 #       _parentSegment = property(_get__parentSegment, doc="") 
    1242 #        
    1243 #       def _get__nextOnCurve(self): 
    1244 #               pSeg = self._parentSegment 
    1245 #               contour = pSeg.getParent() 
    1246 #               #could this potentially return an incorrect index? say, if two segments are exactly the same? 
    1247 #               return contour.segments[(contour.segments.index(pSeg) + 1) % len(contour.segments)] 
    1248 #        
    1249 #       _nextOnCurve = property(_get__nextOnCurve, doc="") 
    1250 #        
    1251 #       def _get_index(self): 
    1252 #               return self._parentSegment.index 
    1253 #        
    1254 #       index = property(_get_index, doc="index of the bPoint on the contour") 
    1255 
    1256 
    1257 #class RPoint(BasePoint): 
    1258 #        
    1259 #       _title = "RoboFabPoint" 
    1260 #        
    1261 #       def __init__(self, x=0, y=0, pointType=None, name=None): 
    1262 #               self.selected = False 
    1263 #               self._type = pointType 
    1264 #               self._x = x 
    1265 #               self._y = y 
    1266 #               self._name = None 
    1267 #                
    1268 #       def _get_x(self): 
    1269 #               return self._x 
    1270 #                
    1271 #       def _set_x(self, value): 
    1272 #               self._x = value 
    1273 #               self._hasChanged() 
    1274 #        
    1275 #       x = property(_get_x, _set_x, doc="") 
    1276 
    1277 #       def _get_y(self): 
    1278 #               return self._y 
    1279 #        
    1280 #       def _set_y(self, value): 
    1281 #               self._y = value 
    1282 #               self._hasChanged() 
    1283 
    1284 #       y = property(_get_y, _set_y, doc="") 
    1285 #        
    1286 #       def _get_type(self): 
    1287 #               return self._type 
    1288 #        
    1289 #       def _set_type(self, value): 
    1290 #               self._type = value 
    1291 #               self._hasChanged() 
    1292 
    1293 #       type = property(_get_type, _set_type, doc="") 
    1294 #        
    1295 #       def _get_name(self): 
    1296 #               return self._name 
    1297 #        
    1298 #       def _set_name(self, value): 
    1299 #               self._name = value 
    1300 #               self._hasChanged() 
    1301 
    1302 #       name = property(_get_name, _set_name, doc="") 
    1303 
    1304 #                
    1305 #class RAnchor(BaseAnchor): 
    1306 #        
    1307 #       _title = "RoboFabAnchor" 
    1308 #        
    1309 #       def __init__(self, name=None, position=None, mark=None): 
    1310 #               BaseAnchor.__init__(self) 
    1311 #               self.selected = False 
    1312 #               self.name = name 
    1313 #               if position is None: 
    1314 #                       self.x = self.y = None 
    1315 #               else: 
    1316 #                       self.x, self.y = position 
    1317 #               self.mark = mark 
    1318 #                
    1319 #       def _get_index(self): 
    1320 #               if self.getParent() is None: return None 
    1321 #               return self.getParent().anchors.index(self) 
    1322 #        
    1323 #       index = property(_get_index, doc="index of the anchor") 
    1324 #        
    1325 #       def _get_position(self): 
    1326 #               return (self.x, self.y) 
    1327 #        
    1328 #       def _set_position(self, value): 
    1329 #               self.x = value[0] 
    1330 #               self.y = value[1] 
    1331 #               self._hasChanged() 
    1332 #        
    1333 #       position = property(_get_position, _set_position, doc="position of the anchor") 
    1334 #        
    1335 #       def move(self, (x, y)): 
    1336 #               """Move the anchor""" 
    1337 #               self.x = self.x + x 
    1338 #               self.y = self.y + y 
    1339 #               self._hasChanged() 
    1340 
    1341 #                
    1342 #class RComponent(BaseComponent): 
    1343 #        
    1344 #       _title = "RoboFabComponent" 
    1345 #        
    1346 #       def __init__(self, baseGlyphName=None, offset=(0,0), scale=(1,1)): 
    1347 #               BaseComponent.__init__(self) 
    1348 #               self.selected = False 
    1349 #               self._baseGlyph = baseGlyphName 
    1350 #               self._offset = offset 
    1351 #               self._scale = scale 
    1352 #                
    1353 #       def _get_index(self): 
    1354 #               if self.getParent() is None: return None 
    1355 #               return self.getParent().components.index(self) 
    1356 #                
    1357 #       index = property(_get_index, doc="index of the component") 
    1358 #        
    1359 #       def _get_baseGlyph(self): 
    1360 #               return self._baseGlyph 
    1361 #                
    1362 #       def _set_baseGlyph(self, glyphName): 
    1363 #               # XXXX needs to be implemented in objectsFL for symmetricity's sake. Eventually. 
    1364 #               self._baseGlyph = glyphName 
    1365 #               self._hasChanged() 
    1366 #                
    1367 #       baseGlyph = property(_get_baseGlyph, _set_baseGlyph, doc="") 
    1368 
    1369 #       def _get_offset(self): 
    1370 #               return self._offset 
    1371 #        
    1372 #       def _set_offset(self, value): 
    1373 #               self._offset = value 
    1374 #               self._hasChanged() 
    1375 #                
    1376 #       offset = property(_get_offset, _set_offset, doc="the offset of the component") 
    1377 
    1378 #       def _get_scale(self): 
    1379 #               return self._scale 
    1380 #        
    1381 #       def _set_scale(self, (x, y)): 
    1382 #               self._scale = (x, y) 
    1383 #               self._hasChanged() 
    1384 #                
    1385 #       scale = property(_get_scale, _set_scale, doc="the scale of the component") 
    1386 #                
    1387 #       def move(self, (x, y)): 
    1388 #               """Move the component""" 
    1389 #               self.offset = (self.offset[0] + x, self.offset[1] + y) 
    1390 #        
    1391 #       def decompose(self): 
    1392 #               """Decompose the component""" 
    1393 #               baseGlyphName = self.baseGlyph 
    1394 #               parentGlyph = self.getParent() 
    1395 #               # if there is no parent glyph, there is nothing to decompose to 
    1396 #               if baseGlyphName is not None and parentGlyph is not None: 
    1397 #                       parentFont = parentGlyph.getParent() 
    1398 #                       # we must have a parent glyph with the baseGlyph 
    1399 #                       # if not, we will simply remove the component from 
    1400 #                       # the parent glyph thereby decomposing the component 
    1401 #                       # to nothing. 
    1402 #                       if parentFont is not None and parentFont.has_key(baseGlyphName): 
    1403 #                               from robofab.pens.adapterPens import TransformPointPen 
    1404 #                               oX, oY = self.offset 
    1405 #                               sX, sY = self.scale 
    1406 #                               baseGlyph = parentFont[baseGlyphName] 
    1407 #                               for contour in baseGlyph.contours: 
    1408 #                                       pointPen = parentGlyph.getPointPen() 
    1409 #                                       transPen = TransformPointPen(pointPen, (sX, 0, 0, sY, oX, oY)) 
    1410 #                                       contour.drawPoints(transPen) 
    1411 #                       parentGlyph.components.remove(self) 
    1412 #        
     1145# ------- 
     1146# Segment 
     1147# ------- 
     1148 
     1149class RSegment(BaseSegment): 
     1150 
     1151        _title = "RoboFabSegment" 
     1152 
     1153        def __init__(self, segmentType=None, points=[], smooth=False): 
     1154                super(RSegment, self).__init__() 
     1155                self._points = points 
     1156                self._RContourClass = None 
     1157 
     1158        def getParent(self): 
     1159                defconContour = self._defconContour() 
     1160                if defconContour is None: 
     1161                        return None 
     1162                if self._RContourClass is None: 
     1163                        return None 
     1164                return self._RContourClass(defconContour) 
     1165 
     1166        def _setDefconContour(self, defconContour): 
     1167                self._defconContour = weakref.ref(defconContour) 
     1168 
     1169        def _defconContour(self): 
     1170                return None 
     1171 
     1172        def _setDefconContourDirty(self): 
     1173                contour = self._defconContour() 
     1174                if contour is not None: 
     1175                        contour.dirty = True 
     1176 
     1177        def _get_index(self): 
     1178                contour = self._defconContour() 
     1179                if contour is None: 
     1180                        return None 
     1181                segments = contour.segments 
     1182                if self._points in segments: 
     1183                        return segments.index(self._points) 
     1184                return None 
     1185 
     1186        index = property(_get_index, doc="index of the segment") 
     1187 
     1188        # Points 
     1189 
     1190        def _get_points(self): 
     1191                return [self.getPoint(point) for point in self._points] 
     1192 
     1193        points = property(_get_points, doc="view the segment as a list of points") 
     1194 
     1195        # smooth  
     1196 
     1197        def _get_smooth(self): 
     1198                return self._points[-1].smooth 
     1199 
     1200        def _set_smooth(self, value): 
     1201                old = self._points[-1].smooth 
     1202                if old == value: 
     1203                        return 
     1204                self._points[-1].smooth = value 
     1205                self._setDefconContourDirty() 
     1206 
     1207        smooth = property(_get_smooth, _set_smooth, doc="smoothness of the segment") 
     1208 
     1209        # type 
     1210 
     1211        def _get_type(self): 
     1212                value = self._points[-1].segmentType 
     1213                if value is None: 
     1214                        value = "offcurve" 
     1215                return value 
     1216 
     1217        def _set_type(self, pointType): 
     1218                if pointType == "offcurve": 
     1219                        pointType = None 
     1220                onCurve = self._points[-1] 
     1221                ocType = onCurve.segmentType 
     1222                defconContour = self._defconContour() 
     1223                if defconContour is None: 
     1224                        return 
     1225                if ocType == pointType: 
     1226                        return 
     1227                onCurve.segmentType = pointType 
     1228                # we are converting a cubic line, move into a cubic curve 
     1229                if pointType == "curve" and ocType in  ["line", "move"]: 
     1230                        # add offcurves 
     1231                        index = defconContour.index(onCurve) 
     1232                        prevOnCurve = defconContour[index - 1] 
     1233                        p1 = defconContour.pointClass((prevOnCurve.x, prevOnCurve.y), segmentType=None) 
     1234                        p2 = defconContour.pointClass((onCurve.x, onCurve.y), segmentType=None) 
     1235                        defconContour.insertPoint(index, p2) 
     1236                        defconContour.insertPoint(index, p1) 
     1237                        found = False 
     1238                        for points in defconContour.segments: 
     1239                                if points[-1] == onCurve: 
     1240                                        found = True 
     1241                                        break 
     1242                        if found: 
     1243                                self._points = points 
     1244                # we are converting a quad curve to a cubic curve 
     1245                elif pointType == "curve" and ocType == "qcurve": 
     1246                        # do nothing 
     1247                        pass 
     1248                # we are converting a cubic curve or quad curve into a  line 
     1249                elif pointType == "line" and ocType in ["curve", "qcurve"]: 
     1250                        # remove offcurves 
     1251                        offCurves = self._points[:-1] 
     1252                        for point in offCurves: 
     1253                                defconContour.removePoint(point) 
     1254                        self._points = [onCurve] 
     1255                # we are converting a cubic move to a line 
     1256                elif pointType == "line" and ocType == "move": 
     1257                        # do nothing 
     1258                        pass 
     1259                # we are converting to a quad curve where just about anything is legal 
     1260                elif pointType == "qcurve": 
     1261                        # do nothing 
     1262                        pass 
     1263                else: 
     1264                        raise RoboFabError, 'unknown segment type' 
     1265                self._setDefconContourDirty() 
     1266 
     1267        type = property(_get_type, _set_type, doc="type of the segment") 
     1268 
     1269        def insertPoint(self, index, pointType, point): 
     1270                raise NotImplementedError 
     1271 
     1272        def removePoint(self, index): 
     1273                raise NotImplementedError 
     1274 
     1275 
     1276# ------ 
     1277# bPoint 
     1278# ------ 
     1279 
     1280class RBPoint(BaseBPoint): 
     1281 
     1282        _title = "RoboFabBPoint" 
     1283 
     1284        def __init__(self, anchor=None): 
     1285                super(RBPoint, self).__init__() 
     1286                self._anchor = anchor 
     1287                self._RContourClass = None 
     1288 
     1289        def _setDefconContour(self, contour): 
     1290                self._defconContour = weakref.ref(contour) 
     1291 
     1292        def _defconContour(self): 
     1293                return None 
     1294 
     1295        def _setDefconContourDirty(self): 
     1296                defconContour = self._defconContour() 
     1297                if defconContour is not None: 
     1298                        defconContour.dirty = True 
     1299 
     1300        def getParent(self): 
     1301                defconContour = self._defconContour() 
     1302                if defconContour is None: 
     1303                        return None 
     1304                if self._RContourClass is None: 
     1305                        return None 
     1306                return self._RContourClass(defconContour) 
     1307 
     1308        def _get_index(self): 
     1309                defconContour = self._defconContour() 
     1310                if defconContour is None: 
     1311                        return None 
     1312                onCurvePoints = defconContour.onCurvePoints 
     1313                if self._anchor in onCurvePoints: 
     1314                        return onCurvePoints.index(self._anchor) 
     1315                return None 
     1316 
     1317        index = property(_get_index, doc="index of the segment") 
     1318 
     1319        def _setAnchorChanged(self, value): 
     1320                pass 
     1321 
     1322        def _setNextChanged(self, value): 
     1323                pass 
     1324 
     1325        def _get__parentSegment(self): 
     1326                defconContour = self._defconContour() 
     1327                if defconContour is None: 
     1328                        return None 
     1329                found = False 
     1330                for points in defconContour.segments: 
     1331                        if self._anchor == points[-1]: 
     1332                                found = True 
     1333                                break 
     1334                if found: 
     1335                        return self.getSegment(points) 
     1336                return None 
     1337 
     1338        _parentSegment = property(_get__parentSegment) 
     1339 
     1340        def _get__nextOnCurve(self): 
     1341                defconContour = self._defconContour() 
     1342                if defconContour is None: 
     1343                        return None 
     1344                onCurvePoints = defconContour.onCurvePoints 
     1345                index = onCurvePoints.index(self._anchor) 
     1346                return self.getPoint(onCurvePoints[(index + 1) % len(onCurvePoints)]) 
     1347 
     1348        _nextOnCurve = property(_get__nextOnCurve) 
     1349 
     1350# ----- 
     1351# Point 
     1352# ----- 
     1353 
     1354class RPoint(BasePoint): 
     1355 
     1356        _title = "RoboFabPoint" 
     1357 
     1358        def __init__(self, obj=None): 
     1359                super(RPoint, self).__init__() 
     1360                self._object = obj 
     1361 
     1362        def __repr__(self): 
     1363                return "<RPoint for position: (%s, %s) type: %s >" % (self.x, self.y, self.type) 
     1364 
     1365        def _setDefconContour(self, contour): 
     1366                self._defconContour = weakref.ref(contour) 
     1367 
     1368        def _defconContour(self): 
     1369                return None 
     1370 
     1371        def _setDefconContourDirty(self): 
     1372                defconContour = self._defconContour() 
     1373                if defconContour is not None: 
     1374                        defconContour.dirty = True 
     1375 
     1376        def getParent(self): 
     1377                defconContour = self._defconContour() 
     1378                if defconContour is None: 
     1379                        return None 
     1380                segments = defconContour.segments 
     1381                found = False 
     1382                for points in segments: 
     1383                        if self._object in points: 
     1384                                found = True 
     1385                                break 
     1386                if found: 
     1387                        return self.getSegment(points) 
     1388                return None 
     1389 
     1390        def _get_x(self): 
     1391                return self._object.x 
     1392 
     1393        def _set_x(self, value): 
     1394                old = self._object.x 
     1395                if old == value: 
     1396                        return 
     1397                self._object.x = value 
     1398                self._setDefconContourDirty() 
     1399 
     1400        x = property(_get_x, _set_x, doc="x attribute for point") 
     1401 
     1402        def _get_y(self): 
     1403                return self._object.y 
     1404 
     1405        def _set_y(self, value): 
     1406                old = self._object.y 
     1407                if old == value: 
     1408                        return 
     1409                self._object.y = value 
     1410                self._setDefconContourDirty() 
     1411 
     1412        y = property(_get_y, _set_y, doc="y attribute for point") 
     1413 
     1414        def _get_smooth(self): 
     1415                return self._points[-1].smooth 
     1416 
     1417        def _set_smooth(self, value): 
     1418                old = self._object.smooth 
     1419                if old == value: 
     1420                        return 
     1421                self._object.smooth = value 
     1422                self._setDefconContourDirty() 
     1423 
     1424        smooth = property(_get_smooth, _set_smooth, doc="smoothness of the segment") 
     1425 
     1426        def _get_type(self): 
     1427                value = self._object.segmentType 
     1428                if value is None: 
     1429                        value = "offcurve" 
     1430                return value 
     1431 
     1432        def _set_type(self, value): 
     1433                if value == "offcurve": 
     1434                        value = None 
     1435                old = self._object.segmentType 
     1436                if old == value: 
     1437                        return 
     1438                self._object.segmentType = value 
     1439                self._setDefconContourDirty() 
     1440 
     1441        type = property(_get_type, _set_type, doc="type of the segment") 
     1442 
     1443        def _get_name(self): 
     1444                return self._object.name 
     1445 
     1446        def _set_name(self, value): 
     1447                old = self._object.name 
     1448                if old == value: 
     1449                        return 
     1450                self._object.name = value 
     1451                self._setDefconContourDirty() 
     1452 
     1453        name = property(_get_name, _set_name, doc="name attribute for point") 
     1454 
     1455 
     1456# ------ 
     1457# Anchor 
     1458# ------ 
     1459 
     1460class RAnchor(BaseAnchor): 
     1461 
     1462        _title = "RoboFabAnchor" 
     1463 
     1464        def __init__(self, obj): 
     1465                super(RAnchor, self).__init__() 
     1466                self._object = obj 
     1467 
     1468        def _get_index(self): 
     1469                glyph = self._object.glyph 
     1470                if glyph is None: 
     1471                        return None 
     1472                return glyph.anchorIndex(self._object) 
     1473 
     1474        index = property(_get_index, doc="index of the anchor") 
     1475 
     1476        def _get_position(self): 
     1477                return (self._object.x, self._object.y) 
     1478 
     1479        def _set_position(self, value): 
     1480                self._object.x = value[0] 
     1481                self._object.y = value[1] 
     1482 
     1483        position = property(_get_position, _set_position, doc="position of the anchor") 
     1484 
     1485        def _get_name(self): 
     1486                return self._object.name 
     1487 
     1488        def _set_name(self, value): 
     1489                self._object.name = value 
     1490 
     1491        name = property(_get_name, _set_name, doc="name of the anchor") 
     1492 
     1493 
     1494# --------- 
     1495# Component 
     1496# --------- 
     1497 
     1498class RComponent(BaseComponent): 
     1499 
     1500        _title = "RoboFabComponent" 
     1501 
     1502        def __init__(self, obj=None): 
     1503                super(RComponent, self).__init__() 
     1504                self._object = obj 
     1505 
     1506        def _get_index(self): 
     1507                glyph = self._object.glyph 
     1508                if glyph is None: 
     1509                        return None 
     1510                return glyph.componentIndex(self._object) 
     1511 
     1512        index = property(_get_index, doc="index of the component") 
     1513 
     1514        def _get_baseGlyph(self): 
     1515                return self._object.baseGlyph 
     1516 
     1517        def _set_baseGlyph(self, glyphName): 
     1518                self._object.baseGlyph = glyphName 
     1519 
     1520        baseGlyph = property(_get_baseGlyph, _set_baseGlyph, doc="") 
     1521 
     1522        def _get_offset(self): 
     1523                xScale, xyScale, yxScale, yScale, xOffset, yOffset = self._object.transformation 
     1524                return xOffset, yOffset 
     1525 
     1526        def _set_offset(self, (x, y)): 
     1527                xScale, xyScale, yxScale, yScale, xOffset, yOffset = self._object.transformation 
     1528                self._object.transformation = (xScale, xyScale, yxScale, yScale, x, y) 
     1529 
     1530        offset = property(_get_offset, _set_offset, doc="the offset of the component") 
     1531 
     1532        def _get_scale(self): 
     1533                xScale, xyScale, yxScale, yScale, xOffset, yOffset = self._object.transformation 
     1534                return xScale, yScale 
     1535 
     1536        def _set_scale(self, (x, y)): 
     1537                xScale, xyScale, yxScale, yScale, xOffset, yOffset = self._object.transformation 
     1538                self._object.transformation = (x, xyScale, yxScale, y, xOffset, yOffset) 
     1539 
     1540        scale = property(_get_scale, _set_scale, doc="the scale of the component") 
     1541 
     1542        def move(self, (x, y)): 
     1543                """Move the component""" 
     1544                self._object.move((x, y)) 
     1545 
     1546        def decompose(self): 
     1547                """Decompose the component""" 
     1548                glyph = self._object.glyph 
     1549                if glyph is None: 
     1550                        return 
     1551                glyph.decomposeComponent(self._object) 
     1552 
    14131553 
    14141554# ---- 
     
    16041744#                       self.fromDict(data) 
    16051745 
     1746 
    16061747if __name__ == "__main__": 
    16071748        from defcon.test.testTools import getTestFontPath 
     
    16271768        print 
    16281769        print "glyph:", font.layers[None]["A"] 
    1629         print font.layers[None]["A"].leftMargin 
     1770        print "glyph.leftMargin:", font.layers[None]["A"].leftMargin 
     1771        print "contours:", list(font.layers[None]["A"]) 
     1772        print "contour:", font.layers[None]["A"][0] 
     1773        print "points:", font.layers[None]["A"][0].points 
     1774        print "segments:", font.layers[None]["A"][0].segments 
     1775         
     1776        for seg in font.layers[None]["A"][0].segments: 
     1777                seg.round() 
     1778         
     1779        print "bPoints:", font.layers[None]["A"][0].bPoints 
     1780        print 
     1781        bPoints = font.layers[None]["A"][0].bPoints 
     1782        for bPoint in bPoints: 
     1783                print "bPoint:", bPoint 
     1784                print "bPoint.anchor:", bPoint.anchor 
     1785                print "bPoint.bcpIn:", bPoint.bcpIn 
     1786                bPoint.bcpIn = (10, 10) 
     1787                print bPoint.bcpIn 
     1788                print "bPoint.bcpOut:", bPoint.bcpOut 
     1789                print  
     1790        for point in font.layers[None]["A"][0].points: 
     1791                print "point", point 
     1792                print "point.getParent():", point.getParent() 
     1793         
     1794         
     1795        print  
     1796        print "anchors:", font.layers[None]["A"].anchors 
     1797        print "components for 'C':", font.layers[None]["C"].components 
     1798        print "decompose..." 
     1799        for component in font.layers[None]["C"].components: 
     1800                component.decompose() 
     1801        print "components for 'C':",  font.layers[None]["C"].components 
     1802        ### endless loop 
     1803        #print font.layers[None]["A"].appendComponent("C") 
     1804 
     1805        print "done"