I am working on a script that should cut a glyph into several parts. To summarize it, it should do a cut of a 10% from the left and make a second one 60% from the left as well.
To do so I am copying the paths into a new sublayer and doing each cut to each layer. However, .cutBetweenPoints() does not seem to work in layers other than the master one and it is cutting the paths on each layer in a quite random way.
Here’s a simplified version of the script as it is right now when iterating through Font.selection and retrieving g:
cLayer = g.layers[Font.masters[0].id]
layerW = cLayer.bounds.size.width
cuts = [layerW * 0.1, layerW * 0.6]
# Iterate through each cut
for i, c in enumerate(cuts):
# Create a new layer for the resulting shape
newLayer = GSLayer()
newLayer.shapes = cLayer.shapes
newLayer.name = 'Left cut %s' % i
newLayer.associatedMasterId = Font.masters[0].id
# Appending the new layer
Font.glyphs[g.name].layers.append(newLayer)
# Applying the cut
cX = cLayer.LSB + c
newLayer.cutBetweenPoints(NSPoint(cutX, layerTop), NSPoint(cutX, layerBottom))
One of the resultant layers looks like this (which is not ok):
I don’t know whether this is bug or I am doing something wrong but the main goal of this script is to two slices from one glyph in different layers. One that goes from to 10% of its width from the left and the other one to 60%.
Thank you so much for any help that anyone will provide.
Also, in a next step I need to use del(layer.shapes[i]) but for some reason it does not work either. It worked at some point but suddenly it stoped working. Using .pop(i) on the array of shapes works, though.
As far as I know, that method works the same way as the knife tool, so your screenshot suggests that it only cut through one segment, not the whole path top to bottom. Instead of layerTop/Bottom try large values like 10000 and -10000.
By the way, this method is buggy in some complex paths or if you cut right through nodes:
# Iterate through each cut
for i, c in enumerate(cuts):
# Create a new layer for the resulting shape
newLayer = cLayer.copy()
newLayer.name = 'Left cut %s' % i
# Appending the new layer
cLayer.parent.layers.append(newLayer)
# Applying the cut
cutX = cLayer.LSB + c
print(NSPoint(cutX, layerTop), NSPoint(cutX, layerBottom))
newLayer.cutBetweenPoints(NSPoint(cutX, layerTop), NSPoint(cutX, layerBottom))
Thank you Georg, this seems to work as well just like the option suggested by @alexs.
Regarding the file, find attached a file with 3 characters. While the script works for O, it does not seem to work with the A or even H. I’ve tried incrementing a bit the cutX value as Alexs said but it didn’t work and resulted with the same output.
I am actually doing it before making any cut with cLayer.removeOverlap() but maybe I need to refresh the layer passed as an argument to the function that handles the cuts since, after removing the overlap I amb calling handleCuts(cLayer).
However, the first cut is done properly but the second one is not.
Ok, I’ve solved it. I was assigning the top NSPoint() coordinate right in the y value of the cap height so the first point was actually on top of a path and this was causing the problem. Something that @alexs was pointing at in one of the responses.
I didn’t notice this until I applied new local guides at the top and bottom values of the cuts.
I’ll keep testing it everything works fine in the rest of the characters.
Hey, I am coming back to this post since I am working on script for a project in which I need to create horizontal cuts to create a stencil version from a solid design.
I have this script that gets the y property of 4 guides that I have named and cuts the glyph at these heights from x -10000 to x 10000. What I am doing there is to rely on the script to remove the in between paths that have been created by these cuts but, for some reason it does not work and it adds points to the paths but not actually cutting them properly.
I have noticed that when I remove layer.removeOverlap() and layer.correctPathDirection() (which I thought would be nice to run before making the cuts) it works better but not sure if its a bug.
Here’s the script:
from Foundation import NSPoint
master = Font.selectedFontMaster
guides = master.guides
cutHeight = 40
for layer in Font.selectedLayers:
for guide in guides:
if guide.name:
layer.removeOverlap()
layer.correctPathDirection()
layer.cutBetweenPoints(NSPoint(-10000, int(guide.y)), NSPoint(10000, int(guide.y)))
#These are arbitrary names I have in my guides
if '1-1' in guide.name or '2-1' in guide.name:
for currentShape in list(layer.shapes):
shape_y = currentShape.bounds.origin.y
shape_h = currentShape.bounds.size.height
if shape_y == guide.y and shape_h == cutHeight:
layer.shapes.remove(currentShape)
layer.correctPathDirection()
the Remove Overlap after you cut is merging the paths again.
try:
from Foundation import NSPoint
master = Font.selectedFontMaster
guides = master.guides
cutHeight = 40
for layer in Font.selectedLayers:
layer.removeOverlap()
for guide in guides:
if guide.name:
layer.cutBetweenPoints(NSPoint(-1000, int(guide.y)), NSPoint(2000, int(guide.y)))
#These are arbitrary names I have in my guides
if '1-1' in guide.name or '2-1' in guide.name:
for currentShape in list(layer.shapes):
shape_y = currentShape.bounds.origin.y
shape_h = currentShape.bounds.size.height
if shape_y == guide.y and shape_h == cutHeight:
layer.shapes.remove(currentShape)
(I didn’t try the second part with the “1-1”, “2-1” guides.)
Ah, I see. I was removing the overlap on each iteration over the guides.
However, in some characters, if I just don’t remove overlaps and correct path directions it still creates some connections between paths in the end instead of cut them in a clean way. Some vertex points (edges of a path) that are right at the same height of the cut, could that be the problem? Is there a way I could create a workaround to prevent this problem?
Good point. However, correcting these shifts might take more time than the one I am saving batch cutting all glyphs. Thanks, though, @GeorgSeifert
Also, out of curiosity, just like instances/exports filters, is there any way I would run a script like this one in an instance other than the ones supported by Glyphs?
Hi, @SCarewe. Maybe I didn’t explain the situation well. Just like these filters (i.e. Roughenizer) are actually running scripts under the hood and applying them to instances, I was wondering whether I could apply a script of my own instead of the default supported by glyphs (see screenshot).
Package your script in a filter plugin (FilterPluginWithoutDialog). Then you can add it as an argument to a Filter custom parameter by referencing its class name.