drawTextAtPoint() question

Hey there,

I’m writing a small plugin but since I want to test it without restarting Glyphs over and over again I’m using Skedge. The plugin needs to have a specific text in a position and I was wondering what should I do in order to use drawTextAtPoint() inside Skedge. Let’s say just to set a text in the originX, originY of the bounds of a Glyph.

Thanks a lot.

drawTextAtPoint() is a convenience method specific to plugins. You can extract it from plugins.py (find it in the GlyphsSDK) or you do something like this:

NSClassFromString("ReporterPlugin").alloc().init().drawTextAtPoint("hello",NSPoint(50,50))

…not sure though if that works in the context of Skedge.

1 Like

The most direct way is this:

textString = "Hallo"
position = NSPoint(50, 50)
attributes = NSString.drawTextAttributes_(None) # or set a color (NSColor.greenColor)
NSString.stringWithString_(textString).drawAtPoint_withAttributes_(position, attributes)

NSString.drawTextAttributes_ will pick a font size depending on the handle size setting in Preferences. If you are drawing in a scaled context, it is a bit more complicated so I advise to draw in a unscaled callback.

Thanks, Rainer! I knew that function is a convenience method for plugins but still I was wondering if there was a possibility of using it if I would import Glyphs’ plugin module. However, it didn’t work so I moved further and did a bit more of research.

Again, thanks a lot for your help, though!

Great! This works just as expected!

Before I got your response, I also came out with another option that works and scales the text. Here’s the code:

from AppKit import NSClassFromString

text = "Hello"
currentZoom = Glyphs.font.currentTab.scale
fontColor=NSColor.blackColor()

fontAttributes = {
				NSFontAttributeName: NSFont.labelFontOfSize_(10 / currentZoom),
				NSForegroundColorAttributeName: fontColor}

displayText = NSAttributedString.alloc().initWithString_attributes_(unicode(text), fontAttributes)
textAlignment = 0
displayText.drawAtPoint_alignment_((10,10), textAlignment)

It is a bit more complicated but does it make sense or do you think I’ll break at some point?

Thanks!

This is how it is done with objctiveC. Only the first and last lines is not needed:

text = "Hello"
currentZoom = Glyphs.font.currentTab.scale
fontColor = NSColor.textColor()

fontAttributes = {NSFontAttributeName: NSFont.labelFontOfSize_(10 / currentZoom),
				NSForegroundColorAttributeName: fontColor}

displayText = NSAttributedString.alloc().initWithString_attributes_(text, fontAttributes)
displayText.drawAtPoint_((10,10))

And better use NSColor.textColor() to support dark mode.
And I think the unicode(text) is not needed.

One problem with the 10 / currentZoom is that if you zoom in and out you get different optical sizes of the font.

1 Like

Ah, great! Good to know. Also I didn’t consider how the text would behave in Dark Mode so it’s nice that you brought this issue as well.

Just one last question. I’m not sure if its a Skedge issue or (probably) mine but everything works as expected but when I put this block of code inside a function (because I want to use it several times) the Macro Panel prints this error:

Traceback (most recent call last):
  File "SkedgeModule.py", line 268, in drawCode
    exec self.code
  File "<macro>", line 15, in <module>
  File "<macro>", line 9, in testText2
NameError: global name 'NSFontAttributeName' is not defined

Do you know why this is happening?

Thanks again.

That error should come up all the time. So you need to import it.

from AppKit import NSFontAttributeName, NSForegroundColorAttributeName

It still prints this error… Don’t know what’s wrong with it.

I don’t know. What happens if you put the import into the function, too?

It only works if I write from AppKit import *.

However, it prints the following message:
<string>:4: SyntaxWarning: import * only allowed at module level

Then it seems to be somehow related how Skedge is running the code. I would say, ignore the warning for now.