question: contours and components inside some rect
RafaŁ Buchner last edited by gferreira
Small scripting question. (Hopefully this heavy rain of the questions will end up at some point)
What is the easiest way to check if some contour or component in the glyph is inside some abstract rectangle?
I have coordinates and size of the rectangle. Now I would like to check out if the objects shapes are inside it.
Determining if points are inside the rect is easy. But when it comes to components and contours: something that have lines and curves is really hard.
I've been trying to creating the function, that would take the contour or component as an argument, and return True or False value. (True if at least part of the shape is inside the rectangle). I've been trying to do it with the booleanOperators and I failed.
By the way, I'm thinking that it could be a bug:
from mojo.tools import union g = CurrentGlyph() union(g, g, g, roundCoordinates=None)
Traceback (most recent call last): File "<untitled>", line 3, in <module> File "/Applications/RoboFont3.app/Contents/Resources/lib/python3.6/mojo/tools.py", line 84, in union File "/Applications/RoboFont3.app/Contents/Resources/lib/python3.6/mojo/tools.py", line 84, in <listcomp> File "/Applications/RoboFont3.app/Contents/Resources/lib/python3.6/fontParts/base/base.py", line 255, in naked File "/Applications/RoboFont3.app/Contents/Resources/lib/python3.6/fontParts/base/base.py", line 232, in raiseNotImplementedError NotImplementedError: The RSegment subclass does not implement this method.
you can use the bounds of the contours or components to check if they overlap with the rectangle:
def overlaps(contourOrComponent, box): left, bottom, right, top = contourOrComponent.bounds rectLeft, rectBottom, rectRight, rectTop = box xOverlap = right > rectLeft and left < rectRight yOverlap = top > rectBottom and bottom < rectTop if xOverlap and yOverlap: return True else: return False x, y, w, h = 118, 246, 104, 402 box = x, y, x+w, y+h g = CurrentGlyph() for c in g.contours: print(overlaps(c, box), c) for c in g.components: print(overlaps(c, box), c)
union: you need to use a glyph or a list of contours:
from mojo.tools import union g = CurrentGlyph() union(g, [g], [g], roundCoordinates=None)
Two circular components could have overlapping bounds but have no visual overlap. The only option to check is to perform a remove overlap and look for changes. This means for components you have to decompose first.
@frederik true! but in this case we know that the frame is a rectangle – so checking the bounds works too. here’s a proof:
g = CurrentGlyph() x, y, w, h = 206, -218, 358, 392 box = x, y, x+w, y+h translate(230, 270) for contour in g.contours: color = (0, 1, 0) if overlaps(contour, box) else (1, 0, 0) fill(*color) B = BezierPath() contour.draw(B) drawPath(B) stroke(0) strokeWidth(10) fill(None) drawGlyph(g) stroke(0, 0, 1) rect(x, y, w, h)
oke, idd much simpler :)
also take a look at fontTools arrayTools:
RafaŁ Buchner last edited by
Great! Thanks for the help!
RafaŁ Buchner last edited by
@gferreira Hmm, I think it doesn't need to be true (Let's say that we have the shape of the glyph "C". The rect is inside of the letter: then it doesn't work)
@RafaŁ-Buchner you’re right :) better to use the boolean glyph method then.
bahman last edited by
This post is deleted!