Python library for direct Bezier manipulation

Simon CozensSimon Cozens Posts: 297
edited September 14 in Font Technology
I’ve been asked to write a tool which performs various transformations to outlines in an OTF, and am now trying to get my head around the various parts of the Python font manipulation ecosystem.

Previously I have written plugins for editors which all come with their own libraries for manipulating Beziers, but this one will be a command line tool using fonttools.

What I’m looking for is an independent library which takes an outline in some format and has functions to add extrema and inflections, rotate, translate, offset, simplify, delete and keep shape, split curve at a point, harmonize, etc. - all the usual operations you want when manipulating curves.

Does such a library exist already? It seems like there should be but I have not found anything in fonttools, robofog, etc. - maybe I’m missing the obvious or maybe the documentation isn’t great.

If not, I think it would be useful to have and I wonder if there would be some value in one which also converted between different Bezier representations (array, NSBezierPath, Glyphs, etc.). I’m happy to write one since I will need it for this project.

Comments

  • Some of the operations you mentioned are simple and require one some lines of code (transformations, adding extrem points...). Others are way more complicated (simplify curve, merge curves). 

    There is code available for some...
  • Simon CozensSimon Cozens Posts: 297
    edited September 14
    I think most of these operations are simple; the hard part is dealing with the various different representations of a curve that different tools use. But as you know the point of having a library is so we don’t all have to be cutting and pasting these different operations again and again.

    Basically I am looking for the Python equivalent of https://pomax.github.io/bezierjs/
  • Converting between the different representations is not that difficult. Write a pen that outputs your internal format. There are pens for NSBezierPath and ttx. 
  • Simon CozensSimon Cozens Posts: 297
    edited September 14
    When you say “pens”, do you mean that fonttools is the library I should be using for manipulating Beziers? (Or robofab? Or either one of those?)
  • Dave CrosslandDave Crossland Posts: 988
    edited September 14
    Pens is a commonly used pattern for manipulation of outlines, used both in fonttools and robofab
  • @Simon Cozens, regretfully there is none. I have been looking for one from quite some time, but with no success.. I even tough reimplementig pomax.bezierjs with their permission, as I saw others have done so in different languages, but didn't had the time... If you find one, or decide to write one and need a helping hand, seek me out - I am very interested, just do not want to do it all by myself (I presume you also :) )!
  • Jens KutilekJens Kutilek Posts: 181
    edited September 14
    I have a module that models a "SuperCubic" which consists of one or more consecutive cubic segments defined by 4 point tuples. The Super Cubic can calculate its own extremum points and inflection points, rasterize into line segments, split at a given t or point (on or close to the curve).

    More functions could be added. Especially simplification and harmonizing could be interesting. Maybe the "SuperCubic" is a good starting point because it already can work across multiple cubic segments.

    I could upload it to GitHub if there's any interest.
  • Khaled HosnyKhaled Hosny Posts: 214
    edited September 15
    FontTools pens can do some of these operations, see TransformPen for example. There are some more pens in https://github.com/robofab-developers/fontPens/, and there is also https://github.com/googlei18n/cu2qu/ for converting cubic to quadratic (and can convert multiple masters in compatible way).
  • Khaled HosnyKhaled Hosny Posts: 214
    edited September 15
    There is also fontTools.misc.bezierTools and fontTools.misc.symfont and you can probably find more stuff in FontTools.

  • I could upload it to GitHub if there's any interest.
    Please. Sounds like the perfect starting point.
  • @Jens Kutilek I would love to take a look at the Superbezier module also! Thank you in advance!
  • I have developed a suite of functionality for manipulating/modifying Bézier curves and glyph contours that I would consider contributing. It’s been all for my own use so far since I use FontForge for my work, but I tried to keep the bulk of it app-agnostic so it can be used in a more general way.
  • This is my module: jkFontGeometry

    Let me know if you have any questions or suggestions. A demo script for Glyphs that extracts the SuperCubics from the current layer is included to get you started.

    Some functions are provided in a c extension for speed. This is optional, the same functions are available in pure Python from jkFontGeometry.geometry.
  • https://github.com/typemytype/booleanOperations implements boolean Operations such as union / intersection etc. (I would consider this as one of the hardest parts of writing an own library; other things like transformations, extrema, subdivision, joining, expanding a stroke are relatively easy).

    Khaled Hosny already mentioned fontTools.misc.bezierTools: https://github.com/typesupply/defcon and other bigger projects also makes use of fontTools.misc.bezierTools, it may be worth to have a look at them as well, because they implement additional methods.



  • Propped path expanding is not so easy (at least not for me). I figured out my own algorithm to remove overlap but my path expansion is not where I like it to be. Especially the inner curve with small radius.
  • +1 to what Georg said. Actually, path expansion and remove overlap both have some interesting “corner cases,” where things get extra complicated.
  • Okay, I admit: path expansion is tricky when the curvature radius of the path is smaller than the pen radius.
Sign In or Register to comment.