Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Get bezier path from text.
-
Hello,
I'd like to read a bezier outline from text.
I know i can draw a bezier path with canvas or ui.Path but i want the opposite: i want to pass a text/single letter and return it's bezier path with all the points etc...Is this possible in Pythonista with built in libraries?
-
Here is some ObjC code which does what you are asking. Most of this is just handling multiple letters, etc. If you want a single letter, it looks like
CGPathRef letter = CTFontCreatePathForGlyph(runFont, glyph, NULL);
It should be possible to convert this code (getting the CtFont, and CgGlyph, then calling CTFontCreatePathForGlyph) using the c bindings.
It is then possible to turn that into a UIBezierPath, which then lets you access the control points, if memory serves.
-
Okay, worked up an example:
https://gist.github.com/jsbain/b1d1f69974706735fa352af247f33102
This takes a string a generates a ui.Path. You can access the underlying UIBezierPath using ObjCInstance(p).
-
I tried and got
Fatal Python error: Segmentation fault
Current thread 0x000000016e2f3000 (most recent call first):
File "/private/var/mobile/Containers/Shared/AppGroup/BC53E549-355D-4E77-BC46-64C3D3E0BDAF/Pythonista3/Documents/text to bezier.py", line 11 in <module> -
Hmm, are you using python3.6 or 2.7 interpreter by default? this probably requires 3.x.
This version may be more robust:
https://gist.github.com/b5a56a632996041888be9df56a5d27e3 -
I use Python 3.5 as default.
The new version doesn't crash but nothing appears in the sheet.... -
@JonB I think you need to set
restype
andargtypes
forCTFontCreatePathForGlyph
. It may happen to work for you because you are using (I think) a 32-bit device. -
I use an IPad mini 4, thus 64bits processor
-
@omz yes, quite right, i get lazy when i try things and they work on my device.
This should hopefully work on 64bit as well.
https://gist.github.com/761de9d628d2a6689d73a00d24ac2a53 -
Always a blank sheet on my iPad mini 4, sorry
-
This one works for me (changed slightly from an earlier version), latest one crashes, can't quite figure out why right now.
from objc_util import * import ui font=ObjCClass('UIFont').systemFontOfSize_weight_(64,1) s='Hello world' p=ui.Path() w=0 c.CTFontCreatePathForGlyph.restype = c_void_p c.CTFontCreatePathForGlyph.argtypes = [c_void_p, c_void_p, c_void_p] for x in s.encode('ascii'): glyph= font._defaultGlyphForChar_(x) if not x==32: #space letter = ObjCInstance(c.CTFontCreatePathForGlyph(font, glyph, None)) letterBezier=UIBezierPath.bezierPathWithCGPath_(letter) #transform it so we shift and flip y letterBezier.applyTransform_(CGAffineTransform(1,0,0,-1,w,font.capHeight())) ObjCInstance(p).appendBezierPath_(letterBezier) w+=font.advancementForGlyph(glyph).width class myview(ui.View): def __init__(self): self.frame=(0,0,500,500) self.bg_color='white' def draw(self): ui.set_color('red') p.line_width=1 p.stroke() myview().present('sheet')
-
Ok now
Thanks to @JonB and @omz
Hoping it's what @marcin_dybas wanted -
Wow what a lively community here!
Thanks for all the responses! This works and will be very helpful.By the way... Here is a simulation of what i am trying to do:
https://www.instagram.com/p/BSL9ea8g0dv/?taken-by=marcin.dybasRight now i'm just displaying images depending on touch location. That's already a heavy operation with 200 images and it's just one axis interpolation. I imagine drawing paths would be much faster and lightweight.
My goal is to simulate what variable fonts can do in a fun and interactive way (i will probably incorporate motion control).
But maybe a more than a simulation can be achieved?
@JonB mentioned CTFontCreatePathForGlyph and while i googled it i found this under "Working With Font Variations":
https://developer.apple.com/reference/coretext/ctfont-q6r#1666125Not sure if this means it is possible to open variable fonts and work with them...