omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    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.

    Pythonista
    4
    13
    7377
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • JonB
      JonB last edited by

      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.

      1 Reply Last reply Reply Quote 0
      • JonB
        JonB last edited by

        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).

        1 Reply Last reply Reply Quote 0
        • cvp
          cvp last edited by

          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>

          1 Reply Last reply Reply Quote 0
          • JonB
            JonB last edited by JonB

            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

            1 Reply Last reply Reply Quote 0
            • cvp
              cvp last edited by

              I use Python 3.5 as default.
              The new version doesn't crash but nothing appears in the sheet....

              1 Reply Last reply Reply Quote 0
              • omz
                omz last edited by

                @JonB I think you need to set restype and argtypes for CTFontCreatePathForGlyph. It may happen to work for you because you are using (I think) a 32-bit device.

                JonB 1 Reply Last reply Reply Quote 0
                • cvp
                  cvp last edited by

                  I use an IPad mini 4, thus 64bits processor

                  1 Reply Last reply Reply Quote 0
                  • JonB
                    JonB @omz last edited by

                    @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

                    1 Reply Last reply Reply Quote 0
                    • cvp
                      cvp last edited by

                      Always a blank sheet on my iPad mini 4, sorry

                      1 Reply Last reply Reply Quote 0
                      • omz
                        omz last edited by

                        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')
                        
                        1 Reply Last reply Reply Quote 1
                        • cvp
                          cvp last edited by cvp

                          Ok now
                          Thanks to @JonB and @omz
                          Hoping it's what @marcin_dybas wanted

                          1 Reply Last reply Reply Quote 0
                          • marcin_dybas
                            marcin_dybas last edited by

                            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.dybas

                            Right 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#1666125

                            Not sure if this means it is possible to open variable fonts and work with them...

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post
                            Powered by NodeBB Forums | Contributors