diff options
author | Rasmus Andersson <rasmus@notion.se> | 2018-09-03 22:55:49 +0300 |
---|---|---|
committer | Rasmus Andersson <rasmus@notion.se> | 2018-09-03 22:55:49 +0300 |
commit | c833e252c925e8dd68108660710ca835d95daa6f (patch) | |
tree | 6b2e28264ed45efd7f054e453b622098d0d875b8 /misc/pylib/fontbuild/alignpoints.pyx | |
parent | 8c1a4c181ef12000179dfec541f1af87e9b03122 (diff) | |
download | inter-c833e252c925e8dd68108660710ca835d95daa6f.tar.xz |
Major overhaul, moving from UFO2 to Glyphs and UFO3, plus a brand new and much simpler fontbuild
Diffstat (limited to 'misc/pylib/fontbuild/alignpoints.pyx')
-rw-r--r-- | misc/pylib/fontbuild/alignpoints.pyx | 178 |
1 files changed, 0 insertions, 178 deletions
diff --git a/misc/pylib/fontbuild/alignpoints.pyx b/misc/pylib/fontbuild/alignpoints.pyx deleted file mode 100644 index 363aeef85..000000000 --- a/misc/pylib/fontbuild/alignpoints.pyx +++ /dev/null @@ -1,178 +0,0 @@ -# Copyright 2015 Google Inc. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -import math - -import numpy as np -from numpy.linalg import lstsq - - -def alignCorners(glyph, va, subsegments): - out = va.copy() - # for i,c in enumerate(subsegments): - # segmentCount = len(glyph.contours[i].segments) - 1 - # n = len(c) - # for j,s in enumerate(c): - # if j < segmentCount: - # seg = glyph.contours[i].segments[j] - # if seg.type == "line": - # subIndex = subsegmentIndex(i,j,subsegments) - # out[subIndex] = alignPoints(va[subIndex]) - - for i,c in enumerate(subsegments): - segmentCount = len(glyph.contours[i].segments) - n = len(c) - for j,s in enumerate(c): - if j < segmentCount - 1: - segType = glyph.contours[i].segments[j].type - segnextType = glyph.contours[i].segments[j+1].type - next = j+1 - elif j == segmentCount -1 and s[1] > 3: - segType = glyph.contours[i].segments[j].type - segNextType = "line" - next = j+1 - elif j == segmentCount: - segType = "line" - segnextType = glyph.contours[i].segments[1].type - if glyph.name == "J": - print s[1] - print segnextType - next = 1 - else: - break - if segType == "line" and segnextType == "line": - subIndex = subsegmentIndex(i,j,subsegments) - pts = va[subIndex] - ptsnext = va[subsegmentIndex(i,next,subsegments)] - # out[subIndex[-1]] = (out[subIndex[-1]] - 500) * 3 + 500 #findCorner(pts, ptsnext) - # print subIndex[-1], subIndex, subsegmentIndex(i,next,subsegments) - try: - out[subIndex[-1]] = findCorner(pts, ptsnext) - except: - pass - # print glyph.name, "Can't find corner: parallel lines" - return out - - -def subsegmentIndex(contourIndex, segmentIndex, subsegments): - # This whole thing is so dumb. Need a better data model for subsegments - - contourOffset = 0 - for i,c in enumerate(subsegments): - if i == contourIndex: - break - contourOffset += c[-1][0] - n = subsegments[contourIndex][-1][0] - # print contourIndex, contourOffset, n - startIndex = subsegments[contourIndex][segmentIndex-1][0] - segmentCount = subsegments[contourIndex][segmentIndex][1] - endIndex = (startIndex + segmentCount + 1) % (n) - - indices = np.array([(startIndex + i) % (n) + contourOffset for i in range(segmentCount + 1)]) - return indices - - -def alignPoints(pts, start=None, end=None): - if start == None or end == None: - start, end = fitLine(pts) - out = pts.copy() - for i,p in enumerate(pts): - out[i] = nearestPoint(start, end, p) - return out - - -def findCorner(pp, nn): - if len(pp) < 4 or len(nn) < 4: - assert 0, "line too short to fit" - pStart,pEnd = fitLine(pp) - nStart,nEnd = fitLine(nn) - prev = pEnd - pStart - next = nEnd - nStart - # print int(np.arctan2(prev[1],prev[0]) / math.pi * 180), - # print int(np.arctan2(next[1],next[0]) / math.pi * 180) - # if lines are parallel, return simple average of end and start points - if np.dot(prev / np.linalg.norm(prev), - next / np.linalg.norm(next)) > .999999: - # print "parallel lines", np.arctan2(prev[1],prev[0]), np.arctan2(next[1],next[0]) - # print prev, next - assert 0, "parallel lines" - # if glyph.name is None: - # # Never happens, but here to fix a bug in Python 2.7 with -OO - # print '' - return lineIntersect(pStart, pEnd, nStart, nEnd) - - -def lineIntersect(p1, p2, p3, p4): - x1, y1 = p1 - x2, y2 = p2 - x3, y3 = p3 - x4, y4 = p4 - - x12 = x1 - x2 - x34 = x3 - x4 - y12 = y1 - y2 - y34 = y3 - y4 - - det = x12 * y34 - y12 * x34 - if det == 0: - print "parallel!" - - a = x1 * y2 - y1 * x2 - b = x3 * y4 - y3 * x4 - - x = (a * x34 - b * x12) / det - y = (a * y34 - b * y12) / det - - return (x,y) - - -def fitLineLSQ(pts): - "returns a line fit with least squares. Fails for vertical lines" - n = len(pts) - a = np.ones((n,2)) - for i in range(n): - a[i,0] = pts[i,0] - line = lstsq(a,pts[:,1])[0] - return line - - -def fitLine(pts): - """returns a start vector and direction vector - Assumes points segments that already form a somewhat smooth line - """ - n = len(pts) - if n < 1: - return (0,0),(0,0) - a = np.zeros((n-1,2)) - for i in range(n-1): - v = pts[i] - pts[i+1] - a[i] = v / np.linalg.norm(v) - direction = np.mean(a[1:-1], axis=0) - start = np.mean(pts[1:-1], axis=0) - return start, start+direction - - -def nearestPoint(a,b,c): - "nearest point to point c on line a_b" - magnitude = np.linalg.norm(b-a) - if magnitude == 0: - raise Exception, "Line segment cannot be 0 length" - return (b-a) * np.dot((c-a) / magnitude, (b-a) / magnitude) + a - - -# pts = np.array([[1,1],[2,2],[3,3],[4,4]]) -# pts2 = np.array([[1,0],[2,0],[3,0],[4,0]]) -# print alignPoints(pts2, start = pts[0], end = pts[0]+pts[0]) -# # print findCorner(pts,pts2) |