Is this possible yet? I’m slanting an entire font and dont want to manually do every glyph that’s a component+path
Job for a simple script.
Sorry this is beyond me, I’m not sure how to to skew it so that the metrics stay the same, I understand it’s something to do with with the centre of the x-height box but I don’t know how to set that in
layer = Glyphs.font.selectedLayers[0] # current layer
layer.applyTransform([
0.5, # x scale factor
0.0, # x skew factor
0.0, # y skew factor
0.5, # y scale factor
0.0, # x position
0.0 # y position
])
Any tips would be appreciated, thanks!
[edit
Here is a shorter version:
#MenuTitle: Skew only Paths and Anchors
# -*- coding: utf-8 -*-
__doc__="""
"""
import GlyphsApp
import math
from AppKit import NSAffineTransform
def slantLayers(layers, angle):
Font.disableUpdateInterface()
xHeight = layers[0].associatedFontMaster().xHeight
transform = NSAffineTransform.new()
slant = math.tan(skewAngle * math.pi / 180.0)
transform.shearXBy_atCenter_(slant, -xHeight / 2.0)
for layer in layers:
for path in layer.paths:
for node in path.nodes:
node.position = transform.transformPoint_(node.position)
for anchor in layer.anchors:
anchor.position = transform.transformPoint_(anchor.position)
Font.enableUpdateInterface()
skewAngle = 13
slantLayers(Glyphs.font.selectedLayers, skewAngle)
Thank you @GeorgSeifert, this is perfect and accurate!
You can also use the transform
tab trigger in the Python for Glyphs repo, find it via the Extend page. The trab trigger expands to a self-explanatory transform()
function which returns the NSAffineTransform
object you need for the slant, scale, rotate, etc. transformation you had in mind.
Just tried running this, but I get this error (when I run it from the macro window):
Traceback (most recent call last):
File "<macro panel>", line 22
File "<macro panel>", line 12, in slantLayers
NameError: name 'selectedLayers' is not defined
Substitute selectedLayers
for layers
(or the other way round, in either case, the argument passed is not actually used properly).
I fixed the code sample.
Now it doesn’t error out, but the transformation is only performed on the visible layer, not all the selected layers.
Works for me. What do you mean by “visible” vs “selected” layers?
A slightly updated version:
#MenuTitle: Skew only Paths and Anchors
# -*- coding: utf-8 -*-
import GlyphsApp
import math
from AppKit import NSAffineTransform
def slantLayers(layers, angle):
Font.disableUpdateInterface()
slantHeight = layers[0].slantHeight()
transform = NSAffineTransform.new()
slant = math.tan(skewAngle * math.pi / 180.0)
transform.shearXBy_atCenter_(slant, -slantHeight)
for layer in layers:
layer.transform_checkForSelection_(transform, False)
Font.enableUpdateInterface()
skewAngle = 13
slantLayers(Font.selectedLayers, skewAngle)
I mean that it only work on the layer I’m currently on, nothing else, even if I have other layers selected.
Say I want to run it on the selected layers like in the screenshot:
Then the script only transforms whatever layer I am currently viewing/editing.
Is this a bug: I select two (or more) layers, and press Cmd+J to copy to the background layer, but only the visible layer is actually copied to the background. Should I not be able to do these operations on all of the selected layers?
Selected Layers doesn’t refers to the selection in the layer panel. It is the selection from the font/edit view.
Is there any way of selecting the content of more layers (and here I’m talking about the layers I have in the layers palette) at once?
Are you talking about another thing also called ‘layers’???
Any way to poll the selection in the layer panel for a script?
You can access everything inside Glyphs. Sometimes the path is a bit hacky.
palettes = Font.parent.windowController().panelSidebarViewController().valueForKey_("paletteInstances")
for palette in palettes:
if "GlyphsPaletteLayers" in palette.__class__.__name__:
break
selectedRows = palette.layersList().selectedRowIndexes()
layers = palette.allSelectedLayers_(selectedRows)
print(layers)
This will return all layers from all glyphs that are selected in Edit/Font view for all selected rows in the layer list.
Perfect, thanks a lot!
So, Claus, you can just use this code sample and replace Font.selectedLayers in the code further up accordingly. This should work (can’t test right now):
#MenuTitle: Skew only Paths and Anchors
# -*- coding: utf-8 -*-
import GlyphsApp
import math
from AppKit import NSAffineTransform
def slantLayers(layers, angle):
Font.disableUpdateInterface()
slantHeight = layers[0].slantHeight()
transform = NSAffineTransform.new()
slant = math.tan(skewAngle * math.pi / 180.0)
transform.shearXBy_atCenter_(slant, -slantHeight)
for layer in layers:
layer.transform_checkForSelection_(transform, False)
Font.enableUpdateInterface()
palettes = Font.parent.windowController().panelSidebarViewController().valueForKey_("paletteInstances")
for palette in palettes:
if "GlyphsPaletteLayers" in palette.__class__.__name__:
break
selectedRows = palette.layersList().selectedRowIndexes()
layers = palette.allSelectedLayers_(selectedRows)
skewAngle = 13
slantLayers(layers, skewAngle)