{"id":13741836,"url":"https://github.com/sillsdev/fontinline","last_synced_at":"2025-12-30T18:43:12.871Z","repository":{"id":11941897,"uuid":"14511725","full_name":"sillsdev/fontinline","owner":"sillsdev","description":"Make inline stroke paths from an outline font","archived":false,"fork":false,"pushed_at":"2018-08-08T02:43:44.000Z","size":156,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-11-15T12:37:06.879Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sillsdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-11-19T02:23:18.000Z","updated_at":"2024-01-01T03:24:40.000Z","dependencies_parsed_at":"2022-09-25T05:11:22.656Z","dependency_job_id":null,"html_url":"https://github.com/sillsdev/fontinline","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sillsdev%2Ffontinline","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sillsdev%2Ffontinline/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sillsdev%2Ffontinline/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sillsdev%2Ffontinline/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sillsdev","download_url":"https://codeload.github.com/sillsdev/fontinline/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253158354,"owners_count":21863280,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T04:01:03.153Z","updated_at":"2025-12-30T18:43:12.865Z","avatar_url":"https://github.com/sillsdev.png","language":"Python","readme":"fontinline\n==========\n\nMake inline stroke paths from an outline font\n\nRequirements (Debian/Ubuntu):\n\n    sudo apt-get install git python-shapely python-fontforge cython build-essential python-dev\n    sudo apt-get install python-pygame  # Optional\n    git clone http://github.com/hansent/python-poly2tri\n    git clone http://github.com/sillsdev/fontinline\n    cd python-poly2tri\n    python setup.py build_ext -i\n    ls p2t.so || echo Something failed, fix it and rebuild p2t\n    cp p2t.so ../fontinline\n    cd ../fontinline\n    python extractpoints.py inputfont.ttf -o outputfont.ttf\n\nNote that python-pygame is optional: if you never use the \"--show-foo\" options\n(where foo can be triangles, lines, dots or glyph) or their one-letter short\nversions (-t, -l, -d or -g), then the pygame dependency will not be required.\nIf you try to use those options and pygame is not installed, you'll see\n\"ImportError: No module named pygame\". If that happens, simply run the\n\"sudo apt-get install python-pygame\" command and try again.\n\nCode structure\n--------------\n\nOn a high level, the fontinline code operates by the following method:\n\n1. Convert the glyph to a polygon made up of straight lines\n   * Bezier curves will be converted to a series of straight lines by subdividing the Bezier curve N times, with N continually increasing until no two straight lines in the curve are at more than 3 degrees from each other. This produces a polygon that's a good approximation of the glyph, with a similar area and perimeter length.\n1. Use that polygon to figure out the \"stroke width\" of the glyph:\n   * First, assume the glyph has the general shape of a letter that can be drawn with a pen: it could be represented as one or more rectangles that have been bent into various curves or angles. (This assumption will fail for glyphs that are filled circles, like the period or colon, but will hold true for most letters in most writing systems.)\n   * If that's the case, the \"width\" of those bent rectangles can be found by treating the glyph as a polygon, and using the formula 2 * (polygon's area) / (polygon's perimeter)\n1. Convert the glyph to a polygon made up of straight lines AGAIN\n   * This time, instead of converting Bezier curves to straight lines at no more than 3 degree angles to each other, the straight lines will have a minimum length of at least (glyph's stroke width). This is critical for the triangulation step that comes next: without this minimum length, the triangulation often ends up producing suboptimal results at curves. (TODO: Make a diagram of what happens when this step is omitted.)\n1. Produce a Delauney triangulation of the glyph polygon\n   * This uses the poly2tri Python library from http://github.com/hansent/python-poly2tri\n1. Consider each separate triangle of the Delauney triangulation. Throw out the triangle sides that coincide with the side of a glyph. Take the centerpoint of each remaining side, and draw straight lines between each centerpoint. This produces a rough, but generally quite accurate, \"midline\" for the glyph.\n1. Take the midline produced in the previous step and draw dots at a (tweakable) interval along each one.\n\nTODO\n----\n\n* Place dots at 0.0 and 1.0 of endpoints (sometimes they're not landing\n  at the end of the midlines, which seems like a bug)\n* If endpoint dots within 50% of another dot, drop other dot\n    * (This calculation might be slightly tricky, but will be\n      simplified if we keep track of endpoint dots specially)\n* Future ideas for possible improvement:\n    * Before dotting, run a smoothing algorithm on all segments (lines, curves)\n      so that, for example, the letter B in Padauk font will have its lower\n      curve look a bit smoother. (Difficulty: hard)\n    * At intersection points, look at the curve direction (2nd derivative)\n      of the lines leading into the intersection. Extend them with the same\n      2nd derivative and look at where those extended lines would naturally\n      intersect. (Difficulty: unknown)\n    * Looking at the letter H as it stands with current code, another smoothing\n      (or kink-removing) algorithm, applied to the vertical segments, might\n      straighten them out. This would require turning the 5 segments that\n      current code produces for H into 3 segments, by detecting the angle of\n      the joins and saying \"Angle is less than X degrees, join these segments\"\n      for smallish values of X (measured against the smoothly-extended lines).\n      (Difficulty: medium)\n    * After drawing intersections, we could also extend the endpoints of the\n      midlines (e.g., the starting and ending points in the letter C) and take\n      them, with the same \"keep the second derivative similar\" algorithm, all\n      the way until they intersect with one side of the tesselation triangle.\n","funding_links":[],"categories":["FieldDB Webservices/Components/Plugins"],"sub_categories":["Utilities"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsillsdev%2Ffontinline","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsillsdev%2Ffontinline","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsillsdev%2Ffontinline/lists"}