def getHorizontalIntersection(point, a, b, c, d): try: # intersecting line e = NSPoint(-10000, point.y) f = NSPoint(10000, point.y) intersections = GSIntersectBezier3Line(a, b, c, d, e, f) intersection = intersections[0].pointValue() return intersection except: #print('Could not find horizontal intersection') return None
def getVerticalIntersection(point, a, b, c, d): try: # intersecting line e = NSPoint(point.x, -10000) f = NSPoint(point.x, 10000) intersections = GSIntersectBezier3Line(a, b, c, d, e, f) intersection = intersections[0].pointValue() return intersection except: #print('Could not find vertical intersection') return None
def _drawTextLabel(self, transform, text, size, vector, percent=1.0): if text is None: return if vector is None: vector = (-1, 1) angle = atan2(vector[0], -vector[1]) text_size = 0.5 * size # para_style = NSMutableParagraphStyle.alloc().init() # para_style.setAlignment_(NSCenterTextAlignment) attrs = { NSFontAttributeName: NSFont.systemFontOfSize_(text_size), NSForegroundColorAttributeName: NSColor.colorWithCalibratedRed_green_blue_alpha_( text_color[0], text_color[1], text_color[2], text_color[3] * percent, ), # NSParagraphStyleAttributeName: para_style, } myString = NSString.string().stringByAppendingString_(text) bbox = myString.sizeWithAttributes_(attrs) bw = bbox.width bh = bbox.height text_pt = NSPoint() text_pt.y = 0 if -0.5 * pi < angle <= 0.5 * pi: text_pt.x = -1.3 * size - bw / 2 * cos(angle) - bh / 2 * sin(angle) else: text_pt.x = -1.3 * size + bw / 2 * cos(angle) + bh / 2 * sin(angle) text_pt = transform.transformPoint_(text_pt) rr = NSRect(origin=(text_pt.x - bw / 2, text_pt.y - bh / 2), size=(bw, bh)) if DEBUG: NSColor.colorWithCalibratedRed_green_blue_alpha_(0, 0, 0, 0.15).set() myRect = NSBezierPath.bezierPathWithRect_(rr) myRect.setLineWidth_(0.05 * size) myRect.stroke() myString.drawInRect_withAttributes_(rr, attrs)
def editTextCallback_(self, textField): try: newValue = float( textField.stringValue() ) except ValueError: self.update() return anchorName = self.anchorNames[textField.tag()] for layer in self.font.selectedLayers: for anchor in layer.anchors: if anchor.name == anchorName: if textField.frame().origin.x == self.posxFieldsOriginX: layer.anchors[anchorName].position = NSPoint( newValue, layer.anchors[anchorName].position.y ) else: layer.anchors[anchorName].position = NSPoint( layer.anchors[anchorName].position.x, newValue ) break
def insert_paths(to_layer, from_layer, alignment, as_component_is_checked, clear_contents): # clear layer if clear_contents: to_layer.background.clear() if as_component_is_checked: # insert as component shift = (to_layer.width - from_layer.width) if alignment == RIGHT else 0 from_glyph_name = from_layer.parent.name to_layer.background.components.append( GSComponent(from_glyph_name, NSPoint(shift, 0))) # select component (makes is quicker to move around the shape later) if to_layer.background.components: to_layer.background.components[-1].selected = True else: # insert all paths for path in from_layer.copyDecomposedLayer().paths: if alignment == RIGHT: shift = to_layer.width - from_layer.width for node in path.nodes: node.x = node.x + shift to_layer.background.paths.append(path) # select path (makes is quicker to move around the shape later) to_layer.background.paths[-1].selected = True
def saveScrawlToBackground(self, layer): font = layer.parent.parent if font.filepath is None: print( "You must save the Glyphs file before a Scrawl background image can be added." ) return data = layer.userData["%s.data" % plugin_id] pixel_size = layer.userData["%s.unit" % plugin_id] pixel_ratio = layer.master.customParameters['ScrawlPenRatio'] if pixel_ratio is None: pixel_ratio = default_pixel_ratio else: pixel_ratio = float(pixel_ratio) rect = NSMakeRect(*layer.userData["%s.rect" % plugin_id]) if data is not None: image_path = join(dirname(font.filepath), "%s-%s.png" % (layer.layerId, layer.parent.name)) try: imgdata = NSBitmapImageRep.alloc().initWithData_(data) except: print("Error saving the image file.") return pngdata = imgdata.representationUsingType_properties_( NSPNGFileType, None) pngdata.writeToFile_atomically_(image_path, False) layer.backgroundImage = GSBackgroundImage(image_path) layer.backgroundImage.position = NSPoint(rect.origin.x, rect.origin.y) layer.backgroundImage.scale = (float(pixel_size), float(pixel_size * pixel_ratio))
def draw_texture(self, texture, location, scale): ''' Draws the texture into this build's graphics context at the location, to the given scale. self.render() needs to a call parent of this method, in order to set up the Cocoa graphics context for the draw calls to work texture: a Texture object location: (tx, ty) tuple scale: (sx, sy) tuple ''' tx, ty = location sx, sy = scale # Cache all assets so we don't frequently reload our PDFs. path = texture.path() if path in Build._asset_cache: tex = Build._asset_cache[path].copy() else: tex = NSImage.alloc().initWithContentsOfFile_(path) Build._asset_cache[path] = tex.copy() if isinstance(texture, TextureWithIndex): rep = tex.representations()[0] rep.setCurrentPage_(texture.index()) # TODO: support opacity if (sx != 1 or sy != 1): #tex = tex.resize((sx, sy)) tex.setSize_(NSSize(sx, sy)) # Cocoa uses inverted Y-axis... ty_ = self.kpf.height - tex.size().height - ty tex.drawAtPoint_fromRect_operation_fraction_(NSPoint(tx, ty_), NSZeroRect, NSCompositeSourceOver, 1.0)
def rotate5(): fifth_circle = - math.pi * 2 / 5; sum_x = sum( [ p.x for c in contours for p in c ] ) sum_y = sum( [ p.y for c in contours for p in c ] ) num_p = sum( [ len( c ) for c in contours ] ) cgx = sum_x / num_p cgy = sum_y / num_p cg = NSPoint( cgx, cgy ) for contour in contours: partner1 = len(contour)//5 partner2 = 2 * partner1 partner3 = 3 * partner1 partner4 = 4 * partner1 for n in range(partner1): vector = blend_points( subtractPoints( contour[n].position, cg ), rotated_vector( contour[partner1].position, fifth_circle, cg ), rotated_vector( contour[partner2].position, fifth_circle * 2, cg ), rotated_vector( contour[partner3].position, fifth_circle * 3, cg ), rotated_vector( contour[partner4].position, fifth_circle * 4, cg ) ) contour[n].position = addPoints( cg, vector ) contour[partner1].position = addPoints( cg, rotated_vector( vector, -fifth_circle ) ) contour[partner2].position = addPoints( cg, rotated_vector( vector, -fifth_circle * 2 ) ) contour[partner3].position = addPoints( cg, rotated_vector( vector, -fifth_circle * 3 ) ) contour[partner4].position = addPoints( cg, rotated_vector( vector, -fifth_circle * 4 ) ) partner1 = ( partner1 + 1 ) % len(contour) partner2 = ( partner2 + 1 ) % len(contour) partner3 = ( partner3 + 1 ) % len(contour) partner4 = ( partner4 + 1 ) % len(contour)
def isWindowOnDockingSide(self, dockingWindow): ''' checks whenever dragged docking window is above any dock bar ''' winX, winY, winW, winH = dockingWindow.getPosSize() titleBarHeight = self._calculateParentWindowTitlebarHeight() x, y = (winX + winW / 2, winY - titleBarHeight / 2) px, py, pw, ph = self.getParentWindowPosSize() titleBarMiddlePoint = NSPoint(pw - (px - x) - pw, (py - y) + ph) isDockingWindowAbove = False dockingPosition = None for position in self.dockingRectPosSizes.keys(): dockingSideObj = getattr(self, f'{position}_dockbar', None) if dockingSideObj is not None: view = dockingSideObj.getNSView().hitTest_(titleBarMiddlePoint) if view is not None: dockingSideObj.getNSView().layer().setBackgroundColor_( NSColor.orangeColor().CGColor()) dockingPosition = position isDockingWindowAbove = True else: dockingSideObj.getNSView().layer().setBackgroundColor_( NSColor.clearColor().CGColor()) if isDockingWindowAbove: dockingWindow.getNSWindow().setAlphaValue_(.4) else: dockingWindow.getNSWindow().setAlphaValue_(1) return dockingPosition, self
def _drawTextLabel(self, transform, text, size, vector): if vector is None: vector = (-1, 1) angle = atan2(vector[0], -vector[1]) text_size = 0.5 * size #para_style = NSMutableParagraphStyle.alloc().init() #para_style.setAlignment_(NSCenterTextAlignment) attrs = { NSFontAttributeName: NSFont.systemFontOfSize_(text_size), NSForegroundColorAttributeName: NSColor.colorWithCalibratedRed_green_blue_alpha_( 0.4, 0.4, 0.6, 0.7 ), #NSParagraphStyleAttributeName: para_style, } myString = NSString.string().stringByAppendingString_(text) bbox = myString.sizeWithAttributes_(attrs) bw = bbox.width bh = bbox.height text_pt = NSPoint() text_pt.y = 0 if -0.5 * pi < angle <= 0.5 * pi: text_pt.x = -1.3 * size - bw / 2 * cos(angle) - bh / 2 * sin(angle) else: text_pt.x = -1.3 * size + bw / 2 * cos(angle) + bh / 2 * sin(angle) text_pt = transform.transformPoint_(text_pt) rr = NSRect( origin = (text_pt.x - bw / 2, text_pt.y - bh / 2), size = (bw, bh) ) if DEBUG: NSColor.colorWithCalibratedRed_green_blue_alpha_( 0, 0, 0, 0.15 ).set() myRect = NSBezierPath.bezierPathWithRect_(rr) myRect.setLineWidth_(0.05 * size) myRect.stroke() myString.drawInRect_withAttributes_( rr, attrs )
def init(self): self = super(DefconAppKitGlyphLineNSView, self).init() self._showLayers = False self._layerDrawingAttributes = {} self._fallbackDrawingAttributes = dict( showGlyphFill=True, showGlyphStroke=False, showGlyphOnCurvePoints=False, showGlyphStartPoints=False, showGlyphOffCurvePoints=False, showGlyphPointCoordinates=False, showGlyphAnchors=False, showGlyphImage=False, showGlyphMargins=False, showFontVerticalMetrics=False, showFontPostscriptBlues=False, showFontPostscriptFamilyBlues=False) self._glyphRecords = [] self._alternateRects = {} self._currentZeroZeroPoint = NSPoint(0, 0) self._rightToLeft = False self._pointSize = 150 self._impliedPointSize = 150 self._scale = 1.0 self._inverseScale = 0.1 self._upm = 1000 self._descender = -250 self._bufferLeft = self._bufferRight = self._bufferBottom = self._bufferTop = 15 self._cutoffDisplayPointSizes = dict(showFontVerticalMetrics=150, showGlyphStartPoints=175, showGlyphOnCurvePoints=175, showGlyphOffCurvePoints=175, showGlyphPointCoordinates=250, showGlyphAnchors=50) self._fitToFrame = None self._backgroundColor = NSColor.whiteColor() self._glyphColor = NSColor.colorWithCalibratedRed_green_blue_alpha_( 0, 0, 0, 1) self._strokeColor = None self._pointColor = None self._alternateHighlightColor = defaultAlternateHighlightColor self._notdefBackgroundColor = NSColor.colorWithCalibratedRed_green_blue_alpha_( 1, 0, 0, .25) return self
def copyAnchor(thisLayer, anchorName, anchorX, anchorY): newAnchor = GSAnchor.alloc().init() newAnchor.name = anchorName thisLayer.addAnchor_(newAnchor) newPosition = NSPoint(anchorX, anchorY) newAnchor.setPosition_(newPosition)
def solveCubicBezier(p1, p2, p3, p4): """ Solve cubic Bezier equation and 1st and 2nd derivative. """ a = NSPoint() a.x = -p1.x + 3.0 * p2.x - 3.0 * p3.x + p4.x a.y = -p1.y + 3.0 * p2.y - 3.0 * p3.y + p4.y b = NSPoint() b.x = 3.0 * p1.x - 6.0 * p2.x + 3.0 * p3.x b.y = 3.0 * p1.y - 6.0 * p2.y + 3.0 * p3.y c = NSPoint() c.x = -3.0 * p1.x + 3.0 * p2.x c.y = -3.0 * p1.y + 3.0 * p2.y d = p1 return a, b, c, d
from AppKit import NSPoint from mojo.events import MeasurementTool measurement = MeasurementTool.measurementClass() measurement.startPoint = NSPoint(100, 100) measurement.endPoint = NSPoint(200, 200) g = CurrentGlyph() g.naked().measurements.append(measurement) g.update()
def interpolatedPosition( self, foregroundPosition, backgroundPosition, factor ): interpolatedX = foregroundPosition.x * factor + backgroundPosition.x * factor interpolatedY = foregroundPosition.y * factor + backgroundPosition.y * factor interpolatedPosition = NSPoint( interpolatedX, interpolatedY ) return interpolatedPosition
def blend_points(p0, p1, p2, p3, p4): return NSPoint(0.2 * (p0.x + p1.x + p2.x + p3.x + p4.x), 0.2 * (p0.y + p1.y + p2.y + p3.y + p4.y))
def rotated_vector(p, angle, center=NSPoint(0, 0)): v = NSPoint(p.x - center.x, p.y - center.y) result = NSPoint() result.x += v.x * math.cos(angle) - v.y * math.sin(angle) result.y += v.x * math.sin(angle) + v.y * math.cos(angle) return result
def solveCubicBezierCurvature(a, b, c, d, t): """ Calc curvature using cubic Bezier equation and 1st and 2nd derivative. Returns position of on-curve point p1234, and vector of 1st and 2nd derivative. """ r = NSPoint() t3 = t**3 t2 = t**2 r.x = a.x * t3 + b.x * t2 + c.x * t + d.x r.y = a.y * t3 + b.y * t2 + c.y * t + d.y r1 = NSPoint() r1.x = 3 * a.x * t2 + 2 * b.x * t + c.x r1.y = 3 * a.y * t2 + 2 * b.y * t + c.y r2 = NSPoint() r2.x = 6 * a.x * t + 2 * b.x r2.y = 6 * a.y * t + 2 * b.y return (r, r1, r2, (r1.x * r2.y - r1.y * r2.x) / (r1.x**2 + r1.y**2)**1.5)
def background(self, layer): # Check if the grid should be drawn currentController = self.controller.view().window().windowController() if currentController: tool = currentController.toolDrawDelegate() if (tool.isKindOfClass_(NSClassFromString("GlyphsToolText")) or tool.isKindOfClass_(NSClassFromString("GlyphsToolHand"))): return try: master = layer.parent.parent.masters[layer.layerId] except KeyError: return if master is None: return gx, gy, grid_type = getGrid(master) if gx == 0 or gy == 0: return if grid_type == "div": upm = layer.parent.parent.upm gx = upm / gx gy = upm / gy NSColor.lightGrayColor().set() NSBezierPath.setDefaultLineWidth_(0.6 / self.getScale()) max_x = int(layer.width // gx + 2) min_y = int(master.descender // gy) max_y = int(master.ascender // gy + 1) max_xx = max_x * gx min_yy = min_y * gy max_yy = max_y * gy for x in range(-1, max_x + 1): xx = gx * x NSBezierPath.strokeLineFromPoint_toPoint_(NSPoint(xx, min_yy), NSPoint(xx, max_yy)) for y in range(min_y, max_y + 1): yy = gy * y NSBezierPath.strokeLineFromPoint_toPoint_(NSPoint(-gx, yy), NSPoint(max_xx, yy)) # NSBezierPath.setDefaultLineWidth_(1.0/self.getScale()) s = int(round(12 / self.getScale())) s2 = s * 0.25 sel = int(round(13 / self.getScale())) for p in layer.paths: for n in p.nodes: if n.type != OFFCURVE: x = n.position.x y = n.position.y if n.selected: s1 = sel else: s1 = s if abs((abs(x) + 1) % gx - 1) < 0.5: NSBezierPath.strokeLineFromPoint_toPoint_( NSPoint(x - s2, y - s1), NSPoint(x - s2, y + s1)) NSBezierPath.strokeLineFromPoint_toPoint_( NSPoint(x + s2, y - s1), NSPoint(x + s2, y + s1)) if abs((abs(y) + 1) % gy - 1) < 0.5: NSBezierPath.strokeLineFromPoint_toPoint_( NSPoint(x - s1, y - s2), NSPoint(x + s1, y - s2)) NSBezierPath.strokeLineFromPoint_toPoint_( NSPoint(x - s1, y + s2), NSPoint(x + s1, y + s2))
def _drawArrow(position, kind, size, vector=(-1, 1), label_size=1): angle = atan2(vector[0], -vector[1]) print vector, "%0.2f°" % degrees(angle) x, y = position head_ratio = 0.7 w = size * 0.5 tail_width = 0.3 chin = 0.5 * (w - w * tail_width) # part under the head NSColor.colorWithCalibratedRed_green_blue_alpha_( 0.9, 0.1, 0.0, 0.85 ).set() t = NSAffineTransform.transform() t.translateXBy_yBy_(x, y) t.rotateByRadians_(angle) myPath = NSBezierPath.alloc().init() myPath.moveToPoint_( (0, 0) ) myPath.relativeLineToPoint_( (-size * head_ratio, w * 0.5) ) myPath.relativeLineToPoint_( (0, -chin) ) myPath.relativeLineToPoint_( (-size * (1 - head_ratio), 0) ) myPath.relativeLineToPoint_( (0, -w * tail_width) ) myPath.relativeLineToPoint_( (size * (1 - head_ratio), 0) ) myPath.relativeLineToPoint_( (0, -chin) ) myPath.closePath() myPath.transformUsingAffineTransform_(t) myPath.fill() drawPath(myPath) myString = NSString.string().stringByAppendingString_(kind) attrs = { NSFontAttributeName: NSFont.systemFontOfSize_(label_size), NSForegroundColorAttributeName: NSColor.colorWithCalibratedRed_green_blue_alpha_( 0.4, 0.4, 0.6, 0.7 ), } bbox = myString.sizeWithAttributes_(attrs) #print bbox p = NSPoint() bw = bbox.width bh = bbox.height #print " ", cos(angle) if -0.5 * pi < angle <= 0.5 * pi: p.x, p.y = ( - size - 20 - bh/2 * sin(angle) - bw/2 * cos(angle), # + bw/2.0 * cos(angle - pi) 0 ) else: p.x, p.y = ( - size - 20 + bh/2 * sin(angle) + bw/2 * cos(angle), # + bw/2.0 * cos(angle - pi) 0, ) p = t.transformPoint_(p) #print p #fontSize(label_size) #text(kind, (p.x - bbox.width/2, p.y - bbox.height/2)) fill(None) rect(p.x - bbox.width/2, p.y - bbox.height/2, bbox.width, bbox.height) fill(1, 0, 0) #oval(p.x -bh/2.0 , p.y -bh/2.0, bh, bh) #myString.drawAtPoint_withAttributes_(p, attrs) rr = NSRect(origin=(p.x -bh/2.0, p.y -bw/2.0), size=(bw, bh)) #print rr myString.drawInRect_withAttributes_(rr, attrs) myString.drawAtPoint_withAttributes_(p, attrs)
def drawRectRightToLeft_(self, rect): self._alternateRects = {} # draw the background bounds = self.bounds() self._backgroundColor.set() NSRectFill(bounds) # create some reusable values scale = self._scale descender = self._descender upm = self._upm scrollWidth = bounds.size[0] # offset for the buffer ctx = NSGraphicsContext.currentContext() ctx.saveGraphicsState() aT = NSAffineTransform.transform() aT.translateXBy_yBy_(scrollWidth - self._bufferLeft, self._bufferTop) aT.concat() # offset for the descender aT = NSAffineTransform.transform() aT.scaleBy_(scale) aT.translateXBy_yBy_(0, descender) aT.concat() # flip flipTransform = NSAffineTransform.transform() flipTransform.translateXBy_yBy_(0, upm) flipTransform.scaleXBy_yBy_(1.0, -1.0) flipTransform.concat() # set the glyph color self._glyphColor.set() # draw the records left = scrollWidth - self._bufferLeft bottom = self._bufferTop height = upm * scale previousXA = 0 for recordIndex, glyphRecord in enumerate(reversed( self._glyphRecords)): glyph = glyphRecord.glyph w = glyphRecord.advanceWidth h = glyphRecord.advanceHeight xP = glyphRecord.xPlacement yP = glyphRecord.yPlacement xA = glyphRecord.xAdvance yA = glyphRecord.yAdvance # handle offsets from the record bottom += yP * scale glyphHeight = height + ((h + yA) * scale) glyphLeft = left + ((-w + xP - xA) * scale) glyphWidth = (-w - xA) * scale # store the glyph rect for the alternate menu rect = ((glyphLeft, bottom), (glyphWidth, glyphHeight)) self._alternateRects[rect] = recordIndex self._currentZeroZeroPoint = NSPoint( glyphLeft, bottom + height + (descender * scale)) # handle the placement aT = NSAffineTransform.transform() if xP: xP += previousXA aT.translateXBy_yBy_(-w - xA + xP, yP) aT.concat() # draw the glyph rect = ((-w + xA - xP, descender - yP), (w, upm)) self.drawGlyph(glyph, rect, alternate=bool(glyphRecord.alternates)) # shift for the next glyph aT = NSAffineTransform.transform() aT.translateXBy_yBy_(-xP, h + yA - yP) aT.concat() left += (-w - xP - xA) * scale previousXA = xA ctx.restoreGraphicsState()
def foreground(self, Layer): """ Whatever you draw here will be displayed IN FRONT OF the paths. Setting a color: NSColor.colorWithCalibratedRed_green_blue_alpha_( 1.0, 1.0, 1.0, 1.0 ).set() # sets RGBA values between 0.0 and 1.0 NSColor.redColor().set() # predefined colors: blackColor, blueColor, brownColor, clearColor, cyanColor, darkGrayColor, grayColor, greenColor, lightGrayColor, magentaColor, orangeColor, purpleColor, redColor, whiteColor, yellowColor Drawing a path: myPath = NSBezierPath.alloc().init() # initialize a path object myPath myPath.appendBezierPath_( subpath ) # add subpath to myPath myPath.fill() # fill myPath with the current NSColor myPath.stroke() # stroke myPath with the current NSColor To get an NSBezierPath from a GSPath, use the bezierPath() method: myPath.bezierPath().fill() You can apply that to a full layer at once: if len( myLayer.paths > 0 ): myLayer.bezierPath() # all closed paths myLayer.openBezierPath() # all open paths See: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSBezierPath_Class/Reference/Reference.html https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/classes/NSColor_Class/Reference/Reference.html """ try: thisGlyph = Layer.parent Font = thisGlyph.parent xHeight = Font.selectedFontMaster.xHeight angle = Font.selectedFontMaster.italicAngle yPos = -100 # rotation point is half of x-height offset = math.tan(math.radians(angle)) * xHeight / 2 shift = math.tan(math.radians(angle)) * yPos - offset glyphLeftMetricsKey = thisGlyph.leftMetricsKey glyphRightMetricsKey = thisGlyph.rightMetricsKey layerLeftMetricsKey = Layer.leftMetricsKey() layerRightMetricsKey = Layer.rightMetricsKey() layerWidth = Layer.width + 10.0 leftMetricsKeyString = "Glyph: '%s'\nLayer: '%s'" % ( glyphLeftMetricsKey, layerLeftMetricsKey) rightMetricsKeyString = "Glyph: '%s'\nLayer: '%s'" % ( glyphRightMetricsKey, layerRightMetricsKey) leftMetricsKeyString = leftMetricsKeyString.replace("'None'", "-") rightMetricsKeyString = rightMetricsKeyString.replace( "'None'", "-") # Text Alignments: # top left: 6 # top center: 7 # top right: 8 # center left: 3 # center center: 4 # center right: 5 # bottom left: 0 # bottom center: 1 # bottom right: 2 self.drawTextAtPoint(leftMetricsKeyString, NSPoint(-10.0 + shift, yPos), fontSize=9.0, textAlignment=2, fontColor=NSColor.orangeColor()) self.drawTextAtPoint(rightMetricsKeyString, NSPoint(layerWidth + shift, yPos), fontSize=9.0, textAlignment=0, fontColor=NSColor.orangeColor()) except Exception as e: self.logToConsole("drawForegroundForLayer_: %s" % str(e))