def ApplyGlitchCollage(self, layer, groups, linecomponents): for g in groups: if len(g) < 2: continue templayer = GSLayer() templayer.paths = g G.remove_overlap(templayer) linetype = False for p in templayer.paths: nodelen = len(p.nodes) if nodelen < 4: continue roundedpath = RoundPath(p, "nodes") roundedpath = convertToFitpath(roundedpath, True) if not roundedpath: continue if random.choice([0, 1, 2, 3]) == 1: tr = random.choice([0, 2]) if tr == 1: self.HalftoneShape(layer, p, "triangle") elif tr == 0: self.HalftoneShape(layer, p, "square") else: layer.paths.append(roundedpath) else: if nodelen > 9: if nodelen > 20: noodlepaths = self.expandMonolineFromPathlist( [roundedpath], 6) AddAllPathsToLayer(noodlepaths, layer) else: if random.choice([0, 1]) == 0: if linetype == False: direction = "vertical" else: direction = "horizontal" linetype = not linetype linecomps = Fill_Drawlines( layer, roundedpath, direction, 15, linecomponents) AddAllComponentsToLayer(linecomps, layer) else: self.Fill_Halftone(layer, roundedpath, "circle") else: layer.paths.append(p) del templayer
def Fill_Halftone(self, thislayer): components = [] for size in range(0,5): font = self.font shapename = "pixel"+str(size) if font.glyphs[shapename]: del font.glyphs[shapename] ng = GSGlyph() ng.name = shapename ng.category = "Mark" ng.export = True font.glyphs.append(ng) firstmaster = font.masters[0].id thislayer = GSLayer() thislayer.layerId = thislayer.associatedMasterId =firstmaster ng.layers[firstmaster] = thislayer thislayer.width = 0 ox, oy = 0, 0 w, h = 40, 40 grid = 10 unit = 5 if size!=0: gridx = 10 * size gridy = gridx else: gridx = 10 gridy = 5 x, y = ox, oy switchx = False for x in range(ox, ox+w, gridx): for y in range(oy, oy+h, gridy): if switchx==True: if size==0: adjust = 5 switchx = not switchx else: adjust = gridx/2 switchx = not switchx else: adjust=0 switchx = not switchx ns = drawRectangle( x + adjust, y , unit, unit) thislayer.paths.append(ns) switchx = False components.append(ng) return components
def newGlyph(self, glyphName, clear=True): """Make a new glyph""" g = self._font.glyphForName_(glyphName) if g is None: g = GSGlyph(glyphName) self._font.addGlyph_(g) elif clear: g.layers[self._masterKey] = GSLayer() return self[glyphName]
def __init__(self, glyph=None, master=0, layer=None): self.masterIndex = master self._layer = None if type(glyph) == RGlyph: self._object = glyph._object self._layer = glyph._layer.copy() self._layerID = glyph._layerID if hasattr(glyph, "masterIndex"): self.masterIndex = glyph.masterIndex return if layer is not None: glyph = layer.parent if glyph is None: glyph = GSGlyph() elif glyph.parent is not None: self.setParent(RFont(glyph.parent, self.masterIndex)) self._object = glyph self._layerID = None if layer is None: try: if glyph.parent: self._layerID = glyph.parent.masters[master].id elif (glyph.layers[master]): self._layerID = glyph.layers[master].layerId except: pass self.masterIndex = master if self._layerID: self._layer = glyph.layerForKey_(self._layerID) else: self._layer = layer self._layerID = layer.associatedMasterId if self._layer is None: self._layerID = "undefined" self._layer = GSLayer() glyph.setLayer_forKey_(self._layer, self._layerID)
def ApplyCollageGraphixxx(self, layer, groups, drawtype, linecomponents): for g in groups: if len(g) < 2: continue templayer = GSLayer() templayer.paths = g G.remove_overlap(templayer) for p in templayer.paths: nodelen = len(p.nodes) if nodelen < 4: continue roundedpath = RoundPath(p, "nodes") roundedpath = convertToFitpath(roundedpath, True) if not roundedpath: continue if drawtype == "vertical" or drawtype == "horizontal": rw = roundedpath.bounds.size.width rh = roundedpath.bounds.size.height if (rw > 130 or rh > 130): all_lines = Fill_Drawlines(layer, roundedpath, drawtype, 20, linecomponents) AddAllComponentsToLayer(all_lines, layer) if drawtype == "blob": # disallow small blobs rw = roundedpath.bounds.size.width rh = roundedpath.bounds.size.height if (rw > 80 and rh > 80) and (rw < 180 or rh < 180): ConvertPathDirection(roundedpath, -1) layer.paths.append(roundedpath) del templayer
def returnSlicedPaths(self, pathlist, sliceheight): slicedpaths = [] tmplayer = GSLayer() AddAllPathsToLayer(pathlist, tmplayer) bounds = AllPathBounds(tmplayer) ox, oy, w, h = bounds[0], bounds[1], bounds[2], bounds[3] starty = int(oy/sliceheight) * sliceheight - 1 y = starty sh = sliceheight while y < starty+h: G.cut_layer(tmplayer, (ox-1, y), (ox+w+1, y)) y+=sh sh = sliceheight * random.randrange(1, 5) slicedpaths = tmplayer.paths del tmplayer return slicedpaths
def __init__(self, glyph = None, master = 0, layer = None): self.masterIndex = master; self._layer = None if type(glyph) == RGlyph: self._object = glyph._object self._layer = glyph._layer.copy() self._layerID = glyph._layerID if hasattr(glyph, "masterIndex"): self.masterIndex = glyph.masterIndex return if layer is not None: glyph = layer.parent if glyph is None: glyph = GSGlyph() elif glyph.parent is not None: self.setParent(RFont(glyph.parent, self.masterIndex)) self._object = glyph self._layerID = None if layer is None: try: if glyph.parent: self._layerID = glyph.parent.masters[master].id elif (glyph.layers[master]): self._layerID = glyph.layers[master].layerId except: pass self.masterIndex = master if self._layerID: self._layer = glyph.layerForKey_(self._layerID) else: self._layer = layer self._layerID = layer.associatedMasterId if self._layer is None: self._layerID = "undefined" self._layer = GSLayer() glyph.setLayer_forKey_(self._layer, self._layerID)
def _get_indic_rightmost_stem(self, l): stem_center = None number_of_samples = 12 stem_width = self._indic_stem_widths.get(l.parent.script, {}).get(l.associatedMasterId) if stem_width is None: return fuzziness = stem_width * 0.1 measure_interval = int(l.bounds.size.height / number_of_samples) measure_heights = range(int(l.bounds.origin.y), int(l.bounds.origin.y + l.bounds.size.height), measure_interval) potential_stems = defaultdict(list) measured_points = [] # l.guides = [] for height in measure_heights: for p in l.paths: measure_l = GSLayer() measure_l.width = l.width measure_l.paths.append(p) measured_points.append(measure_l.intersectionsBetweenPoints((0, height), (measure_l.width, height), components=True)[1:-1]) for c in l.components: measure_l = c.componentLayer.copyDecomposedLayer() measure_l.removeOverlap() measure_l.applyTransform(c.transform) measured_points.append(measure_l.intersectionsBetweenPoints((0, height), (measure_l.width + c.transform[4], height), components=True)[1:-1]) # if 1: # ngl = GSGuideLine() # ngl.position = NSPoint(0, height) # ngl.setShowMeasurement_(1) # l.guides.append(ngl) # print(l, stem_width) for measure_coords in measured_points: for ci, coord in enumerate(measure_coords): try: next_coord = measure_coords[ci + 1] except IndexError: break coord_distance = next_coord.x - coord.x # print(coord_distance, measure_coords) if self._check_coord(coord_distance, stem_width, fuzziness=fuzziness): stem_mid_point = round((next_coord.x + coord.x) / 2) stem_mid_point_max = stem_mid_point + fuzziness stem_mid_point_min = stem_mid_point - fuzziness added = False for min_max in potential_stems.keys(): pmin, pmax = min_max if pmax > stem_mid_point_max > pmin or pmax > stem_mid_point_min > pmin: potential_stems[min_max].append(stem_mid_point) added = True break if not added: potential_stems[(stem_mid_point_min, stem_mid_point_max)].append(stem_mid_point) vals = potential_stems.values() vals.sort(reverse=True) vals.sort(key=len, reverse=True) stem_center = round(sum(vals[0]) / len(vals[0])) return stem_center
class RGlyph(BaseGlyph): _title = "GSGlyph" preferedSegmentType = "curve" def __init__(self, glyph=None, master=0, layer=None): self.masterIndex = master self._layer = None if type(glyph) == RGlyph: self._object = glyph._object self._layer = glyph._layer.copy() self._layerID = glyph._layerID if hasattr(glyph, "masterIndex"): self.masterIndex = glyph.masterIndex return if layer is not None: glyph = layer.parent if glyph is None: glyph = GSGlyph() elif glyph.parent is not None: self.setParent(RFont(glyph.parent, self.masterIndex)) self._object = glyph self._layerID = None if layer is None: try: if glyph.parent: self._layerID = glyph.parent.masters[master].id elif (glyph.layers[master]): self._layerID = glyph.layers[master].layerId except: pass self.masterIndex = master if self._layerID: self._layer = glyph.layerForKey_(self._layerID) else: self._layer = layer self._layerID = layer.associatedMasterId if self._layer is None: self._layerID = "undefined" self._layer = GSLayer() glyph.setLayer_forKey_(self._layer, self._layerID) def __repr__(self): font = "unnamed_font" glyph = "unnamed_glyph" fontParent = self.getParent() if fontParent is not None: try: font = fontParent.info.postscriptFullName except AttributeError: pass try: glyph = self.name except AttributeError: pass return "<RGlyph %s for %s>" % (self._object.name, font) def setParent(self, parent): self._parent = weakref.proxy(parent) def getParent(self): try: return self._parent() except: return None def __getitem__(self, index): return self.contours[index] def __delitem__(self, index): self._layer.removePathAtIndex_(index) self._invalidateContours() def _invalidateContours(self): self._contours = None if self._layer: self._layer.updatePath() def __iter__(self): Values = self._layer.paths if Values is not None: for element in Values: yield element def __len__(self): return len(self._layer.paths) def copy(self): Copy = RGlyph(self._object.copy(), self.masterIndex) Copy._layerID = self._layerID Copy._layer = Copy._object.layerForKey_(self._layerID) return Copy def _get_contours(self): return self._layer.paths contours = property(_get_contours, doc="allow for iteration through glyph.contours") def _hasNotChanged(self): raise NotImplementedError def _get_box(self): bounds = self._layer.bounds bounds = (int(round(NSMinX(bounds))), int(round(NSMinY(bounds))), int(round(NSMaxX(bounds))), int(round(NSMaxY(bounds)))) return bounds box = property( _get_box, doc="the bounding box of the glyph: (xMin, yMin, xMax, yMax)") # # attributes # def _get_lib(self): try: return self._object.userData() except: return None def _set_lib(self, key, obj): if self._object.userData() is objc.nil: self._object.setUserData_(NSMutableDictionary.dictionary()) self._object.userData().setObject_forKey_(obj, key) lib = property(_get_lib, _set_lib, doc="Glyph Lib") def _set_name(self, newName): prevName = self.name if newName == prevName: return self._object.name = newName name = property(lambda self: self._object.name, _set_name) def _get_unicodes(self): if self._object.unicode is not None: return [int(self._object.unicode, 16)] return [] def _set_unicodes(self, value): if not isinstance(value, list): raise RoboFabError, "unicodes must be a list" try: self._object.setUnicode = value[0] except: pass unicodes = property(_get_unicodes, _set_unicodes, doc="all unicode values for the glyph") def _get_unicode(self): if self._object.unicode is None: return None return self._object.unicodeChar() def _set_unicode(self, value): if type(value) == str: if value is not None and value is not self._object.unicode: self._object.setUnicode_(value) elif type(value) == int: strValue = "%0.4X" % value if strValue is not None and strValue is not self._object.unicode: self._object.setUnicode_(strValue) else: raise (KeyError) unicode = property(_get_unicode, _set_unicode, doc="first unicode value for the glyph") index = property( lambda self: self._object.parent.indexOfGlyph_(self._object)) note = property(lambda self: self._object.valueForKey_("note"), lambda self, value: self._object.setNote_(value)) leftMargin = property(lambda self: self._layer.LSB, lambda self, value: self._layer.setLSB_(value), doc="Left Side Bearing") rightMargin = property(lambda self: self._layer.RSB, lambda self, value: self._layer.setRSB_(value), doc="Right Side Bearing") width = property(lambda self: self._layer.width, lambda self, value: self._layer.setWidth_(value), doc="width") components = property(lambda self: self._layer.components, doc="List of components") guides = property(lambda self: self._layer.guides, doc="List of guides") def appendComponent(self, baseGlyph, offset=(0, 0), scale=(1, 1)): """append a component to the glyph""" new = GSComponent(baseGlyph, offset, scale) self._layer.addComponent_(new) def removeComponent(self, component): """remove a specific component from the glyph""" self._layer.removeComponent_(component) def getPointPen(self): # if "GSPen" in sys.modules.keys(): # del(sys.modules["GSPen"]) from GSPen import GSPointPen return GSPointPen(self, self._layer) def appendAnchor(self, name, position, mark=None): """append an anchor to the glyph""" new = GSAnchor(name=name, pt=position) self._layer.addAnchor_(new) def removeAnchor(self, anchor): """remove a specific anchor from the glyph""" self._layer.removeAnchor_(anchor) def removeContour(self, index): """remove a specific contour from the glyph""" if type(index) == type(int): self._layer.removePathAtIndex_(index) else: self._layer.removePath_(index) def center(self, padding=None): """Equalize sidebearings, set to padding if wanted.""" left = self._layer.LSB right = self._layer.RSB if padding: e_left = e_right = padding else: e_left = (left + right) / 2 e_right = (left + right) - e_left self._layer.setLSB_(e_left) self._layer.setRSB_(e_right) def decompose(self): """Decompose all components""" self._layer.decomposeComponents() def clear(self, contours=True, components=True, anchors=True, guides=True): """Clear all items marked as True from the glyph""" if contours: self.clearContours() if components: self.clearComponents() if anchors: self.clearAnchors() if guides: self.clearGuides() def clearContours(self): """clear all contours""" while len(self._layer.paths) > 0: self._layer.removePathAtIndex_(0) def clearComponents(self): """clear all components""" self._layer.setComponents_(NSMutableArray.array()) def clearAnchors(self): """clear all anchors""" self._layer.setAnchors_(NSMutableDictionary.dictionary()) def clearGuides(self): """clear all horizontal guides""" self._layer.setGuideLines_(NSMutableArray.array()) def update(self): self._contours = None #GSGlyphsInfo.updateGlyphInfo_changeName_(self._object, False) def correctDirection(self, trueType=False): self._layer.correctPathDirection() def removeOverlap(self): removeOverlapFilter = NSClassFromString( "GlyphsFilterRemoveOverlap").alloc().init() removeOverlapFilter.runFilterWithLayer_error_(self._layer, None) def _mathCopy(self): """ copy self without contour, component and anchor data """ glyph = self._getMathDestination() glyph.name = self.name glyph.unicodes = list(self.unicodes) glyph.width = self.width glyph.note = self.note try: glyph.lib = dict(self.lib) except: pass return glyph anchors = property(lambda self: self._layer.anchors) def getRepresentation(self, representaion): if representaion == "defconAppKit.NSBezierPath": return self._layer.bezierPath.copy() return None def performUndo(self): pass def prepareUndo(self, undoTitle): pass def getLayer(self, name): return RGlyph(layer=self._object.layerForName_(name))
def expandMonolineFromPathlist(self, Paths, noodleRadius): Layer = GSLayer() for p in Paths: Layer.paths.append(p) G.offset_layer(Layer, noodleRadius, noodleRadius, make_stroke=True) G.correct_path_direction(Layer) return Layer.paths
class RGlyph(BaseGlyph): _title = "GSGlyph" preferedSegmentType = "curve" def __init__(self, glyph = None, master = 0, layer = None): self.masterIndex = master; self._layer = None if type(glyph) == RGlyph: self._object = glyph._object self._layer = glyph._layer.copy() self._layerID = glyph._layerID if hasattr(glyph, "masterIndex"): self.masterIndex = glyph.masterIndex return if layer is not None: glyph = layer.parent if glyph is None: glyph = GSGlyph() elif glyph.parent is not None: self.setParent(RFont(glyph.parent, self.masterIndex)) self._object = glyph self._layerID = None if layer is None: try: if glyph.parent: self._layerID = glyph.parent.masters[master].id elif (glyph.layers[master]): self._layerID = glyph.layers[master].layerId except: pass self.masterIndex = master if self._layerID: self._layer = glyph.layerForKey_(self._layerID) else: self._layer = layer self._layerID = layer.associatedMasterId if self._layer is None: self._layerID = "undefined" self._layer = GSLayer() glyph.setLayer_forKey_(self._layer, self._layerID) def __repr__(self): font = "unnamed_font" glyph = "unnamed_glyph" fontParent = self.getParent() if fontParent is not None: try: font = fontParent.info.postscriptFullName except AttributeError: pass try: glyph = self.name except AttributeError: pass return "<RGlyph %s for %s>" %(self._object.name, font) def setParent(self, parent): self._parent = weakref.proxy(parent) def getParent(self): try: return self._parent() except: return None def __getitem__(self, index): return self.contours[index] def __delitem__(self, index): self._layer.removePathAtIndex_(index) self._invalidateContours() def _invalidateContours(self): self._contours = None if self._layer: self._layer.updatePath() def __iter__(self): Values = self._layer.paths if Values is not None: for element in Values: yield element def __len__(self): return len(self._layer.paths) def copy(self): Copy = RGlyph(self._object.copy(), self.masterIndex) Copy._layerID = self._layerID Copy._layer = Copy._object.layerForKey_(self._layerID) return Copy def _get_contours(self): return self._layer.paths contours = property(_get_contours, doc="allow for iteration through glyph.contours") def _hasNotChanged(self): raise NotImplementedError def _get_box(self): bounds = self._layer.bounds bounds = (int(round(NSMinX(bounds))), int(round(NSMinY(bounds))), int(round(NSMaxX(bounds))), int(round(NSMaxY(bounds)))) return bounds box = property(_get_box, doc="the bounding box of the glyph: (xMin, yMin, xMax, yMax)") # # attributes # def _get_lib(self): try: return self._object.userData() except: return None def _set_lib(self, key, obj): if self._object.userData() is objc.nil: self._object.setUserData_(NSMutableDictionary.dictionary()) self._object.userData().setObject_forKey_(obj, key) lib = property(_get_lib, _set_lib, doc="Glyph Lib") def _set_name(self, newName): prevName = self.name if newName == prevName: return self._object.name = newName name = property(lambda self: self._object.name, _set_name) def _get_unicodes(self): if self._object.unicode is not None: return [int(self._object.unicode, 16)] return [] def _set_unicodes(self, value): if not isinstance(value, list): raise RoboFabError, "unicodes must be a list" try: self._object.setUnicode = value[0] except: pass unicodes = property(_get_unicodes, _set_unicodes, doc="all unicode values for the glyph") def _get_unicode(self): if self._object.unicode is None: return None return self._object.unicodeChar() def _set_unicode(self, value): if type(value) == str: if value is not None and value is not self._object.unicode: self._object.setUnicode_(value) elif type(value) == int: strValue = "%0.4X" % value if strValue is not None and strValue is not self._object.unicode: self._object.setUnicode_(strValue) else: raise(KeyError) unicode = property(_get_unicode, _set_unicode, doc="first unicode value for the glyph") index = property(lambda self: self._object.parent.indexOfGlyph_(self._object)) note = property(lambda self: self._object.valueForKey_("note"), lambda self, value: self._object.setNote_(value)) leftMargin = property(lambda self: self._layer.LSB, lambda self, value: self._layer.setLSB_(value), doc="Left Side Bearing") rightMargin = property(lambda self: self._layer.RSB, lambda self, value: self._layer.setRSB_(value), doc="Right Side Bearing") width = property(lambda self: self._layer.width, lambda self, value: self._layer.setWidth_(value), doc="width") components = property(lambda self: self._layer.components, doc="List of components") guides = property(lambda self: self._layer.guides, doc="List of guides") def appendComponent(self, baseGlyph, offset=(0, 0), scale=(1, 1)): """append a component to the glyph""" new = GSComponent(baseGlyph, offset, scale) self._layer.addComponent_(new) def removeComponent(self, component): """remove a specific component from the glyph""" self._layer.removeComponent_(component) def getPointPen(self): # if "GSPen" in sys.modules.keys(): # del(sys.modules["GSPen"]) from GSPen import GSPointPen return GSPointPen(self, self._layer) def appendAnchor(self, name, position, mark=None): """append an anchor to the glyph""" new = GSAnchor(name=name, pt=position) self._layer.addAnchor_(new) def removeAnchor(self, anchor): """remove a specific anchor from the glyph""" self._layer.removeAnchor_(anchor) def removeContour(self, index): """remove a specific contour from the glyph""" if type(index) == type(int): self._layer.removePathAtIndex_(index) else: self._layer.removePath_(index) def center(self, padding=None): """Equalize sidebearings, set to padding if wanted.""" left = self._layer.LSB right = self._layer.RSB if padding: e_left = e_right = padding else: e_left = (left + right)/2 e_right = (left + right) - e_left self._layer.setLSB_(e_left) self._layer.setRSB_(e_right) def decompose(self): """Decompose all components""" self._layer.decomposeComponents() def clear(self, contours=True, components=True, anchors=True, guides=True): """Clear all items marked as True from the glyph""" if contours: self.clearContours() if components: self.clearComponents() if anchors: self.clearAnchors() if guides: self.clearGuides() def clearContours(self): """clear all contours""" while len(self._layer.paths) > 0: self._layer.removePathAtIndex_(0) def clearComponents(self): """clear all components""" self._layer.setComponents_(NSMutableArray.array()) def clearAnchors(self): """clear all anchors""" self._layer.setAnchors_(NSMutableDictionary.dictionary()) def clearGuides(self): """clear all horizontal guides""" self._layer.setGuideLines_(NSMutableArray.array()) def update(self): self._contours = None #GSGlyphsInfo.updateGlyphInfo_changeName_(self._object, False) def correctDirection(self, trueType=False): self._layer.correctPathDirection() def removeOverlap(self): removeOverlapFilter = NSClassFromString("GlyphsFilterRemoveOverlap").alloc().init() removeOverlapFilter.runFilterWithLayer_error_(self._layer, None) def _mathCopy(self): """ copy self without contour, component and anchor data """ glyph = self._getMathDestination() glyph.name = self.name glyph.unicodes = list(self.unicodes) glyph.width = self.width glyph.note = self.note try: glyph.lib = dict(self.lib) except: pass return glyph anchors = property(lambda self: self._layer.anchors) def getRepresentation(self, representaion): if representaion == "defconAppKit.NSBezierPath": return self._layer.bezierPath.copy() return None def performUndo(self): pass def prepareUndo(self, undoTitle): pass def getLayer(self, name): return RGlyph(layer = self._object.layerForName_(name))