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
    7373
    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.
    • marcin_dybas
      marcin_dybas last edited by

      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?

      1 Reply Last reply Reply Quote 0
      • 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